Все статьи
Deep dive9 мин чтения

Ваши данные о потреблении информируют решение Apple о возврате, но не управляют им

Когда клиент просит у Apple возврат, у вас есть 12 часов, чтобы отправить данные о потреблении. Собственная документация Apple называет это одним из множества факторов, а не приговором. Вот что на самом деле меняют ваши данные, почему DECLINE все равно может закончиться возвратом и чего стоит этот сигнал в деньгах.

Рука кладет небольшую латунную гирьку на весы, где уже лежит несколько других, символизируя данные о потреблении как один из факторов в решении Apple о возврате

Главное

  • Когда клиент запрашивает возврат, Apple отправляет на ваш сервер уведомление CONSUMPTION_REQUEST и дает вам 12 часов, чтобы ответить данными о потреблении через эндпоинт Send Consumption Information. Пропустите это окно, и Apple примет решение без вашего участия.
  • Собственными словами Apple: App Store использует множество факторов при принятии решения о возврате, а данные о потреблении, которые вы отправляете, служат для информирования этого решения. Ваш refundPreference, это один из таких факторов, а не приговор.
  • Вы можете отправить refundPreference со значением предпочтение отклонить, предпочтение вернуть полностью или предпочтение вернуть пропорционально. Apple взвешивает его. Именно поэтому команды видят, как покупка, для которой указано предпочтение отклонить, все равно получает возврат, и это работает так, как описано в документации.
  • Apple отклоняет ваши данные о потреблении, если customerConsented не равно true. Если клиент не дал согласия на передачу данных, рекомендация Apple, это вообще не отвечать на уведомление, и вы несете единоличную ответственность за получение этого согласия.
  • Начиная с WWDC24 CONSUMPTION_REQUEST срабатывает и для автопродлеваемых подписок, а не только для расходуемых покупок, так что тот же 12-часовой ответ теперь охватывает гораздо больше ваших возвратов, чем раньше.
  • Для автопродлеваемых подписок Apple сама рассчитывает потребление и запрещает предпочтение пропорционального возврата, поэтому здесь ваше влияние слабее, чем на расходуемой покупке, которую вы можете описать как полностью использованную.
  • Деньги, которые вы уже потратили на исполнение покупки, вычисления, вызовы сторонних API, хранилище, ушли независимо от того, одобрит Apple возврат или нет. Ваш ответ о потреблении меняет возврат, но никогда не меняет затраты, которые вы уже понесли на доставку.

Клиент нажимает возврат, и в течение минуты ваш сервер получает CONSUMPTION_REQUEST от Apple. У вас есть 12 часов, чтобы ответить данными о потреблении, и возникает соблазн прочитать этот ответ как право вето: отправьте предпочтение отклонить, оставьте деньги себе. Это не вето. Собственная документация Apple говорит, что App Store использует множество факторов для определения того, будет ли запрос на возврат одобрен или отклонен, и что предоставленные вами данные о потреблении служат для информирования его решений о возврате. Информировать, а не решать. Этот пост разбирает, что на самом деле меняют ваши данные о потреблении, почему покупка, для которой указано предпочтение отклонить, все равно может быть возвращена, и чего стоит все это упражнение, когда вы учтете уже потраченные деньги.

Что Apple на самом деле делает с вашими данными о потреблении

Эндпоинт Send Consumption Information существует, чтобы вы могли передать Apple контекст в момент, когда возврат под вопросом. Он не передает вам само решение. Чтение этого потока в правильном порядке, это разница между разумными ожиданиями и заведением бага на поведение, которое задокументировано.

App Store решает, а вы рекомендуете

Apple явно разделяет роли. В справочнике по Send Consumption Information Apple пишет, что App Store использует множество факторов для определения того, будет ли запрос на возврат одобрен или отклонен, и что он использует предоставленные вами данные о потреблении для информирования своих решений о возврате. О самом поле refundPreference Apple заявляет, что ваше предпочтение по возврату, это один из множества факторов, которые App Store использует для информирования своих решений о возврате. Значит, самый сильный сигнал, который вы можете отправить, прямое предпочтение отклонить, все равно остается одним входным параметром в модели, которую вы не контролируете. История клиента, указанная им причина, тип продукта и собственные сигналы Apple о мошенничестве, все это находится в той же модели рядом с вашим ответом.

CONSUMPTION_REQUEST теперь охватывает подписки, а не только расходуемые покупки

Раньше это была история про расходуемые покупки. Начиная с WWDC24 уведомление CONSUMPTION_REQUEST срабатывает, когда клиент запрашивает возврат за расходуемую внутреннюю покупку или автопродлеваемую подписку. Это большое расширение охвата. Тот же 12-часовой ответ теперь применяется и к возвратам по подпискам, где ваше влияние иное, потому что Apple сама рассчитывает потребление для автопродлеваемых подписок и не примет от вас предпочтение пропорционального возврата. Читайте тип продукта в каждом запросе, прежде чем решать, насколько сильно может давить ваш ответ.

Пять входных параметров, которые вам разрешено отправлять

Тело запроса V2, которое принимает Apple, невелико, работу делают пять полей, и три из них обязательны. Каждый из них, это входной параметр, который Apple взвешивает, а не переключатель, форсирующий исход. Вот что вы можете вложить в ответ и что это сообщает Apple.

ПолеОбязательноЧто это сообщает Apple
customerConsentedДаСогласился ли клиент поделиться этими данными о возврате. Должно быть true, иначе Apple отклонит запрос.
consumptionStatusНетСколько было использовано: не указано, не использовано, использовано частично или использовано полностью.
deliveryStatusНетДоставило ли ваше приложение работающую покупку или столкнулось с проблемой, которую вы хотите зафиксировать.
sampleContentProvidedНетПредлагали ли вы бесплатный образец, пробную версию или описание функции до покупки.
refundPreferenceНетВаш рекомендуемый исход: предпочтение отклонить, предпочтение вернуть полностью или предпочтение вернуть пропорционально.

12-часовое окно и барьер согласия, который пропускает большинство команд

Две механики решают, будет ли ваш ответ вообще учтен. Одна, это часы. Другая, это флаг согласия, который останавливает множество благих ответов прямо на пороге.

Ответьте в течение 12 часов или момент упущен

Инструкция Apple проста: ответьте в течение 12 часов после получения уведомления CONSUMPTION_REQUEST. Это все окно. Запрос на возврат не ждет вашего следующего рабочего дня, а ответ о потреблении, который приходит с опозданием, это ответ, который Apple так и не взвесила. Если вы отвечаете на них вручную, 12-часовые часы, это то, что тихо отказывает первым, по выходным, по праздникам и в 3 часа ночи по вашему часовому поясу. Ответ должен быть автоматизирован, чтобы быть надежным, потому что окну все равно, когда бодрствует ваша команда.

Циферблат аналоговых часов на столе рядом со смартфоном, лежащим экраном вниз, символизирует 12-часовое окно для ответа на CONSUMPTION_REQUEST от Apple

Вы не можете отправить данные, пока клиент не дал согласия

Вот барьер, о который спотыкаются команды. Apple отклоняет запрос Send Consumption Information, у которого значение customerConsented не равно true. Словами Apple: если клиент дал согласие, ответьте, вызвав API и отправив данные о потреблении; если нет, не отвечайте на уведомление CONSUMPTION_REQUEST. Apple также прямо возлагает ответственность на вас: вы должны получить действительное согласие клиента перед передачей его персональных данных, и вы, разработчик, несете единоличную ответственность за его получение. Значит, первый вопрос по каждому запросу не в том, сколько они использовали, а в том, согласился ли этот клиент, чтобы мы рассказали Apple. Нет согласия, нет ответа, и возврат решается на основании всего, кроме вашей версии истории.

Что на самом деле меняет решение Apple о возврате

Если ответ, это рекомендация, честный вопрос в том, насколько сильно она рекомендует. Ответ таков: ваши данные значат больше всего именно там, где человек колебался бы, и меньше всего там, где исход и так не вызывал сомнений.

Почему вы можете отправить предпочтение отклонить и все равно увидеть возврат

Разработчики сообщают, что отправляют предпочтение отклонить по покупке, которую клиент полностью использовал, и видят, как Apple все равно возвращает за нее деньги. Это не сломанный API. Apple сказала вам, что взвешивает множество факторов, и в любом конкретном запросе некоторые из этих факторов могут перевесить полностью использованную расходуемую покупку: клиент с чистой историей, названная причина, которую Apple считает весомой, небольшая сумма, первый запрос. Ваш ответ давил против возврата. Другие входные параметры давили сильнее. Урок не в том, чтобы перестать отвечать, а в том, чтобы перестать ожидать, что чистая расходуемая покупка всегда уцелеет. Там, где сигнал действительно неоднозначен, статус частичного использования, задокументированная проблема с доставкой и честное предпочтение, это входные параметры, которые могут склонить пограничный случай в вашу пользу.

Сколько стоит рекомендация в деньгах

Возврат, это не цена продажи. Это цена продажи плюс все, что вы уже потратили на ее доставку, а ответ о потреблении затрагивает только первую часть.

К моменту прихода запроса деньги уже потрачены

К тому времени, когда Apple спрашивает, возвращать ли деньги, клиент уже использовал вещь. На расходуемой покупке это значит, что вычисления отработали, вызовы сторонних API были оплачены, изображения, токены или генерации были произведены, а хранилище было записано. Это оплаченные затраты на вашей стороне, и они не возвращаются, если Apple отклоняет возврат, и они теряются дважды, если Apple его одобряет. Ваш ответ о потреблении может отыграть цену продажи в пограничном случае. Он не может отыграть стоимость товаров, которые вы уже передали. Вот настоящая причина, почему полностью использованная покупка, это дорогая для возврата, и это не имеет отношения к тому, как давно она была куплена.

  • Цена продажи: ваша чистая выручка после комиссии Apple, отменяемая, если возврат одобрен. Это единственная часть, на которую может повлиять ваш ответ.
  • Стоимость доставки: вычисления, вызовы API, хранилище и любая выплата, которую вы уже сделали по покупке. Ушла независимо от решения.
  • Время персонала: каждый возврат, обработанный вручную, это минуты чьего-то дня, а 12-часовое окно означает, что эти минуты выпадают на неудобные часы.
  • Пропущенная закономерность: клиент, который возвращает снова и снова, это затрата, которую вы видите только если отслеживаете потребление и историю по всем запросам, а не рассматриваете каждый как разовый.

Как Google Play решает тот же вопрос

Apple, это не единственный магазин, который просит вас высказаться, а затем решает сам. Google Play запускает параллельный поток для банковских чарджбэков, и форма та же: вы отправляете доказательства, магазин решает. Различия, в часах и в том, что вам разрешено отправлять.

ВопросApp StoreGoogle Play
ТриггерУведомление CONSUMPTION_REQUESTPendingRefundReviewNotification для чарджбэка
Ваше окно12 часов24 часа
Как вы отвечаетеSend Consumption Informationorders.reviewrefund
Ваша рекомендацияrefundPreference: отклонить, вернуть полностью, вернуть пропорциональноrefundPreference: APPROVE, DECLINE или NEUTRAL
Кто решаетApp StoreGoogle Play или банк при чарджбэке

Вывод по обоим магазинам одинаков. Ваша работа, ответить в пределах окна точными доказательствами потребления и честным предпочтением. Работа магазина, решить. Путаница между этими двумя, это то, как команда в итоге либо игнорирует окно, потому что ответ, это лишь рекомендация, либо доверяет ответу как вето и оказывается застигнутой врасплох, когда возврат все же приходит. Ни то, ни другое не верно. Отвечайте каждый раз, отвечайте точно и относитесь к исходу как к решению, которое вы проинформировали, а не приняли.

RefundHalt перехватывает CONSUMPTION_REQUEST в момент, когда Apple его отправляет, проверяет согласие, собирает статус потребления, статус доставки и основанное на доказательствах предпочтение по возврату и отвечает в пределах 12-часового окна, при этом никто в вашей команде не следит за часами. То же самое он делает для проверки чарджбэков Google Play в пределах ее 24-часового окна. Вы не можете заставить Apple решить в вашу пользу. Вы можете сделать так, чтобы Apple никогда не решала без вашей версии истории, по каждому возврату, вовремя.

Частые вопросы

Останавливает ли отправка данных о потреблении в Apple возврат?
Не сама по себе. Документация Apple говорит, что App Store использует множество факторов для решения о возврате и что ваши данные о потреблении служат для информирования этого решения. Ваш ответ, включая refundPreference со значением предпочтение отклонить, это один входной параметр, который Apple взвешивает, так что он может сдвинуть пограничный случай, но не гарантирует отказ, особенно по покупке, которую клиент полностью использовал.
Сколько времени у меня есть, чтобы ответить на CONSUMPTION_REQUEST?
12 часов. Apple говорит отвечать в течение 12 часов после получения уведомления CONSUMPTION_REQUEST через эндпоинт Send Consumption Information. Ответ, который приходит после окна, это ответ, который Apple так и не взвесила, поэтому реакция должна быть автоматизирована, а не выполняться человеком, который может спать.
Почему Apple вернула деньги за покупку после того, как я отправил предпочтение отклонить?
Потому что предпочтение отклонить, это рекомендация, а не команда. Apple заявляет, что ваше предпочтение по возврату, это один из множества факторов, которые она использует для информирования своего решения. В конкретном запросе история клиента, указанная им причина, сумма и собственные сигналы Apple о мошенничестве могут перевесить ваше предпочтение, так что возврат после предпочтения отклонить, это поток, работающий так, как описано в документации.
Нужно ли мне согласие клиента, чтобы отправить данные о потреблении?
Да. Apple отклоняет запрос Send Consumption Information, если customerConsented не равно true, и ее рекомендация в том, что если клиент не дал согласия, вам вообще не следует отвечать на CONSUMPTION_REQUEST. Apple также заявляет, что вы, разработчик, несете единоличную ответственность за получение действительного согласия перед передачей данных клиента.
Работает ли поток потребления для подписок или только для расходуемых покупок?
И для того, и для другого, начиная с WWDC24. CONSUMPTION_REQUEST теперь срабатывает для расходуемой внутренней покупки или автопродлеваемой подписки. Для автопродлеваемых подписок Apple сама рассчитывает потребление и не принимает предпочтение пропорционального возврата, так что ваше влияние уже, чем на расходуемой покупке, использование которой вы можете описать напрямую.

Источники и дополнительное чтение

RefundHalt

Автопилот возвратов для App Store и Google Play

Читайте дальше

Playbook8 мин чтения

Помечайте каждую покупку в Google Play обфусцированным идентификатором аккаунта, иначе возвратный платёж придёт без возможности его отследить

Google Play позволяет проставить на каждую покупку стабильный хешированный идентификатор и считывает его обратно, когда возникает спор. Настройте это, и разбор возвратного платежа привяжется к тому самому пользователю, чьё потребление вы обязаны отчитать. Пропустите, и вы будете сопоставлять голый идентификатор заказа с догадками под 24-часовым таймером.

Deep dive8 мин чтения

Неопознанное списание в банковской выписке превращается в чарджбэк, а чарджбэк обходится дороже, чем возврат

Когда клиент не может понять, за что ваше приложение списало деньги, он звонит в банк, а не вам, и этот спор оборачивается чарджбэком. Apple показывает всё как apple.com/bill и не позволяет ничего изменить. Google Play даёт задать название в выписке. Вот сколько стоит каждый вариант и что вы контролируете.

Следующий запрос на возврат уже в пути.

Настройте RefundHalt за то время, что уходит на чтение очередного письма в поддержку о возврате, который вы не успели оспорить.