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

Коли покупку в Google Play повертають або оскаржують через chargeback, Voided Purchases API це те, як ви про це дізнаєтесь

Google Play тихо анулює покупку, коли її повертають або оскаржують через chargeback. Voided Purchases API це список таких замовлень, щоб ви могли відкликати доступ. Ось кожне поле, вікно у 30 днів, опція revoke, що приховує замовлення, і скільки це коштує.

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

Головне

  • Voided Purchases API, метод purchases.voidedpurchases.list, повертає замовлення, які Google Play скасував, повернув або оскаржив через chargeback, щоб ви могли побудувати систему відкликання, яка відрізає доступ до того, чим клієнт більше не володіє.
  • З'являються лише відкликані замовлення. Повернення, здійснене розробником без опції revoke, невидиме для цього API, тож якщо ви хочете забрати доступ, вам потрібно робити повернення з увімкненою опцією revoke.
  • Вікно становить 30 днів. startTime не може бути старішим за 30 днів тому, тож сервер, який не працює довше місяця, назавжди втрачає ці анульовані замовлення. Опитуйте за розкладом.
  • voidedSource каже вам, хто анулював замовлення: 0 це користувач, 1 це розробник, 2 це Google. voidedReason каже вам чому, від 0 Other до 7 Chargeback і 8 Unacknowledged_purchase.
  • Real-time developer notifications надсилають VoidedPurchaseNotification тієї миті, коли покупку анульовано, але ставтеся до цього як до сигналу. Викликайте Voided Purchases API за авторитетним списком, перш ніж відкликати.
  • Ідентифікуйте поновлення підписки за orderId, а не за purchaseToken. Один purchaseToken охоплює кожне поновлення підписки, тож самого токена недостатньо, щоб відрізнити два поновлення.
  • Квоти становлять 6,000 запитів на день і 30 запитів у будь-якому 30-секундному вікні, тож гортайте результати за допомогою continuation token і робіть запити за часовим вікном, ніколи не один виклик на замовлення.

Повернення коштів у Google Play не стукає до ваших дверей. Гроші рухаються, клієнт тримає застосунок відкритим, і якщо ви не підете шукати, у вас нічого не зміниться. Voided Purchases API це те місце, куди ви йдете шукати. Він видає вам список замовлень, які були скасовані, повернені або оскаржені через chargeback, щоб ви могли відкликати доступ до того, за що клієнт більше не платить. Спрямуйте на нього заплановане завдання, прочитайте список, обріжте право доступу. Це весь цикл.

Є одна пастка, яка збиває з пантелику більшість команд, і вона не в коді. Тут з'являються лише замовлення, які були відкликані. Якщо ви повертаєте покупку в Play Console, не поставивши галочку опції revoke, це замовлення ніколи не досягне цього API, і ваше завдання відпрацює чисто, поки клієнт із поверненням зберігає все, що ви йому продали. Ця стаття проходить API поле за полем, числа, що його обмежують, і місця, де витікають гроші, коли ви це пропускаєте.

Що насправді повертає Voided Purchases API

API відповідає на одне питання: які замовлення для цього застосунку були анульовані нещодавно. Анулювання охоплює три результати, що всі закінчуються тим, що клієнт отримує свої гроші назад. Скасування, повернення або chargeback. Воно застосовується до одноразових продуктів у застосунку та до підписок, і ви обираєте обсяг одним параметром. Встановіть type на 0, і ви отримаєте лише анульовані покупки продуктів у застосунку, це значення за замовчуванням. Встановіть його на 1, і ви отримаєте анульовані покупки в застосунку та анульовані покупки підписок разом.

Кожен запис у списку це об'єкт анульованої покупки. Полів небагато, і кожне з них має значення.

Поля анульованої покупки

ПолеЩо воно містить
orderIdІдентифікатор замовлення, що унікально визначає одноразову покупку, покупку підписки або одне поновлення підписки. Це ваш ключ для join
purchaseTokenТокен, що ідентифікує одноразову покупку або підписку. Він не розрізняє поновлення, тож для них використовуйте orderId
purchaseTimeMillisКоли покупку було здійснено, у мілісекундах від епохи
voidedTimeMillisКоли покупку було скасовано, повернено або оскаржено через chargeback, у мілісекундах від епохи
voidedSourceХто ініціював анулювання: 0 користувач, 1 розробник, 2 Google
voidedReasonЧому покупку було анульовано, ціле число від 0 до 8
voidedQuantityАнульована кількість від часткового повернення на основі кількості, повертається лише коли includeQuantityBasedPartialRefund дорівнює true

Прочитайте voidedReason, перш ніж діяти

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

voidedReasonLabelЩо це означає для вас
0OtherКатегорію не призначено. Відкличте і рухайтеся далі
1RemorseПокупець передумав. Звичайне повернення
2Not_receivedКлієнт каже, що ніколи не отримав продукт. Варто перевірити вашу доставку
3DefectiveПродукт не працював. Сигнал якості, зафіксуйте його
4Accidental_purchaseНенавмисна покупка, часто зі спільного пристрою
5FraudGoogle позначив транзакцію як шахрайську
6Friendly_fraudchargeback, коли законний власник картки оскаржує платіж, який він сам здійснив
7ChargebackБанк клієнта скасував платіж. Остаточно з банком, і тепер виставляється вам
8Unacknowledged_purchaseGoogle автоматично повернув кошти за покупку, яку ваш застосунок так і не підтвердив (acknowledge)

Вікно у 30 днів це пастка, що спорожнює ваш список

Voided Purchases API може показувати лише анульовані покупки за останні 30 днів. Параметр startTime за замовчуванням дорівнює поточному часу мінус 30 днів, і його не можна встановити старішим за це. endTime за замовчуванням дорівнює зараз. Тож ця кінцева точка це рухоме одномісячне вікно, а не архів.

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

Опція revoke вирішує, чи взагалі з'явиться замовлення

Це найпоширеніша причина, чому команда повідомляє, що API зламаний. Повертаються лише відкликані замовлення. Повернення, ініційовані користувачем, скасування, chargeback і повернення, ініційовані Google, завжди відкликаються, тож вони завжди з'являються. Повернення, ініційоване розробником, це інша річ. Коли ви повертаєте замовлення самі, через Play Console або Orders API, ви обираєте, чи також відкликати його. Поверніть без revoke, і замовлення врегульоване з клієнтом, але ніколи не спливає у Voided Purchases API.

Правило, що з цього випливає, просте. Якщо ваш намір забрати доступ, робіть повернення з увімкненою опцією revoke. Інакше ви віддали гроші і залишили двері відчиненими, а вашому завданню відкликання, хоч би як добре воно було написане, немає над чим працювати.

Як опитувати його, не зачепивши квоту

Кінцева точка має обмеження швидкості, і ліміти достатньо низькі, щоб наївний цикл їх досяг. Ви отримуєте 6,000 запитів на день, що рахуються за тихоокеанським часом, і не більше 30 запитів у будь-який 30-секундний період. Цього бюджету достатньо для віконного опитування і він ворожий до дизайнів один запит на замовлення.

Вікна запитів і continuation token

maxResults за замовчуванням дорівнює 1,000, що також є стелею. Коли вікно містить більше однієї сторінки анулювань, відповідь несе об'єкт tokenPagination із nextPageToken. Передайте цей токен назад у наступному виклику, щоб пройти сторінки. Встановіть startTime і endTime, щоб обмежити вікно, яке вас цікавить, гортайте, доки токен не закінчиться, потім просувайте вікно. Цей шаблон тримає вас у межах як 30-секундного ліміту сплеску, так і денної межі.

Real-time developer notifications закривають розрив

Опитування щодня все одно залишає до доби сліпоти, а вікно у 30 днів карає за довгі проміжки. Real-time developer notifications усувають затримку. Google публікує VoidedPurchaseNotification у Cloud Pub/Sub topic, яким ви володієте, тієї миті, коли покупку анульовано, і ваш бекенд споживає його за лічені секунди. Повідомлення маленьке.

Поле RTDNЩо воно містить
purchaseTokenТокен з початкової покупки
orderIdІдентифікатор замовлення для анульованої транзакції, новий на кожне поновлення підписки
productType1 для підписки, 2 для одноразової покупки
refundType1 для повного повернення, 2 для часткового повернення на основі кількості
Рука закриває латунний замок над стосом чеків поруч зі смартфоном, ілюструючи відкликання доступу після того, як покупку в Google Play анульовано

У що це вам обходиться у грошах

API це сантехніка, але причина під'єднати його це рахунок. Кожне анулювання в тому списку відповідає реальному числу, і два з них стають дорожчими.

Рахунок за chargeback лягає на вас із 3 серпня 2026 року

Починаючи з 3 серпня 2026 року, Google перекладає вартість chargeback на розробника. Ви втрачаєте ціну покупки і зверху сплачуєте банківську комісію за chargeback. voidedReason зі значенням 7 більше не просто втрачений продаж, це рядок витрат із прикріпленою комісією. Ви не можете скасувати chargeback, він остаточний з банком, але ви можете зупинити кровотечу після нього. Швидке виявлення анулювання дозволяє вам відкликати право доступу і, для всього, що ви ще доставляєте, припинити витрати на клієнта, якому повернули кошти, а потім скасували платіж.

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

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

Friendly fraud це патерн, за яким варто стежити

voidedReason зі значенням 5 або 6 не є одноразовим. Fraud і friendly fraud групуються за обліковим записом, за пристроєм, а іноді за промоакцією. API дає вам voidedSource і voidedReason на кожному анулюванні, чого достатньо, щоб відстежувати зловживання за обліковим записом, замість того щоб трактувати кожне скасування як окрему витрату. Клієнт, який робить chargeback двічі, каже вам щось, чого не сказало перше повернення.

Як під'єднати це способом RefundHalt

Модель невелика, коли ви тримаєте всі частини. Слухайте VoidedPurchaseNotification у реальному часі, щоб ніщо не чекало цілу добу. Викликайте Voided Purchases API як джерело істини, прив'язане до orderId, щоб поновлення підписок ніколи не плуталися. Читайте voidedSource і voidedReason, щоб chargeback оброблявся інакше, ніж повернення через каяття. Опитуйте за розкладом, достатньо щільним, щоб вікно у 30 днів ніколи не кусало, і робіть повернення з увімкненою опцією revoke щоразу, коли ваш намір відрізати доступ.

Це та частина, яку RefundHalt виконує за вас. Він споживає повідомлення в реальному часі, звіряє кожне анулювання з API, відкликає точне замовлення, а не весь продукт, і відділяє банківський chargeback від звичайного повернення, щоб дорогі були позначені, а не поховані. Ви отримуєте доступ, відкликаний за секунди, і запис про те, хто що і чому анулював, без потреби самостійно розгортати конвеєр Pub/Sub і завдання опитування.

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

Чому мої повернені замовлення не показуються у Voided Purchases API?
Бо повертаються лише відкликані замовлення. Повернення користувачів, скасування, chargeback і повернення, ініційовані Google, завжди відкликаються і завжди з'являються. Повернення, ініційоване розробником, з'являється лише якщо ви також обрали опцію revoke. Якщо ви повернули замовлення без відкликання, замовлення врегульоване, але невидиме для цього API, тож робіть повернення з увімкненим revoke щоразу, коли маєте намір забрати доступ.
Наскільки далеко назад сягає Voided Purchases API?
Тридцять днів. Параметр startTime за замовчуванням дорівнює поточному часу мінус 30 днів і не може бути встановлений старішим за це, тож кінцева точка це рухоме одномісячне вікно, а не архів. Анульоване замовлення, яке за давністю переходить межу 30 днів, зникає з API без способу його отримати, ось чому ви опитуєте за розкладом і підкріплюєте це real-time notifications.
Чи слід використовувати real-time developer notifications, чи Voided Purchases API, щоб відкликати доступ?
Використовуйте обидва. VoidedPurchaseNotification надходить за лічені секунди і каже вам подивитися, але власна настанова Google це ставитися до нього як до сигналу, а не джерела істини. Викликайте Voided Purchases API, щоб підтвердити поточний стан, потім відкликайте. Повідомлення усуває затримку, а API дає вам авторитетні voidedSource і voidedReason, щоб діяти.
Як мені відрізнити chargeback від звичайного повернення в API?
Прочитайте поле voidedReason. Значення 7 це chargeback, що означає, що банк клієнта скасував платіж, а 6 це friendly fraud. Значення 1 це повернення через каяття. Це важливо, бо з 3 серпня 2026 року Google передає розробнику ціну покупки за chargeback і банківську комісію, тож voidedReason зі значенням 7 коштує вам більше, ніж звичайне повернення.
Чи охоплює Voided Purchases API підписки?
Так. Встановіть параметр type на 1, щоб отримати як анульовані покупки в застосунку, так і анульовані покупки підписок. За замовчуванням, type 0, повертає лише покупки продуктів у застосунку. Для підписок ідентифікуйте точний анульований період за orderId, бо один purchaseToken охоплює кожне поновлення, а для кожної транзакції поновлення генерується новий orderId.

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

RefundHalt

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

Читайте далі

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

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