Серийные злоупотребления возвратами обходятся вам дважды, вот как магазины позволяют дать отпор
Клиент, который снова и снова оформляет возврат, это не случайность. Злоупотребление возвратами стоит вам возвращённых денег плюс тех вычислений, которые вы уже потратили, и оба магазина дают вам сигнал идентичности, appAccountToken от Apple и обфусцированный идентификатор аккаунта от Google, чтобы связать этот паттерн воедино.

Главное
- Только два процесса возврата когда-либо позволяют разработчику предоставить доказательства против злоупотребления возвратами: CONSUMPTION_REQUEST от Apple с окном в 12 hours и рассмотрение возвратного платежа в Google Play через Review Refund API с окном в 24 hours.
- appAccountToken от Apple это UUID, который вы генерируете и прикрепляете к покупке, а StoreKit связывает его с итоговой транзакцией, так что ваш сервер может привязать каждый возврат к точному аккаунту, который его совершил.
- Обфусцированный идентификатор аккаунта Google Play это хешированная строка длиной не более 64 characters, которую сам Google использует для обнаружения нерегулярной активности, например когда с одного аккаунта за короткий промежуток совершают покупки множество устройств.
- Хранение персональных данных в открытом виде в обфусцированном идентификаторе аккаунта Google приводит к блокировке ваших покупок, поэтому поле должно содержать зашифрованное значение или односторонний хеш, но никогда не сырой email.
- Поле voidedReason в Google Play помечает friendly_fraud и fraud как причины, отличные от обычного возврата по причине remorse, что позволяет направлять повторных злоумышленников в очередь на рассмотрение вместо автоматического пути «вернуть и забыть».
- Google сообщает, что в 2022 заблокировал мошеннических и недобросовестных транзакций более чем на $2 billion, и поля идентичности, питающие эту систему, работают только если вы заполняете их при каждой покупке.
- Каждая возвращённая покупка, сохраняющая доступ, это вычисления, хранилище и расходы на API, за которые вы продолжаете платить с денег, которые уже вернули, а серийный любитель возвратов намеренно умножает этот счёт.
Один возврат это издержки ведения бизнеса. Тот же аккаунт, оформляющий возврат в четвёртый раз после того, как каждый раз использовал купленное, это злоупотребление возвратами, и это паттерн, который вы можете увидеть только если каждая покупка несёт контролируемую вами идентичность. И Apple, и Google дают вам эту идентичность, и оба дают узкое окно, чтобы предъявить её магазину до того, как решение о возврате или возвратном платеже будет принято. Пропустите окно или не прикрепите идентичность, и серийный любитель возвратов будет выглядеть точно так же, как впервые недовольный клиент. Вот как их различить и во что обходится эта разница в деньгах.
Почему злоупотребление возвратами это проблема идентичности, а не проблема возврата
Решение о возврате принимает магазин. Вы не можете помешать клиенту попросить, а в большинстве процессов вы не можете помешать магазину удовлетворить просьбу. Что вы можете сделать, это решить, делал ли данный аккаунт это раньше и был ли купленный контент действительно доставлен и использован. Оба этих вопроса про идентичность: кто из ваших пользователей стоит за этой транзакцией и какова его история. Если ваши покупки не несут стабильного идентификатора, ведущего к вашим собственным записям о пользователях, вы не можете ответить ни на один из вопросов, и каждый возврат приходит без контекста.
Вот в чём настоящий пробел. Механика возврата зафиксирована политикой. Доказательства, которые вы к ней приносите, целиком в вашей власти построить, и они начинаются в момент покупки, а не в момент возврата.
Два окна, где доказательства меняют исход
Существует ровно два процесса, где что-либо отправленное вами может повлиять на решение. CONSUMPTION_REQUEST от Apple срабатывает, когда клиент просит возврат за расходуемую покупку или автовозобновляемую подписку, и у вас есть 12 hours на ответ. Рассмотрение возвратного платежа в Google Play срабатывает, когда пользователь оспаривает списание в своём банке, и у вас есть 24 hours, чтобы ответить через Review Refund API. Любой другой возврат, 48-hour возврат по самообслуживанию в Play, возврат, предоставленный поддержкой, автоматический возврат за неподтверждённую покупку, решается без вас.
Оба этих канала доказательств гораздо сильнее, когда транзакция уже несёт ваш идентификатор. Информация о потреблении Apple может включать appAccountToken наряду с историей аккаунта и его тратами, а рассмотрение в Google может опереться на обфусцированный идентификатор аккаунта, за которым оно наблюдало с момента покупки. Аккаунт без идентификатора это аккаунт без истории, которую можно предъявить.
Два поля идентичности, бок о бок
Apple и Google решили одну и ту же задачу почти одинаково, с разными названиями и разными правилами. Оба позволяют пометить покупку значением, ведущим обратно к вашей собственной записи о пользователе. Ни одно не включено по умолчанию. Оба бесполезны, если вы не задаёте их в момент покупки.
Apple: appAccountToken
appAccountToken это UUID, который вы генерируете и передаёте при начале покупки. StoreKit связывает его с итоговой транзакцией, и он появляется в данных транзакции, которые проверяет ваш сервер, и в информации о потреблении, которую вы отправляете обратно во время CONSUMPTION_REQUEST. Поскольку это ваше значение, оно сопоставляет транзакцию магазина напрямую с аккаунтом в вашей базе данных, без участия email или имени. Оно должно быть настоящим UUID, а всё иное отклоняется. Позже Apple добавила эндпойнт Set App Account Token, который может прикреплять или обновлять токен на прошлых транзакциях, включая покупки, сделанные вне вашего приложения, например погашение промокодов.
Google Play: обфусцированный идентификатор аккаунта
Эквивалент Google это setObfuscatedAccountId, необязательная строка, привязанная к покупающему аккаунту. Собственная документация Google прямо говорит о её назначении: Google Play использует её для обнаружения нерегулярной активности, например когда множество устройств совершают покупки на одном аккаунте за короткий промежуток, и чтобы заблокировать часть мошеннических транзакций до их завершения. Она ограничена 64 characters и не должна содержать персональные данные в открытом виде. Сохраните туда сырой email, и Google полностью заблокирует покупку, потому что поле ожидает зашифрованное значение или односторонний хеш. Родственное поле setObfuscatedProfileId существует для приложений, где один аккаунт держит несколько профилей.
| Поле | Магазин | Тип и ограничение | Устанавливает | По умолчанию | Что магазин с ним делает |
|---|---|---|---|---|---|
| appAccountToken | Apple | UUID | Вы, при покупке | Не задано | Привязывает транзакцию к вашему пользователю, возвращается в данных транзакции и потребления |
| obfuscatedAccountId | Google Play | Хешированная строка, макс. 64 симв. | Вы, при покупке | Не задано | Обнаруживает нерегулярную активность и блокирует часть мошенничества до завершения |
Во что на самом деле обходится возврат от серийного злоумышленника
Сам возврат это наименьшая часть счёта. Когда магазин удовлетворяет возврат, вы отдаёте выручку, и это видно в бухгалтерской книге. Чего нет в строке возврата, так это всего, что вы потратили на доставку продукта, который теперь бесплатен.
Представьте расходуемую покупку, которая запускает реальную работу: генерацию изображения, пакет вызовов API к провайдеру модели, экспорт видео, выплату автору. Вы заплатили за эти вычисления в тот момент, когда клиент их использовал. Возврат отбирает обратно цену, но не отбирает счёт от провайдера. Серийный любитель возвратов это тот, кто усвоил, что контент переживает возврат, поэтому он запускает цикл заново: купить, потребить, вернуть, повторить. Каждый цикл вы съедаете стоимость доставки во второй раз.
Затем есть собственный сдвиг издержек магазина. С August 3 2026 Google Play переносит цену покупки и банковские комиссии за возвратный платёж на разработчика для заказов, размещённых после этой даты. Возвратный платёж, который раньше был в основном проблемой Google, становится вашей выручкой плюс комиссией, и повторный оспариватель поднимает это число каждый раз. Поля идентичности это то, что позволяет вам передать в Review Refund API доказательства для оспаривания незаконного спора внутри окна в 24 hours.
Google обозначает масштаб прямо: он сообщает, что заблокировал мошеннических и недобросовестных транзакций более чем на $2 billion в 2022. Это число существует потому, что сигналы, среди них обфусцированный идентификатор аккаунта, были заполнены. Приложение, которое отправляет покупки с пустыми полями идентичности, отказывается от этой защиты.

Как поймать повторных любителей возвратов до того, как магазин примет решение
Помечайте каждую покупку идентичностью, которой владеете вы
Задавайте appAccountToken на каждой покупке StoreKit и setObfuscatedAccountId на каждой покупке Play Billing, обе сгенерированные из вашей собственной записи о пользователе. На Apple используйте настоящий UUID, сопоставленный с аккаунтом. На Google хешируйте ключ аккаунта, чтобы никакие персональные данные не путешествовали в открытом виде. Делайте это в момент покупки, потому что на Google это единственный шаг, который вы не можете восстановить позже.
Ведите реестр, ключом которого является эта идентичность
Сохраняйте каждую покупку, доставку, событие потребления и возврат против идентификатора. Когда приходит CONSUMPTION_REQUEST или рассмотрение возвратного платежа, полная история аккаунта, включая предыдущие возвраты, находится в одном запросе. Информация о потреблении Apple имеет явные поля именно для этого: consumptionStatus, deliveryStatus, playTime, accountTenure, lifetimeDollarsPurchased и ваш refundPreference.
Читайте voidedReason и направляйте злоумышленников иначе
Когда покупка Google аннулируется, поле voidedReason сообщает вам почему, и friendly_fraud и fraud это отдельные значения от обычного возврата по причине remorse. Направляйте их в очередь на рассмотрение и к более строгой политике, а не по тому же автоматическому пути, что и первый возврат. Собственное руководство Google это модель нескольких предупреждений: предупредите первого нарушителя, примите более жёсткие меры к повторным и отключите покупки для аккаунта, который продолжает.
Отвечайте в окно каждый раз
Доказательства засчитываются только внутри двух окон. Автоматизируйте ответ на CONSUMPTION_REQUEST так, чтобы он срабатывал с хорошим запасом внутри 12 hours, а рассмотрение возвратного платежа чтобы оно срабатывало внутри 24. Идеальная история, которую вы подаёте с опозданием, это история, которую магазин никогда не прочтёт.
| Сигнал, который вы хотите поймать | Где он живёт | Поле или процесс, который его раскрывает |
|---|---|---|
| Тот же аккаунт, много устройств, короткое окно | Google Play | Обнаружение нерегулярной активности по обфусцированному идентификатору аккаунта |
| Этот аккаунт уже оформлял возврат раньше | Ваш реестр | История с ключом по appAccountToken или обфусцированному идентификатору аккаунта |
| Контент был доставлен и потреблён | Apple | deliveryStatus и consumptionStatus в информации о потреблении |
| Спор на самом деле это мошенничество со стороны первой стороны | Google Play | Значение voidedReason friendly_fraud |
Что магазины будут и не будут делать за вас
Стоит быть точным насчёт разделения труда, потому что легко предположить, что магазины справляются со злоупотреблениями, а они по большей части не сообщают вам, когда не справляются. Google активно использует обфусцированный идентификатор аккаунта для блокировки части мошенничества до завершения покупки, и его системы ловят большую долю на уровне платформы. Apple сама решает каждый возврат и рассматривает вашу информацию о потреблении как входные данные, но никогда как голос. Ни один магазин не ведёт за вас ваш список злоумышленников, не вычитает возвращённую расходуемую покупку из вашего баланса и не говорит повторному любителю возвратов нет от вашего имени. Идентичность это то, на что магазин действует на границах, а вы действуете везде остальном.
Это та же причина, по которой RefundHalt делает ключом всего идентичность покупки: возврат, рассмотрение возвратного платежа и запрос о потреблении для одного аккаунта разрешаются в одну историю, так что серийный любитель возвратов проявляется как паттерн уже при первом повторении, а не после четвёртого счёта, который вы уже оплатили.
Частые вопросы
- Что такое злоупотребление возвратами в приложении?
- Злоупотребление возвратами это когда клиент многократно запрашивает возвраты после получения и использования купленного, так что он сохраняет контент или выгоду, получая деньги обратно. В магазинах приложений это обычно проявляется как один и тот же аккаунт, снова и снова возвращающий расходуемые покупки или подписки, либо как friendly fraud, когда легитимное списание оспаривается в банке.
- Как связать внутреннюю покупку с конкретным пользователем?
- На Apple сгенерируйте UUID и передайте его как appAccountToken при начале покупки, и StoreKit свяжет его с транзакцией и вернёт в данных транзакции и потребления. В Google Play вызовите setObfuscatedAccountId с хешированным значением, привязанным к аккаунту. Оба сопоставляют транзакцию магазина с вашей собственной записью о пользователе, не раскрывая персональных данных.
- Может ли Apple или Google сказать мне, что аккаунт это повторный любитель возвратов?
- Не напрямую. Google использует обфусцированный идентификатор аккаунта для обнаружения нерегулярной активности и блокировки части мошенничества до покупки, а Apple позволяет вам подавать историю аккаунта во время запроса о потреблении, но ни один магазин не выдаёт вам список повторных любителей возвратов. Вы строите его сами из своего собственного реестра с ключом по полям идентичности.
- Почему Google блокирует мою покупку, когда я задаю идентификатор аккаунта?
- Потому что обфусцированный идентификатор аккаунта не должен содержать персональные данные в открытом виде. Хранение чего-то вроде сырого адреса email в нём заставляет Google Play заблокировать покупку. Используйте зашифрованное значение или односторонний хеш и держитесь внутри ограничения в 64 characters.
- Останавливает ли оспаривание возвратов через запрос о потреблении злоупотребления?
- Оно может их снизить. CONSUMPTION_REQUEST это один из всего двух процессов, где ваши доказательства достигают магазина до того, как он примет решение, и история аккаунта плюс данные о доставке и потреблении помогают Apple выявлять злоупотребление возвратами и friendly fraud. Однако это не блокировка. Apple всё равно решает, а злоупотребление, приходящее через неоспариваемые процессы, остаётся незатронутым.
Источники и дополнительное чтение
- Apple: appAccountToken (App Store Server API)
- Apple: ConsumptionRequest (App Store Server API)
- Android: BillingFlowParams.Builder.setObfuscatedAccountId
- Android: Fight fraud and abuse (Play Billing security)
- Google Play Developer API: Voided Purchases
- Google Play Billing: Provide refund and chargeback suggestions (Review Refund API)
- Android Developers Blog: Play Commerce prevented over $2 billion in fraudulent and abusive transactions in 2022
- Google Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
Автопилот возвратов для App Store и Google Play
Читайте дальше
The refunds you cannot contest: what Apple and Google decide without asking you
Only two refund flows ever ask for your evidence: Apple's consumption request and Google Play's chargeback review. Everything else, the 48-hour Play refund, support refunds, voided purchases, unacknowledged trials, is decided without you. Here is the full map, what you can prevent, and what you can only record.
Apple's CONSUMPTION_REQUEST, explained: the 12 hours that decide your refund
When a customer asks Apple for a refund, Apple asks you first. Here's exactly what the CONSUMPTION_REQUEST notification contains, what Apple expects back, how to answer one end to end, and why most developers silently forfeit.