Усі статті
Deep dive8 хв читання

Apple може скасувати вже наданий рефанд, а скасований рефанд, який ваш сервер ігнорує, блокує клієнта, що заплатив

Коли App Store скасовує вже наданий рефанд, він очікує, що ваш сервер відновить доступ, який ви відкликали. Ось як працюють сповіщення про рефанд, відхилений рефанд і скасований рефанд у App Store та Google Play, і чого коштує кожне з них, коли ви його ігноруєте.

Сяючий замок на телефоні поряд з банківською випискою та недосяжним ключем, як образ скасованого рефанду, що блокує клієнта, який заплатив

Головне

  • App Store надсилає сповіщення REFUND_REVERSED, коли скасовує раніше наданий рефанд через те, що клієнт його оскаржив, і вказівка Apple однозначна: якщо ваш застосунок відкликав контент чи послуги, їх потрібно відновити.
  • Сповіщення REFUND означає, що App Store уже повернув кошти за транзакцію, тож ваш сервер має відкликати право доступу. Сповіщення REFUND_DECLINED означає, що Apple відхилив запит, і клієнт зберігає і доступ, і списання.
  • Якщо ви відкликаєте доступ під час рефанду, але ніколи не обробляєте скасування, клієнт, чиє списання відновлено, залишається заблокованим. Це запит у підтримку, відгук на одну зірку, а в Google Play це роздратування, яке може перетворитися на chargeback, що тепер коштує вам грошей.
  • revocationReason від Apple повідомляє, чому стався рефанд: value 1 означає, що Apple повернув кошти через фактичну або уявну проблему у вашому застосунку, value 0 означає іншу причину, наприклад випадкову покупку.
  • Google Play не має сповіщення про скасування. Він надсилає VoidedPurchaseNotification, коли покупку анульовано, і окремий PendingRefundReviewNotification для chargeback, а решту ви звіряєте за pull-моделлю Voided Purchases API.
  • Google Play дає вам 24 години, щоб відповісти на PendingRefundReviewNotification, викликавши orders.reviewrefund, і фіксує лише ваш перший виклик. З 3 серпня 2026 року програний chargeback коштує розробнику ціни за вирахуванням сервісного збору Google плюс комісія банку.
  • Обробляйте сповіщення про рефанди App Store ідемпотентно. Повторні доставки є нормою, тож прив’язуйте кожне відкликання й відновлення до transaction id і робіть повторне сповіщення no-op.

Рефанд не завжди останнє слово. App Store може скасувати вже наданий рефанд після того, як клієнт його оскаржить, і коли цей скасований рефанд надходить на ваш сервер, він несе одну вказівку: поверніть доступ. Більшість команд налаштовують звичайне сповіщення REFUND, відрізають клієнта і на цьому зупиняються. Вони ніколи не будують другу половину. Тож коли надходить скасування, нічого не спрацьовує, і клієнт, який знову платить, залишається заблокованим від того, що купив. Ось як працює повний набір сповіщень про рефанди в App Store та Google Play, і чого коштує кожне з них, коли ви його ігноруєте.

App Store надсилає три сповіщення про рефанди, а не одне

Більшість обробки рефандів побудовано під одну подію: гроші повернулися, відрізаємо клієнта. Насправді потік App Store Server Notifications V2 несе три окремі результати рефанду, і кожен вимагає різного. Два з них змінюють те, до чого має доступ клієнт. Один скасовує перший. Ось повний набір, словами самого Apple.

СповіщенняЩо воно означаєЩо робить ваш сервер
CONSUMPTION_REQUESTКлієнт попросив рефанд, і Apple хоче дані про споживанняНадішліть consumption payload протягом 12 hours
REFUNDApp Store повернув кошти за транзакціюВідкличте право доступу для цієї транзакції
REFUND_DECLINEDApp Store відхилив запит на рефандНічого; клієнт зберігає доступ і списання
REFUND_REVERSEDApp Store скасував наданий ним рефандВідновіть контент або послугу, яку ви відкликали

REFUND, те, що обробляє кожна команда

Коли App Store обробляє рефанд, він надсилає сповіщення REFUND на URL, який ви налаштували, і визначення Apple просте: воно 'вказує, що App Store успішно повернув кошти за транзакцію для витратної In-App Purchase, невитратної In-App Purchase, автоматично поновлюваної підписки або непоновлюваної підписки.' Ви зберігаєте повернуту транзакцію, відкликаєте те, що вона купила, і Apple просить вас повідомити клієнта про зміни за допомогою контекстних повідомлень у застосунку. Це сповіщення, яке всі налаштовують першим, і часто єдине.

REFUND_DECLINED, те, що не вимагає від вас нічого

REFUND_DECLINED означає рівно те, що каже: 'App Store відхилив запит на рефанд.' Клієнт попросив, Apple сказав ні, і транзакція залишається чинною. Ніщо в доступі клієнта не змінюється, тож ваша логіка прав доступу тут нічого не робить. Цінність цього сповіщення в обліку. Воно закриває цикл запиту на рефанд, на який ви могли відповісти через CONSUMPTION_REQUEST, і підтверджує, що клієнт досі має те, за що заплатив. Ставтеся до нього як до запису, а не дії.

REFUND_REVERSED, те, що заскочує команди зненацька

Це сповіщення, яке більшість конвеєрів рефандів ніколи не обробляє. Визначення Apple недвозначне: REFUND_REVERSED 'вказує, що App Store скасував раніше наданий рефанд через суперечку, яку висунув клієнт. Якщо ваш застосунок відкликав контент чи послуги внаслідок відповідного рефанду, їх потрібно відновити.' Прочитайте це двічі. Apple надав клієнту рефанд, ви відкликали доступ, потім Apple вирішив, що рефанд не має чинності, і забрав його назад. Списання знову активне. Клієнт заплатив, і якщо ваш сервер уміє лише відкликати, він залишається заблокованим. Скасований рефанд, це єдина подія рефанду, яка додає доступ назад, і це та, під яку майже ніхто не будує.

Скільки насправді коштує вам скасований рефанд

Пропущене скасування, це не похибка округлення. Простежте гроші в обох напрямках, бо помилка в будь-якій половині має ціну.

Пропустіть скасування, і ви тримаєте платного клієнта заблокованим. Apple відновив списання, тож клієнт знову без грошей, а ваш застосунок відмовляє йому в тому, що він купив. Безпосередня ціна, це час підтримки й рефанд доброї волі, який ви тепер, можливо, видаєте самі, цього разу без комісії магазину, що поверталася б, аби пом’якшити це. Повільніша ціна, це відгук і відтік, а в Google Play саме це роздратування від блокування перетворюється на chargeback.

Пропустіть початковий рефанд, і ви й далі обслуговуєте клієнта, який нічого не заплатив. Дзеркальна помилка, це взагалі ніколи не відкликати. Клієнт з рефандом, який досі генерує зображення, викликає ваші API і заповнює ваше сховище, накопичує реальні витрати проти продажу, який скасовано. Обчислення, сторонні виклики й сховище, це гроші, які ви вже витратили, і жодні з них не повертаються разом із рефандом.

  • Витрати на підтримку: людина відповідає на запит про доступ, який ваш власний код видалив і ніколи не відновив.
  • Рефанди доброї волі: повторна видача коштів клієнту, якого ви помилково заблокували, без повернення комісії магазину за ручний жест.
  • Марні витрати: обчислення, виклики API і сховище, спожиті обліковим записом з рефандом, який ви так і не відрізали.
  • Ризик chargeback: у Google Play клієнт, який почувається списаним двічі, може оскаржити, і програна суперечка тепер лягає на вас.

Скасований рефанд і звичайний рефанд, це той самий потік webhook, спрямований у протилежні боки. Обробіть один і пропустіть інший, і ви платите з обох кінців.

Рука, що тягне паперовий чек назад через стіл, як образ скасованого рефанду, що скасовує рефанд App Store, за яким ваш сервер уже діяв

Чому Apple скасовує рефанд і як читати revocationReason

Скасування не випадкове. Apple пов’язує його з 'суперечкою, яку висунув клієнт', тобто клієнт оскаржує рішення про рефанд заднім числом. Коли рефанд надавали вперше, транзакція мала revocationDate і revocationReason, і цю причину варто прочитати, перш ніж щось нижче за потоком на неї зреагує.

  • revocationReason 1: App Store повернув кошти 'через фактичну або уявну проблему у вашому застосунку.' Це сигнал про ваш продукт, а не лише про цього клієнта.
  • revocationReason 0: App Store повернув кошти 'з інших причин, наприклад через випадкову покупку.' Жодного сигналу про якість застосунку не додано.

Коли для тієї транзакції надходить REFUND_REVERSED, відкликання скасовується. Ваша логіка відновлення має знайти початковий transaction id, підтвердити, що ви його відкликали, і повернути право доступу точно таким, яким воно було.

Google Play не надсилає скасування, тож натомість ви звіряєте

Модель Google Play інша, і різниця має значення, якщо ви пропускаєте обидва магазини через один обробник webhook. Немає Google-еквівалента REFUND_REVERSED. Real-time developer notifications від Google розділяють події рефанду на два повідомлення, а скасування обробляються звіркою, а не пушем.

Сповіщення про анульовану покупку

Коли покупку в Google Play анульовано, ваш сервер отримує VoidedPurchaseNotification. Воно називає purchaseToken і orderId, productType виду subscription або one-time, і refundType, що є або повним анулюванням, або частковим рефандом за кількістю для багатокількісних покупок. Google каже, що цих даних достатньо, щоб знайти потрібну покупку й скоригувати право доступу. Для чогось більшого воно вказує вам на Voided Purchases API, pull-модель, що перелічує анульовані замовлення в межах діапазону часових позначок, який ви запитуєте.

Розгляд chargeback і його 24-годинний годинник

Chargeback надходять через інше повідомлення, PendingRefundReviewNotification. Коли клієнт оскаржує списання у своєму банку, Google Play надсилає це сповіщення й запускає годинник. У вас є 24 години, щоб викликати orders.reviewrefund з перевагою щодо рефанду й будь-якими доказами використання, аби Google міг оскаржити неправомірний chargeback від вашого імені. Google фіксує ваш перший виклик і ігнорує решту. Це аналог CONSUMPTION_REQUEST від Apple у Google, єдине вікно, коли ваша сторона суперечки має значення.

Оскільки пушу про скасування немає, chargeback, який Google оскаржує і виграє, не надходить як акуратна подія відновлення. Ви звіряєте його з Voided Purchases API і власними записами. Урок той самий, що й у App Store: анульоване замовлення не завжди остаточне, і стан ваших прав доступу має вміти рухатися назад, а не лише вперед.

Подія рефандуApp StoreGoogle Play
Рефанд наданоREFUND notificationVoidedPurchaseNotification
Рефанд відхиленоREFUND_DECLINED notificationНемає окремого повідомлення
Рефанд скасованоREFUND_REVERSED notificationНемає пушу; звірка через Voided Purchases API
Вікно доказів у суперечціCONSUMPTION_REQUEST, 12 hoursPendingRefundReviewNotification, 24 hours
Хто може видати рефандЛише AppleGoogle або ви з вкладки Orders

Як обробляти кожне сповіщення про рефанд, нікого не блокуючи

Вам не потрібні окремі конвеєри для кожного магазину. Вам потрібен обробник, який уміє рухати право доступу в обох напрямках і ставиться до кожного повідомлення як до можливо дубльованого.

  • Будуйте відновлення, а не лише відкликання. Для кожного шляху, що прибирає доступ під час REFUND, напишіть зворотний, який відновлює його під час REFUND_REVERSED, прив’язаний до того самого transaction id.
  • Зробіть це ідемпотентним. Обидва магазини можуть доставити те саме сповіщення понад один раз, тож прив’язуйте кожне відкликання й відновлення до transaction або order id і робіть повтор no-op.
  • Читайте причину, перш ніж діяти. Використовуйте revocationReason, щоб відрізнити рефанд через якість застосунку від випадкового, і спрямовуйте випадки якості застосунку до того, хто відповідає за якість продукту.
  • Відповідайте на вікна доказів вчасно. Надсилайте дані про споживання Apple протягом 12 hours після CONSUMPTION_REQUEST і викликайте orders.reviewrefund протягом 24 hours після PendingRefundReviewNotification.
  • Зберігайте кожну подію. Зберігайте REFUND_DECLINED і сирі сповіщення, щоб скасування, яке надійде пізніше, можна було зіставити з рефандом, який воно скасовує.

Ніщо з цього не змінює того, чи станеться рефанд. Воно змінює те, чи помітить колись клієнт по інший бік скасованого рефанду, що ваш сервер зробив помилку.

Поширені запитання

Що таке сповіщення REFUND_REVERSED у App Store?
Це App Store повідомляє ваш сервер, що він скасував раніше наданий рефанд, бо клієнт його оскаржив. Вказівка Apple однозначна: якщо ваш застосунок відкликав контент чи послуги внаслідок того рефанду, їх потрібно відновити. Списання знову активне, тож клієнт має отримати свій доступ назад.
Що мені робити, коли я отримую сповіщення REFUND_DECLINED?
Нічого щодо доступу клієнта. REFUND_DECLINED означає, що App Store відхилив запит на рефанд, тож транзакція залишається чинною, і клієнт зберігає те, за що заплатив. Ставтеся до нього як до запису, що закриває запит на рефанд, часто той, на який ви відповіли через CONSUMPTION_REQUEST.
Чи надсилає Google Play сповіщення, коли рефанд або chargeback скасовано?
Ні. Google Play не має аналога Apple REFUND_REVERSED. Він надсилає VoidedPurchaseNotification, коли покупку анульовано, і PendingRefundReviewNotification для chargeback, але оскаржений chargeback, який Google виграє, не надсилається вам пушем. Ви звіряєте його за допомогою Voided Purchases API і власних записів.
Скільки часу я маю, щоб відповісти на chargeback Google Play?
24 години. Коли Google Play надсилає PendingRefundReviewNotification, у вас є 24 години, щоб викликати orders.reviewrefund з перевагою щодо рефанду й доказами використання. Google фіксує лише ваш перший виклик. З 3 серпня 2026 року програний chargeback коштує розробнику ціни за вирахуванням сервісного збору Google плюс комісія банку.
Що повідомляє мені revocationReason щодо повернутої транзакції App Store?
Воно повідомляє, чому Apple повернув кошти. Value 1 означає, що Apple повернув кошти через фактичну або уявну проблему у вашому застосунку, це продуктовий сигнал. Value 0 означає іншу причину, наприклад випадкову покупку. Читання його дає змогу відокремити рефанди, що вказують на баг, від рутинних.

Джерела та додаткове читання

RefundHalt

Автопілот повернень для App Store і Google Play

Читайте далі

Deep dive8 хв читання

Невпізнане списання у банківській виписці перетворюється на зворотний платіж, а зворотний платіж коштує вам більше, ніж повернення коштів

Коли клієнт не може зрозуміти, за що ваш застосунок його списав, він телефонує банку, а не вам, і ця суперечка стає зворотним платежем. Apple показує все як apple.com/bill і не дозволяє нічого змінити. Google Play дозволяє задати назву у виписці. Ось скільки коштує кожен варіант і що ви контролюєте.

Deep dive8 хв читання

Хто платить за повернення коштів у вашому застосунку, це здебільшого ви, але не за комісію, яку ви, як вам здається, втрачаєте

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

Наступний запит на повернення вже в дорозі.

Налаштуйте RefundHalt за час, потрібний, щоб прочитати черговий лист у підтримку про повернення, яке ви не встигли оскаржити.