Ваш застосунок може показати аркуш запиту на повернення коштів усередині застосунку, і ось що робить Apple після того, як клієнт натискає надіслати
Запит на повернення коштів усередині застосунку від Apple дозволяє клієнту попросити повернення, не виходячи з вашого застосунку, на аркуші, який Apple створює і перевіряє. Ось що повертає beginRefundRequest, які годинники CONSUMPTION_REQUEST і 48 годин він запускає на вашому сервері та чи варто випускати цю кнопку.

Головне
- beginRefundRequest від Apple, це метод StoreKit 2, який показує власний аркуш повернення Apple усередині вашого застосунку. Клієнт бачить деталі своєї покупки і список кодів причин, обирає одну, і запит вирушає до Apple. Ви не будуєте форму і не вирішуєте результат.
- Виклик повертає статус success або userCancelled, чи кидає duplicateRequest або failed. Статус success означає, що App Store отримав запит, а не що він його схвалив. Ніколи не показуйте підтверджене повернення у своєму інтерфейсі при success.
- Після того, як клієнт надіслав запит, Apple потрібно до 48 годин, щоб схвалити або відхилити. Для витратних покупок він спершу надсилає CONSUMPTION_REQUEST на ваш сервер, і у вас є звичні 12 годин, щоб відповісти даними про використання, якщо клієнт дав згоду.
- Результат надходить на ваш сервер як App Store Server Notification, той самий потік, який ви вже отримуєте. Схвалення, це сповіщення REFUND, відмова, це REFUND_DECLINED. Запит усередині застосунку потрапляє в цей потік точно так само, як повернення, розпочате на сторінці reportaproblem від Apple.
- Кнопка доступна з iOS 15 і iPadOS 15, Mac Catalyst 15 та visionOS 1, тож будь-який застосунок, націлений на ці версії, може показати її вже сьогодні.
- Фінансовий аргумент полягає в тому, що повернення, яке ви можете оскаржити, краще за зворотний платіж, який ви оскаржити не можете. Утримання клієнта в процесі Apple запускає CONSUMPTION_REQUEST, на яке ви можете відповісти, замість банківського зворотного платежу, який є остаточним і несе комісію.
- Apple радить викликати її з налаштувань облікового запису або меню довідки, а не з екрана покупки, щоб незадоволений клієнт знайшов її, не рекламуючи повернення всім іншим.
Apple дозволяє клієнту запросити повернення коштів, жодного разу не виходячи з вашого застосунку. Один виклик StoreKit, beginRefundRequest, показує власний аркуш повернення Apple прямо у вашому інтерфейсі, клієнт обирає причину, і запит вирушає до Apple на перевірку. Ви не будуєте форму, ви не торкаєтеся грошей і ви не вирішуєте результат. Те, що ви отримуєте, це спосіб розмістити шлях повернення там, де розчарований клієнт уже перебуває, замість того щоб втратити його на користь його банку. Це запит на повернення коштів усередині застосунку, і його варто зрозуміти, перш ніж ви вирішите, чи випускати цю кнопку.
Ось частина, яка має значення для вашого доходу. Кнопка сама по собі нічого не повертає. Вона відкриває запит, Apple потрібно до 48 годин, щоб схвалити або відхилити його, а для витратних покупок спершу випускає CONSUMPTION_REQUEST на ваш сервер. Тож аркуш, це не роздача подарунків. Це вирва в ту саму перевірку повернення, на яку ви вже можете впливати, і вона може відтягнути спір від карткової мережі, перш ніж він стане зворотним платежем, який ви не можете оскаржити.
Чим насправді є аркуш запиту на повернення коштів усередині застосунку
beginRefundRequest, це метод StoreKit 2, який показує аркуш запиту на повернення для транзакції у сцені вікна. Сигнатура коротка: func beginRefundRequest(in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus. Коли ви його викликаєте, система показує аркуш із деталями покупки клієнта і списком кодів причин на вибір. Apple будує і контролює цей інтерфейс. Ви надаєте сцену і транзакцію, більше нічого.
Порада Apple щодо того, куди її помістити, однозначна. Викликайте цю функцію з налаштувань облікового запису або меню довідки, щоб клієнт, який хоче повернення, знайшов її там, де шукав би підтримку. Вона з'явилася в iOS 15 і iPadOS 15, Mac Catalyst 15 та visionOS 1, тож будь-який застосунок, націлений на ці версії, може показати її вже сьогодні.
Два способи відкрити аркуш
Є дві точки входу. Ви можете викликати beginRefundRequest(in:) для конкретної транзакції, яку вже маєте, що обмежує аркуш цією однією покупкою. Ви також можете відкрити аркуш за ідентифікатором продукту, коли хочете, щоб клієнт повернув покупку певного продукту. У будь-якому разі аркуш, список причин і рішення належать Apple. Ваша робота закінчується на тому, щоб показати його і зчитати результат.
Що повертає виклик і що може піти не так
Метод, це async throws, тож він або повертає статус, або кидає помилку. І те, і інше, це короткі списки, і обидва варто обробити, щоб ваш інтерфейс сказав щось правдиве після закриття аркуша.
| Результат | Тип | Що це означає |
|---|---|---|
| success | RefundRequestStatus | App Store отримав запит на повернення. Його подано, не схвалено |
| userCancelled | RefundRequestStatus | Клієнт закрив аркуш, не надіславши. Нічого не було надіслано |
| duplicateRequest | RefundRequestError | App Store уже має запит на повернення для цієї покупки |
| failed | RefundRequestError | Саме надсилання не вдалося. Дайте клієнту спробувати ще раз |
Що відбувається на вашому сервері після того, як клієнт натискає надіслати
Закриття аркуша, це початок процесу, а не кінець. Apple перевіряє запит і бере до 48 годин, щоб схвалити або відхилити його. Для витратної покупки в застосунку, перш ніж вирішити, App Store надсилає на ваш сервер сповіщення CONSUMPTION_REQUEST із проханням про дані про використання. Якщо клієнт дав згоду поділитися цими даними, ви відповідаєте через ендпоінт Send Consumption Information. Якщо він не дав згоди, власна вказівка Apple, це взагалі не відповідати на сповіщення.
Щойно Apple ухвалює рішення, результат опиняється на вашому сервері як App Store Server Notification. Це той самий потік, який ви вже отримуєте, і запит усередині застосунку потрапляє в нього точно так само, як повернення, яке клієнт розпочинає на сторінці reportaproblem від Apple. В обробці нічого не змінюється лише тому, що запит почався всередині вашого застосунку.
| Етап | Що спрацьовує | Ваш крок | Годинник |
|---|---|---|---|
| Клієнт надсилає аркуш | beginRefundRequest повертає success | Запишіть це, покажіть в очікуванні, не повернуто | Миттєво |
| Тільки витратні, Apple питає першим | Сповіщення CONSUMPTION_REQUEST | Надішліть дані про споживання, якщо клієнт дав згоду, інакше мовчіть | 12 годин на відповідь |
| Apple схвалює | Сповіщення REFUND | Відкличте право для цієї транзакції | До 48 годин на рішення |
| Apple відмовляє | Сповіщення REFUND_DECLINED | Збережіть продаж, нічого не змінюйте | До 48 годин на рішення |

Скільки коштує вам ця кнопка і що вона може заощадити
Повернення, яке ви можете оскаржити, краще за зворотний платіж, який ви оскаржити не можете
Клієнт, який не може знайти шлях повернення всередині вашого застосунку, не здається. Він іде до свого банку. Картковий зворотний платіж є остаточним у банку, він несе комісію за спір і забирає рішення як із ваших рук, так і з рук Apple. Запит на повернення коштів усередині застосунку утримує того самого клієнта в системі Apple, де витратна покупка запускає CONSUMPTION_REQUEST, на яке ви можете відповісти, і рішення, на яке ви можете вплинути. Обміняти неоскаржуваний зворотний платіж на оскаржувану перевірку Apple, це весь фінансовий аргумент за цю кнопку.
Ви знижуєте поріг для повернення
Чесна противага в тому, що видимий шлях повернення в один дотик породжує більше запитів на повернення, ніж захований лист до підтримки. Деякі з них ніколи б не сталися. Це реальна ціна, і саме тому Apple каже вам розмістити точку входу в налаштуваннях облікового запису або меню довідки, а не на екрані покупки. Ви хочете, щоб її знайшов клієнт, який уже незадоволений, а не той, хто просто цікавий.
Витрата, яка триває весь час, це обслуговування облікового запису з поверненням
Хоч би яким було рішення, лічильник постачання продовжує йти, доки ви не відреагуєте на результат. За кожну годину, поки повернене право лишається активним, ви й далі платите реальні витрати за ним: обчислення, виклики API моделі, сховище і будь-яку виплату творцю чи партнеру, прив'язану до використання цього клієнта. Запит усередині застосунку цього не змінює. Змінює це швидке відкликання при сповіщенні REFUND. Кнопка настільки дешева, наскільки добра ваша обробка сповіщення, яке вона зрештою породжує.
Чи варто вам випускати запит на повернення коштів усередині застосунку
Розмістіть її там, де живе підтримка, а не там, де живуть продажі
Дотримуйтесь поради Apple щодо розміщення. Налаштування облікового запису і меню довідки, це правильні місця. Посилання на повернення поруч із пейволом привчає людей очікувати повернення грошей і запрошує до повернення з цікавості, яке вам ніколи не потрібно було пропонувати.
Протестуйте весь потік у пісочниці, перш ніж довіряти йому
Ви можете змоделювати весь шлях у пісочниці й у тестуванні StoreKit у Xcode, переводячи запит з очікування на схвалений або відхилений. Схвалення доставляє сповіщення REFUND на ваш сервер, а відмова доставляє REFUND_DECLINED, тож ви можете довести, що ваш обробник реагує правильно, перш ніж справжній клієнт колись натисне надіслати.
Обробляйте кожен результат і ніколи не обіцяйте зайвого
При success покажіть в очікуванні, при failed запропонуйте повторну спробу, при userCancelled скажіть, що нічого не змінилося, а duplicateRequest сприйміть як тиху нотатку, що попередній запит клієнта досі чинний. Одна помилка, яка болить, це сказати клієнту, що його повернення виконано, коли все, що ви маєте, це поданий запит.
Як RefundHalt обробляє те, що відбувається потім
Аркуш усередині застосунку належить Apple. Те, що йде після нього, належить вам, і це та частина, якою керує RefundHalt. Коли клієнт надсилає повернення зсередини вашого застосунку, RefundHalt перехоплює CONSUMPTION_REQUEST для витратних покупок і відповідає на нього в межах 12-годинного вікна доказами використання, які допомагають Apple вирішити. Коли Apple ухвалює рішення, він відкликає при REFUND і лишає доступ недоторканим при REFUND_DECLINED, кожен прив'язаний до точної транзакції. Ви можете запропонувати дружніший шлях повернення всередині застосунку, не залишаючи перевірку, докази чи відкликання ручній метушні.
Поширені запитання
- Що робить beginRefundRequest?
- Він показує аркуш запиту на повернення Apple усередині вашого застосунку для конкретної транзакції. Клієнт бачить деталі своєї покупки і список кодів причин, обирає одну, і запит вирушає до Apple. Метод повертає статус success або userCancelled, чи кидає duplicateRequest або failed. Він не повертає саму покупку, бо Apple перевіряє запит і бере до 48 годин на рішення.
- Чи повертає запит на повернення всередині застосунку гроші одразу?
- Ні. Результат success означає, що App Store отримав запит, а не що він його схвалив. Apple бере до 48 годин, щоб схвалити або відхилити, а для витратних покупок спершу просить у вашого сервера дані про використання через сповіщення CONSUMPTION_REQUEST. Покажіть клієнту при success стан в очікуванні, ніколи не підтверджене повернення.
- Яка версія iOS підтримує запит на повернення всередині застосунку?
- iOS 15 і iPadOS 15, Mac Catalyst 15 та visionOS 1. Метод StoreKit 2 beginRefundRequest(in:) доступний з цих версій, тож будь-який застосунок, націлений на iOS 15 чи новіший, може показати аркуш повернення Apple зсередини застосунку.
- Де мені розмістити кнопку повернення всередині застосунку?
- Apple радить викликати її з налаштувань облікового запису або меню довідки, а не з екрана покупки чи пейволу. Це розміщує шлях повернення там, де незадоволений клієнт шукає підтримку, не рекламуючи повернення клієнтам, які й не збиралися його просити.
- Чи краще повернення всередині застосунку, ніж звернення клієнта до свого банку?
- Зазвичай так, для вашого доходу. Банківський зворотний платіж є остаточним і несе комісію, а також усуває з рішення і Apple, і вас. Запит на повернення всередині застосунку утримує клієнта в процесі Apple, де витратна покупка запускає CONSUMPTION_REQUEST, на яке ви можете відповісти, і перевірку, на яку ви можете вплинути. Оскаржуване повернення краще за неоскаржуваний зворотний платіж.
Джерела та додаткове читання
- Apple Developer: beginRefundRequest(in:)
- Apple Developer: Transaction.RefundRequestStatus
- Apple Developer: Transaction.RefundRequestError
- Apple Developer: App Store Server Notifications V2 notificationType
- Apple Developer: Send Consumption Information
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
Автопілот повернень для App Store і Google Play
Читайте далі
Коли покупку в Google Play повертають або оскаржують через chargeback, Voided Purchases API це те, як ви про це дізнаєтесь
Google Play тихо анулює покупку, коли її повертають або оскаржують через chargeback. Voided Purchases API це список таких замовлень, щоб ви могли відкликати доступ. Ось кожне поле, вікно у 30 днів, опція revoke, що приховує замовлення, і скільки це коштує.
Три сповіщення про повернення коштів у App Store надходять після рішення Apple, а REFUND_REVERSED повертає продаж назад
Apple надсилає чотири повідомлення про повернення коштів через App Store Server Notifications V2, і більшість застосунків обробляють лише два. REFUND каже відкликати доступ, REFUND_DECLINED означає зберегти продаж, а REFUND_REVERSED повертає продаж назад і просить відновити те, що ви забрали. Ось що вимагає кожне з них.