Потоки событий

В Adapty вы будете получать различные события подписки на протяжении всего пути пользователя в вашем приложении. Приведённые ниже сценарии подписки описывают типичные ситуации и помогают понять, какие события Adapty генерирует при оформлении, отмене или возобновлении подписки.

Обратите внимание, что Apple обрабатывает платежи за подписку за несколько часов до фактического начала или продления. В схемах ниже мы показываем начало/продление подписки и списание средств как одновременные события, чтобы диаграммы были понятнее. Кроме того, события, связанные с одним и тем же действием, происходят одновременно и могут отображаться в вашем Event Feed в произвольном порядке, который может отличаться от последовательности, показанной на наших диаграммах.

Жизненный цикл подписки

Поток первоначальной покупки

Этот поток срабатывает, когда пользователь впервые оформляет подписку без пробного периода. В этом случае создаются следующие события:

  • Subscription started
  • Access level updated — для предоставления пользователю доступа

Когда наступает дата обновления подписки, она продлевается. При этом создаются следующие события:

  • Subscription renewal — для начала нового периода подписки
  • Access level updated — для обновления даты истечения подписки и продления доступа ещё на один период Ситуации, когда платёж не прошёл или пользователь отменил продление, описаны в Billing Issue Outcome Flow и Subscription Cancellation Flow соответственно.
Initial_Purchase_Flow.webp

Поток отмены подписки

Когда пользователь отменяет подписку, создаются следующие события:

  • Subscription renewal canceled — указывает, что подписка остаётся активной до конца текущего периода, после чего пользователь потеряет доступ
  • Access level updated — создаётся для отключения автопродления уровня доступа

После окончания подписки срабатывает событие Subscription expired (churned), фиксирующее завершение подписки.

Subscription_Cancellation_Flow.webp

Если возврат средств одобрен, следующее событие заменяет Subscription expired (churned):

  • Subscription refunded — завершает подписку и предоставляет информацию о возврате средств
Subscription_Cancellation_Flow_with_a_Refund.webp

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

  • Subscription renewal cancelled
  • Subscription expired (churned)
  • Access Level updated — для отзыва доступа у пользователя Если возврат средств одобрен, также срабатывает событие Subscription refunded.
Subscription_Immediate_Cancellation_Flow.webp

Поток реактивации подписки

Если пользователь отменяет подписку, она истекает, а затем он повторно покупает ту же подписку, будет создано событие Subscription renewed. Даже если между периодами доступа есть разрыв, Adapty рассматривает это как единую цепочку транзакций, связанных через vendor_original_transaction_id. Поэтому повторная покупка считается продлением.

Событие Access level updated будет создано дважды:

  • в момент окончания подписки — чтобы отозвать доступ пользователя
  • в момент повторной покупки подписки — чтобы предоставить доступ
Subscription_Rejoin_Flow.webp

Поток приостановки подписки (только Android)

Этот поток применяется, когда пользователь приостанавливает и затем возобновляет подписку на Android.

Приостановка подписки имеет отложенный эффект. Если пользователь приостанавливает подписку до её продления, подписка остаётся активной, и пользователь сохраняет оплаченный доступ до конца расчётного периода.

  1. Когда пользователь приостанавливает подписку, срабатывает событие Subscription paused (Android only).

  2. По окончании периода подписки Adapty вызывает событие Access level updated, чтобы отозвать доступ пользователя.

  3. Когда пользователь возобновляет подписку, срабатывают следующие события:

    • Subscription renewed
    • Access level updated — для восстановления доступа пользователя

Все эти подписки относятся к одной цепочке транзакций, связанных одним vendor_original_transaction_id.

Subscription_Paused_Flow.webp

Потоки пробного периода

Если в вашем приложении используются пробные периоды, вы будете получать дополнительные события, связанные с пробным периодом.

Поток с успешной конвертацией пробного периода

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

  • Trial started — фиксирует начало пробного периода
  • Access level updated — предоставляет доступ

Событие Trial converted создаётся в момент, когда начинается обычная подписка.

Trial_Flow_with_Successful_Conversion.webp

Пробный период без успешной конвертации

Если пользователь отменяет пробный период до его конвертации в подписку, в момент отмены создаются следующие события:

  • Trial renewal cancelled — отключает автоматическую конвертацию пробного периода в подписку
  • Access level updated — отключает продление доступа

Пользователь сохраняет доступ до конца пробного периода, после чего создаётся событие Trial expired, фиксирующее его окончание.

Trial_Flow_without_Successful_Conversion.webp

Возобновление подписки после истёкшего пробного периода

Если пробный период завершился (из-за проблем с оплатой или отмены), а пользователь позже оформил подписку, создаются следующие события:

  • Access level updated — открывает доступ пользователю
  • Trial converted

Даже если между пробным периодом и подпиской прошло время, Adapty связывает их через vendor_original_transaction_id. Это преобразование рассматривается как часть непрерывной цепочки транзакций, начавшейся с пробного периода с нулевой ценой. Именно поэтому создаётся событие Trial converted, а не Subscription started.

Subscription_Reactivation_Flow_after_Expired_Trial.webp

Изменения продукта

В этом разделе описаны любые изменения активных подписок: обновления до более дорогого тарифа, переход на более дешёвый или покупка продукта из другой группы.

Немедленная смена продукта

После того как пользователь меняет продукт, изменение может вступить в силу сразу — до окончания текущей подписки (как правило, при апгрейде или замене продукта). В момент такой смены:

  • Уровень доступа изменяется, и создаются два события Access level updated:
    1. для отзыва доступа к первому продукту.
    2. для предоставления доступа ко второму продукту.
  • Старая подписка завершается, и выплачивается возврат средств (создаётся событие Subscription refunded с cancellation_reason = upgraded). Обратите внимание: событие Subscription expired (churned) при этом не создаётся — его заменяет событие Subscription refunded.
  • Новая подписка начинается (для нового продукта создаётся событие Subscription started).
Immediate_Product_Change_Flow_Upgrade.webp

Если пользователь понижает уровень подписки, первая подписка продолжается до конца оплаченного периода, а когда она заканчивается, её заменяет новая подписка более низкого уровня. В этом случае сразу создаётся только событие Access level updated, отключающее автопродление доступа. Все остальные события создаются в момент фактической замены подписки:

  • Создаётся ещё одно событие Access level updated — чтобы предоставить доступ ко второму продукту.
  • Создаётся событие Subscription expired (churned) — чтобы завершить подписку на первый продукт.
  • Создаётся событие Subscription started — чтобы начать новую подписку на новый продукт.
Delayed_Product_Change_Downgrade.webp

Отложенный сценарий смены продукта

Существует также вариант, когда пользователь меняет продукт в момент продления подписки. Этот вариант очень похож на предыдущий: сразу создаётся одно событие Access level updated, которое отключает автопродление доступа для старого продукта. Все остальные события создаются в момент, когда пользователь меняет подписку и это изменение отражается в системе:

  • Создаётся ещё одно событие Access level updated, чтобы открыть доступ для второго продукта.
  • Создаётся событие Subscription expired (churned), чтобы завершить подписку на первый продукт.
  • Создаётся событие Subscription started, чтобы начать новую подписку на новый продукт.
Product_Change_on_Renewal_Flow.webp

Процесс обработки проблем с оплатой

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

При наличии льготного периода: если оплата проходит успешно, триал конвертируется или подписка продлевается. Если нет — стор продолжает попытки списать средства, и если они все равно не увенчались успехом, стор завершает триал или подписку самостоятельно.

Таким образом, в момент возникновения проблемы с оплатой в 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_Issue_Outcome_Flow_with_Grace_Period.webp

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

  • Событие Trial expired или Subscription expired (churned) с cancellation_reason равным billing_error

  • Access level updated — уровень доступа пользователя отзывается

Billing_Issue_Outcome_Flow_without_Grace_Period.webp

Потоки совместного использования покупок между аккаунтами пользователей

Когда Customer User ID пытается восстановить или продлить подписку, уже привязанную к другому Customer User ID , настройка Sharing paid access between user accounts в Adapty определяет, как управляется доступ. Порядок действий будет зависеть от выбранного варианта.

Для транзакций Apple Family Sharing (in_app_ownership_type=FAMILY_SHARED) срабатывает только событие Access level updated — перечисленные ниже события подписки для конкретных продуктов не отправляются. Полная матрица событий — в разделе Apple Family Sharing.

Перенос уровня доступа на нового пользователя

Рекомендуемый вариант — перенести уровень доступа на нового пользователя. Это сохраняет историю транзакций исходного пользователя и обеспечивает корректную аналитику. Будет создано только 2 события Access level updated:

  1. для отзыва уровня доступа у первого пользователя
  2. для предоставления уровня доступа второму пользователю
Transfer_Access_to_New_User_Flow.webp

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

  • Пользователь A: уровень доступа обновлён (отправляется, когда пользователь 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: Уровень доступа обновлён (отправляется при переустановке приложения и входе 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
  }
  • Пользователь B: уровень доступа обновлён (отправляется, когда пользователь 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. Это удобно, когда пользователь переустанавливает приложение и входит с другим email — он по-прежнему сохранит доступ к предыдущей покупке. При этом несколько идентифицированных пользователей могут разделять один уровень доступа. Пока уровень доступа общий, все транзакции записываются под оригинальным Customer User ID , чтобы сохранить полную историю транзакций и аналитику. Таким образом, будет создано только 1 событие: Access level updated — для предоставления доступа второму пользователю.

Share_Access_Between_Users_Flow.webp

Ниже описаны поля, связанные с назначением и передачей уровня доступа в событиях, генерируемых в этом сценарии:

Пользователь B: Access level updated (отправляется при входе пользователя 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 .

Share_Access_Between_Users_Disabled_Flow.webp