イベントフロー
1つのアクションから複数のイベントが発生することがよくあります。例えば、初回購入では Subscription started と Access level updated の両方が送信されます。以下の図は、ユーザーがサブスクリプションを開始・キャンセル・再開した際に Adapty が送信するイベントとその順序を示しています。
ダイアグラムの読み方
- タイミング。 Appleはサブスクリプションの開始または更新の数時間前に課金します。このギャップを表示すると、受け取るイベントは変わらないにもかかわらず、すべての図に1ステップが追加されるため、図では課金と開始をまとめて表示しています。
- 順序。 1つのアクションからのイベントは同時に届きます。図ではある順序で描く必要がありますが、イベントフィードでは異なる順序で表示される場合があり、どちらが正しいというわけではありません。
- 対象範囲。 ストア通知によってすべてのイベントがトリガーされます。合成イベントは表示されません。Adaptyはタイマーで送信し、インテグレーションごとに遅延が異なるため、シーケンス内に固定の位置がありません。
サブスクリプションのライフサイクル
初回購入フロー
このフローは、顧客がトライアルなしで初めてサブスクリプションを購入したときに発生します。この場合、以下のイベントが生成されます:
- Subscription started
- Access level updated:ユーザーへのアクセス付与
サブスクリプションの更新日が来ると、サブスクリプションが更新されます。この場合、以下のイベントが生成されます:
- Subscription renewal:サブスクリプションの新しい期間の開始
- Access level updated:サブスクリプションの有効期限を更新し、さらに1期間のアクセスを延長
支払いが成功しなかった場合やユーザーが更新をキャンセルした場合については、それぞれ請求問題アウトカムフローとサブスクリプションキャンセルフローを参照してください。
サブスクリプションキャンセルフロー
ユーザーがサブスクリプションをキャンセルすると、以下のイベントが作成されます。
- 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 イベントは2回生成されます:
- サブスクリプション終了時にユーザーのアクセスを取り消すとき
- サブスクリプション再購入時にアクセスを付与するとき
サブスクリプション一時停止フロー(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 を使って両者をリンクします。この変換は、ゼロ価格のトライアルから始まる継続的なトランザクションチェーンの一部として扱われます。そのため、Subscription started ではなく Trial converted イベントが生成されます。
プロダクトの変更
このセクションでは、アップグレード、ダウングレード、別グループのプロダクトの購入など、アクティブなサブスクリプションに加えられた変更について説明します。
即時プロダクト変更フロー
ユーザーがプロダクトを変更した後、サブスクリプション終了前にシステムで即時変更が適用される場合があります(主にアップグレードまたはプロダクトの置き換えの場合)。この場合、プロダクト変更時に以下のイベントが生成されます:
- アクセスレベルが変更され、2つの Access level updated イベントが生成されます:
- 最初のプロダクトへのアクセスを削除
- 2番目のプロダクトへのアクセスを付与
- 古いサブスクリプションが終了し、返金が行われます(Subscription refunded イベントが
cancellation_reason=upgradedで生成されます)。Subscription expired (churned) イベントは生成されず、Subscription refunded イベントに置き換えられます。 - 新しいサブスクリプションが開始されます(新しいプロダクトの Subscription started イベントが生成されます)。
ユーザーがサブスクリプションをダウングレードした場合、最初のサブスクリプションは有料期間の終了まで継続し、終了後に新しい低ランクのサブスクリプションに切り替わります。このケースでは、自動更新の無効化を示す Access level updated イベントのみが即座に作成されます。その他のイベントはすべて、サブスクリプションが実際に切り替わるタイミングで作成されます。
- 2番目のプロダクトへのアクセスを付与するため、別のAccess level updatedイベントが作成されます。
- 最初のプロダクトのサブスクリプションを終了するため、**Subscription expired (churned)**イベントが作成されます。
- 新しいプロダクトの新規サブスクリプションを開始するため、Subscription startedイベントが作成されます。
遅延プロダクト変更フロー
サブスクリプション更新時にプロダクトを変更するバリアントもあります。このバリアントは前のケースと非常に似ており、古いプロダクトのアクセス自動更新を無効化する Access level updated イベントが1つ即時に生成されます。その他のイベントはユーザーがサブスクリプションを変更してシステムで反映される時点で生成されます:
- 2つ目のプロダクトへのアクセスを付与するため、別の Access level updated イベントが作成されます。
- 1つ目のプロダクトのサブスクリプションを終了するため、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:ユーザーのアクセスを取り消す
グレース期間がない場合、請求リトライ期間(アプリストアがユーザーへの請求を繰り返し試みる期間)は即座に開始されます。
グレース期間終了までに支払いが成功しなかった場合のフローは同じです。アプリストアが自動的にサブスクリプションを終了する際に、同じイベントが生成されます:
-
Trial expired または Subscription expired (churned) イベント(
cancellation_reasonはbilling_error) -
Access level updated(アクセスレベルを失効)
ユーザーアカウント間での購入共有フロー
カスタマーユーザーID iOS、Android、React Native、Flutter、Unity が、別の カスタマーユーザーID iOS、Android、React Native、Flutter、Unity にすでに紐付いているサブスクリプションを復元または延長しようとした場合、Adaptyの Sharing paid access between user accounts 設定でアクセス管理方法が制御されます。選択したオプションによってフローが異なります。
Apple Family Sharingのトランザクション(in_app_ownership_type=FAMILY_SHARED)の場合、Access level updated イベントのみが発火し、以下のプロダクト別サブスクリプションイベントは発生しません。完全なイベントマトリクスについては Apple Family Sharing をご参照ください。
ユーザーが Restore Purchases をタップしても、同じプロファイルですでにアクセスがある場合、リストアは何も行わず、Webhookイベントは発生しません。このセクションのイベントは、プロファイル間でアクセスが実際に移行する場合にのみ発生します。
2番目のプロファイルが既存のサブスクリプションを要求したときにどのイベントが発生するかを一目で確認するには、以下のマトリクスを参照してください。その後のセクションでは、各フローの完全なJSONペイロードを示します。
| イベント | 有効(デフォルト) | 新しいユーザーにアクセスを移行 | 無効 |
|---|---|---|---|
新しいプロファイル:Access level updated(is_active=true) | 発生する | 発生する | 発生しない |
古いプロファイル:Access level updated(is_active=false) | 発生しない — 両方のプロファイルがアクセスを保持 | 新しい識別済みデバイスがトランザクションを伝播したときに発生 | 発生しない — 元のプロファイルがアクセスを保持 |
新しいイベントの profiles_sharing_access_level フィールド | アクセスレベルを共有している他のプロファイルを一覧表示 | null | 該当なし — イベントは発生しない |
移行されたサブスクリプションの更新、返金、期限切れは、現在アクセスレベルを保持しているプロファイルで subscription_renewed、subscription_refunded、subscription_expired イベントを引き続き発生させます。移行イベント自体は subscription_started イベントを発生させません。新しいトランザクションは記録されず、アトリビューションのみが変更されるためです。
モード別の詳細については、実用的なリファレンスをご参照ください。
新しいユーザーへのアクセス移行フロー
推奨オプションは、アクセスレベルを新しいユーザーに移行することです。これにより、元のユーザーのトランザクション履歴が保持され、一貫したアナリティクスが実現します。作成される Access level updated イベントは2つだけです:
- 最初のユーザーのアクセスを削除する
- 2番目のユーザーにアクセスを付与する
このシナリオで生成されるイベントにおける、アクセスレベルの割り当てと移行に関連するフィールドの詳細を以下に示します:
-
ユーザー 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 } -
ユーザー A: アクセスレベル更新(アプリを再インストールしてユーザー B がログインし、ユーザー 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:Access level updated(ユーザー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でサインインしている場合、複数のユーザーが同じアクセスレベルを共有できます。これは、ユーザーがアプリを再インストールして別のメールアドレスでログインした場合でも、以前の購入へのアクセスを維持できるため便利です。このオプションでは、複数の識別済みユーザーが同じアクセスレベルを共有できます。アクセスレベルを共有している間、すべてのトランザクションは完全なトランザクション履歴とアナリティクスを維持するために、元の カスタマーユーザーID iOS、Android、React Native、Flutter、Unity の下に記録されます。
したがって、作成されるイベントは1つのみです:2番目のユーザーにアクセスを付与するための Access level updated です。
このシナリオで生成されるイベントのうち、アクセスレベルの割り当てと共有に関連するフィールドの詳細を以下に示します:
ユーザー 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
}
]
}
ユーザー間でアクセスを共有しないフロー
このオプションでは、最初にアクセスレベルを取得したユーザープロファイルのみが永続的にそれを保持します。購入を単一の カスタマーユーザーID iOS、Android、React Native、Flutter、Unity に紐付ける必要がある場合に最適です。