Повернення через Advanced Commerce API залишається єдиним способом, у який iOS-розробник може ініціювати повернення коштів, і остаточне рішення все одно за Apple
Більшість iOS-розробників не можуть повернути гроші клієнту. Застосунки на Advanced Commerce API від Apple можуть запросити повернення, відкликати підписку або повернути довільну суму. Розбираємо, як працює кожен endpoint, у чому Apple досі може відмовити і де губляться гроші.

Головне
- У червні 2026 року інженер Apple заявив, що розробник не може напряму оформити повернення за звичайну покупку в App Store. Єдине, що може зробити розробник, це надіслати дані про споживання та refundPreference у відповідь на CONSUMPTION_REQUEST.
- Застосунки, схвалені для Advanced Commerce API від Apple, отримують endpoint Request Transaction Refund, який просить App Store повернути кошти за разовий платіж або транзакцію підписки, а також endpoints Revoke Subscription і Cancel a Subscription.
- Щоб викликати endpoints Advanced Commerce API для повернення, відкликання та скасування, Account Holder розробника має підписати Advanced Commerce API Addendum. За словами Apple, якщо останню версію не прийнято, виклик поверне помилку.
- Endpoint Request Transaction Refund приймає refundType зі значенням FULL, PRORATED або CUSTOM, а refundAmount у тисячних частках грошової одиниці дозволено лише з CUSTOM. За словами Apple, сума має містити податок у всіх регіонах, крім Канади та США.
- Поле refundRiskingPreference за замовчуванням дорівнює true. Це дозволяє App Store надіслати CONSUMPTION_REQUEST щодо запиту на повернення, який подав сам розробник. Apple просить відповісти протягом 12 годин.
- Endpoints Advanced Commerce API для повернення, відкликання та скасування в продакшені обмежені 5 запитами на секунду на застосунок, а sandbox отримує 10 відсотків від цього ліміту.
- Після успішного виклику Revoke Subscription Apple надсилає сповіщення REFUND і вимагає припиняти доступ із дати revocationDate, але не раніше, ніж надійде сповіщення.
Звичайні iOS-розробники не можуть повернути гроші клієнту. У червні 2026 року App Store Commerce Engineer відповів на запитання на форумі розробників однією фразою: наразі розробник не може напряму оформити повернення. Є один виняток, і він міститься в Advanced Commerce API. Застосунки, які Apple до нього допускає, можуть надіслати запит на повернення через Advanced Commerce API, відкликати підписку з поверненням коштів або запросити довільну суму. Чи переказувати гроші, і далі вирішує Apple.
Що таке Advanced Commerce API і хто його отримує
Apple випустила Advanced Commerce API 23 січня 2025 року. Він обробляє вбудовані покупки Apple для винятково великих каталогів: довільних разових покупок, підписок і підписок із додатковими опціями. Ви не створюєте кожен продукт в App Store Connect. Ви визначаєте SKU на своєму сервері й передаєте їх Apple у момент покупки.
Доступ надається окремо для кожного застосунку. Ви заповнюєте форму заявки, а сторінка Apple про відповідність вимогам називає три бізнес-моделі, які мають бути основою застосунку:
- Винятково великі каталоги разових покупок, наприклад аудіокниги, заняття, курси або мінізастосунки.
- Винятково великі каталоги контенту за підпискою, де пропозиція кожного автора є окремою підпискою.
- Підписка з додатковими опціями, які подовжуються разом як одна покупка, наприклад преміальні канали або спорт.
Apple також дозволяє подати заявку, якщо API потрібен для іншої програми. Його вимагає Mini Apps Partner Program, яка виплачує учасникам 85% від відповідних продажів вбудованих покупок у розміщених мінізастосунках.
Endpoints для повернень з'явилися пізніше, і для них потрібен підпис
Версія 1.1 від 24 березня 2025 року додала Request Transaction Refund і Revoke Subscription. Сторінка програми Apple каже, що застосунки з контентом за підпискою також можуть отримати право на API Cancel, Revoke і Refund, щоб обробляти скасування, перевіряти контент після покупки та керувати каталогами. Сторінка кожного endpoint додає ту саму умову: ваш Account Holder має підписати Advanced Commerce API Addendum, а якщо останню версію не прийнято, виклик поверне помилку. Сценарії використання кожного endpoint перелічені в Addendum, а не в документації.
Три endpoints поруч
| Cancel a Subscription | Revoke Subscription | Request Transaction Refund | |
|---|---|---|---|
| Шлях | advancedCommerce/v1/subscription/cancel/{transactionId} | advancedCommerce/v1/subscription/revoke/{transactionId} | advancedCommerce/v1/transaction/requestRefund/{transactionId} |
| Охоплення | Підписки з автоподовженням | Підписка та всі її позиції | Разові платежі та транзакції підписок |
| Повернення коштів | Немає | FULL або PRORATED | FULL, PRORATED або CUSTOM, для кожного SKU |
| Доступ | Зберігається до кінця періоду | Припиняється в revocationDate | Задається для кожної позиції прапорцем revoke |
| Ліміт у продакшені | 5 на секунду | 5 на секунду | 5 на секунду |
Cancel a Subscription зупиняє наступне списання
Cancel вимикає автоподовження. За словами Apple, клієнт зберігає доступ до кінця поточного періоду. Нічого не повертається. Це правильний виклик, коли клієнт хоче піти й уже використав оплачений час.
Revoke Subscription припиняє все одразу
Revoke встановлює автоподовження в false і відкликає підписку з повним або пропорційним поверненням. Тіло запиту містить refundReason, refundRiskingPreference, refundType і requestInfo. Потім Apple надсилає сповіщення REFUND на ваш endpoint App Store Server Notifications V2. Вказівка Apple конкретна: вимикайте доступ із дати revocationDate з цього сповіщення і не вимикайте його до того, як сповіщення надійде.
Request Transaction Refund працює за позиціями
Це точний інструмент. Ви надсилаєте список позицій, і в кожній указано SKU, refundReason, refundType і прапорець revoke. З CUSTOM ви також передаєте refundAmount у тисячних частках грошової одиниці, тобто 4990 означає 4,99. Якщо надіслати суму з FULL або PRORATED, Apple відхилить запит із помилкою 4000155. Відповідь містить підписану транзакцію, а для підписок ще й підписані дані про подовження.
Apple приймає такі значення refundReason: UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, OTHER і MODIFY_ITEMS_REFUND. Сьоме значення, SIMULATE_REFUND_DECLINE, призначене лише для тестування в sandbox і TestFlight. Воно існує тому, що App Store може відмовити.
Apple може відхилити навіть ваш власний запит на повернення
Назва endpoint чесна. Це запит. Два поля показують, де насправді ухвалюється рішення.
refundRiskingPreference відкриває шлях до перевірки споживання
Apple описує refundRiskingPreference як ознаку того, чи запитає App Store у вас дані про споживання для рішення про повернення. За замовчуванням значення true. Якщо воно true, ви отримуєте CONSUMPTION_REQUEST щодо власного запиту на повернення і відповідаєте через Send Consumption Information. Apple просить розробників відповісти протягом 12 годин після отримання CONSUMPTION_REQUEST. Встановіть false, і це сповіщення не надійде.
Помилки, які означають відмову
| Помилка | Код | Що каже Apple |
|---|---|---|
| AlreadyRefundedError | 4030021 | За транзакцією вже зроблено повернення |
| PendingRefundError | 4000181 | За транзакцією є повернення в очікуванні |
| TransactionNotRefundableError | 4030024 | Транзакція не підлягає поверненню |
| TransactionCannotBeRefundedContactSupportError | 4030025 | Клієнт може звернутися до Apple Support |
| RefundAmountWithoutCustomError | 4000155 | Суму надіслано без CUSTOM |
До PendingRefundError варто готуватися заздалегідь. Імовірна причина: клієнт уже звернувся до Apple через Report a Problem до того, як відреагувала ваша підтримка. Правила Apple і так вимагають, щоб у цих застосунках був шлях до повернення всередині застосунку, посилання Report a Problem або API beginRefundRequest, тож обидві двері відчинені одночасно.

Скільки вам коштує повернення через Advanced Commerce API
Повернути гроші з власної ініціативи здається дешевше, ніж сперечатися. Але це все одно витрата, а API дає змогу легко повторювати деякі помилки у великих масштабах.
Податок усередині довільної суми
За словами Apple, запитаний refundAmount має містити податок у всіх регіонах, крім Канади та США. Команда, яка розраховує повернення CUSTOM від ціни SKU без податку, недоплатить клієнтам у всіх інших вітринах, а потім витратить час підтримки на виправлення кожного випадку.
Витрати, які не повертаються
- Виплати: у каталозі авторів або в хоста мінізастосунків частку автора часто виплачують під час продажу. Повернення клієнту її не поверне.
- Ліцензії на контент: відрахування правовласнику за аудіокнигу чи курс можуть, залежно від договору, нараховуватися вже за доступ, і повернення їх не скасовує.
- Обчислення: стримінг, транскодування та вся серверна робота для покупки вже у вашому рахунку.
- Виклики API: сторонні сервіси з оплатою за запит, від розпізнавання мовлення до інференсу моделей, залишаються оплаченими після повернення.
Повне повернення, коли йшлося про одну позицію
Revoke Subscription повертає гроші та припиняє всю підписку разом із додатковими опціями. Якщо клієнт оскаржує лише одну опцію, Request Transaction Refund дає змогу повернути тільки цей SKU, із прапорцем revoke лише для цієї позиції. Виклик Revoke Subscription через скаргу на одну позицію повертає й виручку за базовий тариф.
Чек-лист перед увімкненням
- Переконайтеся, що ваш Account Holder прийняв поточну версію Advanced Commerce API Addendum, і налаштуйте сповіщення про помилку, яка приходить, коли прийняття спливає.
- Генеруйте новий requestReferenceId у форматі UUID для кожного запиту й використовуйте той самий повторно лише для повтору виклику, що завершився за тайм-аутом.
- Ставте виклики повернень у чергу. Ліміт становить 5 на секунду на застосунок, а відповідь 429 містить заголовок Retry-After у мілісекундах UNIX.
- Тестуйте відмови в sandbox із SIMULATE_REFUND_DECLINE і пам'ятайте, що ліміти sandbox становлять 10 відсотків від продакшену.
- Вирішуйте питання з refundRiskingPreference у кожному випадку окремо й тримайте напоготові обробник даних про споживання на 12-годинне вікно, якщо значення залишається true.
- Припиняйте доступ лише після надходження сповіщення REFUND, з його revocationDate.
- Записуйте причину, суму та SKU кожного запиту, щоб бачити власну частку повернень раніше, ніж її побачить Apple.
Поширені запитання
- Чи може iOS-розробник напряму повернути гроші клієнту?
- Не за звичайну покупку в App Store. У червні 2026 року інженер Apple заявив, що розробник не може напряму оформити повернення. Застосунки, схвалені для Advanced Commerce API і з підписаним Addendum, можуть запросити його через endpoint Request Transaction Refund, але рішення все одно ухвалює Apple.
- Чим Cancel відрізняється від Revoke в Advanced Commerce API?
- Cancel вимикає автоподовження, і клієнт зберігає доступ до кінця періоду, без повернення. Revoke одразу припиняє підписку та всі її позиції й повертає повну або пропорційну суму. Після Revoke Apple надсилає сповіщення REFUND.
- Чи можна повернути довільну суму через Advanced Commerce API?
- Так. Встановіть refundType у CUSTOM і передайте refundAmount у тисячних частках грошової одиниці. За словами Apple, сума має містити податок у всіх регіонах, крім Канади та США, а надсилання суми з FULL або PRORATED повертає помилку 4000155.
- Чи отримаю я CONSUMPTION_REQUEST щодо повернення, яке запросив сам?
- Можете отримати. refundRiskingPreference за замовчуванням дорівнює true, тому App Store може запитати у вас дані про споживання через CONSUMPTION_REQUEST, і Apple просить відповісти протягом 12 годин. Встановіть false, і, за словами Apple, це сповіщення не буде надіслано.
- Чому мій запит на повернення через Advanced Commerce API не пройшов?
- Перевірте код помилки. 4030021 означає, що за транзакцією вже зроблено повернення, 4000181 означає, що повернення вже очікує обробки, 4030024 означає, що транзакція не підлягає поверненню, а 4030025 означає, що клієнту слід звернутися до Apple Support. Непідписаний або застарілий Addendum теж призводить до помилки.
Джерела та додаткове читання
- Apple Developer: Advanced Commerce API eligibility and requirements
- Advanced Commerce API: Request Transaction Refund
- Advanced Commerce API: RequestRefundItem
- Advanced Commerce API: refundRiskingPreference
- Advanced Commerce API: Revoke Subscription
- Advanced Commerce API: Rate limits
- Advanced Commerce API changelog
- App Store Server API: Send Consumption Information
- Apple Developer Forums: Refund option in App Store Server API
- Apple Developer: Mini Apps Partner Program
RefundHalt
Автопілот повернень для App Store і Google Play
Читайте далі
Надмірні запити на повернення коштують дорожче за самі повернення: обидва магазини застосунків вважають їх сигналом якості
Правило 5.6.4 Apple прямо називає надмірні запити на повернення ознакою того, що застосунок не відповідає стандартам якості, а угода Google про розповсюдження дозволяє видаляти застосунки нових розробників через частку повернень. Розбираємо, що пише кожен магазин, скільки коштує видалення і як не потрапити під удар.
Перевіряйте серверні сповіщення App Store, перш ніж діяти щодо повернення коштів, бо надіслати запит на ваш webhook URL може будь-хто
Сповіщення про повернення коштів залишається звичайним HTTPS-запитом, доки ви не перевірите його підпис. Пояснюємо, як перевіряти серверні сповіщення App Store і повідомлення Google Play RTDN, що саме підписує кожен магазин і скільки коштує підроблене або помилково відхилене повернення.