Потоки событий
В Adapty вы будете получать различные события подписок на протяжении всего пути пользователя в вашем приложении. Эти потоки описывают типичные сценарии и помогают понять, какие события Adapty генерирует, когда пользователи оформляют, отменяют или возобновляют подписки.
Обратите внимание: Apple обрабатывает платежи за подписку за несколько часов до фактического начала или продления. На схемах ниже начало/продление подписки и списание средств показаны одновременно — для наглядности.
Кроме того, события, связанные с одним действием, происходят одновременно и могут появляться в вашем Event Feed в любом порядке, который может отличаться от последовательности на наших схемах.
Жизненный цикл подписки
Поток первоначальной покупки
Этот поток возникает, когда пользователь впервые покупает подписку без пробного периода. В этом случае создаются следующие события:
- Subscription started
- Access level updated — для предоставления доступа пользователю
Когда наступает дата продления подписки, подписка возобновляется. При этом создаются следующие события:
- Subscription renewal — для начала нового периода подписки
- Access level updated — для обновления даты истечения подписки и продления доступа ещё на один период
Ситуации, когда платёж не проходит или пользователь отменяет продление, описаны в разделах Поток исхода проблемы с оплатой и Поток отмены подписки соответственно.
Поток отмены подписки
Когда пользователь отменяет подписку, создаются следующие события:
- Subscription renewal canceled — указывает, что подписка остаётся активной до конца текущего периода, после чего пользователь потеряет доступ
- Access level updated — для отключения автопродления доступа
Когда подписка заканчивается, срабатывает событие Subscription expired (churned), отмечающее окончание подписки.
Если возврат средств одобрен, вместо Subscription expired (churned) создаётся следующее событие:
- Subscription refunded — для завершения подписки с указанием деталей возврата
Для Stripe подписка может быть отменена немедленно, без ожидания оставшегося периода. В этом случае все события создаются одновременно:
- Subscription renewal cancelled
- Subscription expired (churned)
- Access Level updated — для лишения пользователя доступа
Если возврат средств одобрен, при его одобрении также срабатывает событие Subscription refunded.
Поток повторной активации подписки
Если пользователь отменил подписку, подписка истекла, а затем он повторно купил ту же подписку, будет создано событие Subscription renewed. Даже при наличии перерыва в доступе Adapty считает это единой цепочкой транзакций, связанной через vendor_original_transaction_id. Поэтому повторная покупка рассматривается как продление.
События Access level updated создаются дважды:
- при окончании подписки — для отзыва доступа пользователя
- при повторной покупке подписки — для предоставления доступа
Поток приостановки подписки (только Android)
Этот поток применяется, когда пользователь приостанавливает и затем возобновляет подписку на Android.
Приостановка подписки имеет отложенный эффект. Если пользователь приостанавливает подписку до момента её продления, подписка остаётся активной, и пользователь сохраняет оплаченный доступ до конца расчётного периода.
-
Когда пользователь приостанавливает подписку, срабатывает событие Subscription paused (Android only).
-
По окончании периода подписки Adapty создаёт событие Access level updated для отзыва доступа пользователя.
-
Когда пользователь возобновляет подписку, срабатывают следующие события:
- Subscription renewed
- Access level updated — для восстановления доступа пользователя
Эти подписки будут принадлежать одной цепочке транзакций, связанной одним vendor_original_transaction_id.
Потоки пробного периода
Если в вашем приложении используются пробные периоды, вы будете получать дополнительные события, связанные с пробным периодом.
Поток пробного периода с успешной конвертацией
Наиболее распространённый поток: пользователь начинает пробный период, привязывает карту и успешно конвертируется в обычную подписку по окончании пробного периода. В этом случае в момент начала пробного периода создаются следующие события:
- Trial started — для отметки начала пробного периода
- Access level updated — для предоставления доступа
Событие Trial converted создаётся в момент начала обычной подписки.
Поток пробного периода без успешной конвертации
Если пользователь отменяет пробный период до его конвертации в подписку, в момент отмены создаются следующие события:
- Trial renewal cancelled — для отключения автоматической конвертации пробного периода в подписку
- Access level updated — для отключения автопродления доступа
Пользователь сохранит доступ до окончания пробного периода, после чего будет создано событие Trial expired, отмечающее его завершение.
Поток повторной активации подписки после истёкшего пробного периода
Если пробный период истёк (из-за проблемы с оплатой или отмены) и пользователь впоследствии покупает подписку, создаются следующие события:
- Access level updated — для предоставления доступа пользователю
- Trial converted
Даже при наличии перерыва между пробным периодом и подпиской Adapty связывает их через vendor_original_transaction_id. Эта конвертация рассматривается как часть непрерывной цепочки транзакций, начавшейся с бесплатного пробного периода. Именно поэтому создаётся событие Trial converted, а не Subscription started.
Изменения продукта
В этом разделе описаны любые изменения активных подписок: обновления до более дорогого тарифа, переход на более дешёвый или покупка продукта из другой группы.
Поток немедленного изменения продукта
После того как пользователь меняет продукт, изменение может быть применено немедленно, до окончания текущей подписки (в основном при обновлении до более дорогого тарифа или замене продукта). В этом случае в момент смены продукта:
- Уровень доступа меняется, и создаются два события Access level updated:
- для отзыва доступа к первому продукту.
- для предоставления доступа ко второму продукту.
- Старая подписка завершается и производится возврат средств (создаётся событие Subscription refunded с
cancellation_reason=upgraded). Обратите внимание: событие Subscription expired (churned) не создаётся — его заменяет Subscription refunded. - Начинается новая подписка (создаётся событие Subscription started для нового продукта).
При переходе на более дешёвый тариф первая подписка будет действовать до конца оплаченного периода, а по его окончании будет заменена новой подпиской более низкого уровня. В этом случае сразу создаётся только событие Access level updated для отключения автопродления доступа. Все остальные события создаются в момент фактической замены подписки:
- Ещё одно событие Access level updated — для предоставления доступа ко второму продукту.
- Событие Subscription expired (churned) — для завершения подписки на первый продукт.
- Событие Subscription started — для начала новой подписки на новый продукт.
Поток отложенного изменения продукта
Также существует вариант, когда пользователь меняет продукт в момент продления подписки. Этот вариант очень похож на предыдущий: сразу создаётся одно событие Access level updated для отключения автопродления доступа к старому продукту. Все остальные события создаются в момент, когда пользователь меняет подписку и изменение применяется в системе:
- Ещё одно событие Access level updated — для предоставления доступа ко второму продукту.
- Событие Subscription expired (churned) — для завершения подписки на первый продукт.
- Событие Subscription started — для начала новой подписки на новый продукт.
Поток исхода проблемы с оплатой
Если попытки конвертировать пробный период или продлить подписку завершаются неудачей из-за проблем с оплатой, дальнейший ход событий зависит от того, включён ли льготный период.
При наличии льготного периода: если платёж проходит успешно, пробный период конвертируется или подписка продлевается. Если платёж не проходит, магазин продолжает пытаться списать средства, и если это так и не удаётся, магазин самостоятельно завершает пробный период или подписку.
Таким образом, в момент проблемы с оплатой в Adapty создаются следующие события:
- Billing issue detected
- Entered grace period (если льготный период включён)
- Access level updated — для предоставления доступа до конца льготного периода
Если платёж впоследствии проходит успешно, Adapty фиксирует событие Trial converted или Subscription renewed, и пользователь не теряет доступ.
Если платёж так и не проходит и магазин отменяет подписку, Adapty генерирует следующие события:
- Trial expired или Subscription expired (churned) с
cancellation_reason: billing_error - Access level updated — для отзыва доступа пользователя
Без льготного периода период повторных попыток оплаты (Billing Retry Period — период, в течение которого магазин продолжает пытаться списать средства) начинается немедленно.
Если платёж так и не проходит до конца этого периода, поток тот же: при автоматическом завершении подписки магазином создаются те же события:
-
Trial expired или Subscription expired (churned) с
cancellation_reasonравнымbilling_error -
Access level updated — для отзыва доступа пользователя
Потоки совместного использования покупок между аккаунтами пользователей
Когда Customer User ID iOS, Android, React Native, Flutter и Unity пытается восстановить или расширить подписку, уже привязанную к другому Customer User ID iOS, Android, React Native, Flutter и Unity , настройка Sharing paid access between user accounts в Adapty определяет, как управляется доступ. Поток будет варьироваться в зависимости от выбранного варианта.
Поток передачи доступа новому пользователю
Рекомендуемый вариант — передача уровня доступа новому пользователю. Это сохраняет историю транзакций исходного пользователя для корректной аналитики. Создаются только 2 события Access level updated:
- для отзыва доступа первого пользователя
- для предоставления доступа второму пользователю
Ниже приведена расшифровка полей, связанных с назначением и передачей уровня доступа в событиях, генерируемых в этом сценарии:
-
User A: Access level updated (отправляется, когда User A покупает подписку в приложении)
{ "profile_id": "00000000-0000-0000-0000-000000000000", "customer_user_id": UserA, "event_properties": { "profile_has_access_level": true, }, "profiles_sharing_access_level": null } -
User A: Access level updated (отправляется, когда приложение переустанавливается и входит User B, лишая User A доступа)
{ "profile_id": "00000000-0000-0000-0000-000000000000", "customer_user_id": UserA, "event_properties": { "profile_has_access_level": false, }, "profiles_sharing_access_level": null } -
User B: Access level updated (отправляется, когда User B входит в систему и получает доступ)
{ "profile_id": "00000000-0000-0000-0000-000000000001", "customer_user_id": UserB, "event_properties": { "profile_has_access_level": true, }, "profiles_sharing_access_level": null }
Поток совместного доступа между пользователями
Этот вариант позволяет нескольким пользователям совместно использовать один и тот же уровень доступа, если их устройство авторизовано под одним Apple/Google ID. Это удобно, когда пользователь переустанавливает приложение и входит с другим адресом электронной почты — он всё равно сохранит доступ к предыдущей покупке. При этом варианте несколько идентифицированных пользователей могут совместно использовать один уровень доступа. Пока доступ является общим, все транзакции записываются под исходным Customer User ID iOS, Android, React Native, Flutter и Unity для сохранения полной истории транзакций и аналитики.
Поэтому будет создано только 1 событие: Access level updated для предоставления доступа второму пользователю.
Ниже приведена расшифровка полей, связанных с назначением и совместным использованием уровня доступа в событиях, генерируемых в этом сценарии:
User B: Access level updated (отправляется, когда User B входит в систему и получает доступ)
{
"profile_id": "00000000-0000-0000-0000-000000000000",
"customer_user_id": UserA,
"event_properties": {
"profile_has_access_level": true,
},
"profiles_sharing_access_level": [
{
"profile_id": "00000000-0000-0000-0000-000000000001,
"customer_user_id": UserB
}
]
}
Поток без совместного доступа между пользователями
При этом варианте только первый профиль пользователя, получивший уровень доступа, сохраняет его без ограничений по времени. Это идеальный вариант, если покупки должны быть привязаны к единственному Customer User ID iOS, Android, React Native, Flutter и Unity .