定期購入のライフサイクル

定期購入はそのライフサイクルを通じてさまざまなステータスに遷移します。これは自動更新、支払いの不承認、デベロッパー管理アクションなど、さまざまな要因によります。

自動更新による定期購入のライフサイクルを処理する

ユーザーの定期購入のステータスが変化すると、バックエンド サーバーは SubscriptionNotification メッセージを受信します。

図 1. 自動更新による定期購入のライフサイクルのステータスと遷移イベント

バックエンドのステータスを更新するには、通知に含まれている購入トークンを使用して purchases.subscriptionsv2.get API を呼び出します。このエンドポイントによって、購入トークンに基づく最新の定期購入のステータスを取得できます。これは定期購入の管理における信頼できる情報源と見なされます。

購入トークンは定期購入の登録後から有効期限の 60 日後まで有効です。この期間を経過すると、購入トークンは無効となり、それを使用して Google Play Developer API を呼び出すことはできなくなります。

新規の自動更新による定期購入

ユーザーが定期購入に登録すると、タイプ SUBSCRIPTION_PURCHASEDSubscriptionNotification メッセージが RTDN クライアントに送信されます。この通知を受け取った場合、PurchasesUpdatedListener からアプリ内で新規購入を登録した場合、アプリの onResume() メソッドで購入を手動でフェッチした場合、いずれの場合も安全なバックエンドで新規購入を処理する必要があります。手順は次のとおりです。

  1. purchases.subscriptionsv2.get エンドポイントをクエリして、最新の定期購入のステータスを含む定期購入リソースを取得します。
  2. subscriptionState フィールドの値が SUBSCRIPTION_STATE_ACTIVE であることを確認します。
  3. 購入を確認します
  4. ユーザーにコンテンツへのアクセスを許可します。購入時に setObfuscatedAccountIdsetObfuscatedProfileId を使用して識別子が設定されている場合、購入に関連付けられたユーザー アカウントは定期購入リソースの ExternalAccountIdentifiers オブジェクトで識別できます。

Play Billing Library にも、定期購入を承認するメソッド acknowledgePurchase()、承認ステータスを確認するメソッド isAcknowledged() があります。ただし、セキュリティ強化のために、購入処理はバックエンドで処理することをおすすめします。

新規に購入された定期購入リソースは、次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", // need to acknowledge new purchases
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

定期購入の更新

分割払い以外の自動更新の定期購入の場合、定期購入が更新されると SUBSCRIPTION_RENEWED 通知が送信されます。分割払いの定期購入の場合、請求日に定期購入の請求が行われるたびに SUBSCRIPTION_RENEWED 通知が送信されます。ユーザーに引き続き定期購入の利用資格があることを確認してから、Google Play Developer API から返された定期購入リソースにある新しい expiryTime を使用して、定期購入のステータスを更新する必要があります。定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ]
}

定期購入の更新は承認する必要はありません。

猶予期間

定期購入の更新でお支払いの問題がある場合、Google はユーザーに通知し、定期購入が期限切れになる前の一定期間、定期的に定期購入の更新を試みます。この復元期間は猶予期間と重複します。復元期間が終了すると、アカウントの一時停止期間に移行します。猶予期間中も、ユーザーが定期購入の利用資格に引き続きアクセスできるようにする必要があります。

queryPurchasesAsync() メソッドでは、引き続き猶予期間中の購入を返します。ユーザーに定期購入の利用資格があるかどうかをアプリが queryPurchasesAsync のみに基づいて確認している場合、このような定期購入は Play Billing Library で有効とされるため、アプリは自動的に猶予期間を処理します。

定期購入のステータスをバックエンドと同期することにより、支払いの不承認をより正確に把握でき、詳細なコンテキストに基づき、非自発的なチャーンを削減できるようになります。タイプ SUBSCRIPTION_IN_GRACE_PERIODSubscriptionNotification メッセージをリッスンして、ユーザーが猶予期間に入ったときに通知されるようにします。ユーザーが猶予期間中の場合、定期購入リソースには autoRenewEnabled = true が含まれます。Google Play は猶予期間の終了まで expiryTime 値を動的に延長します。利用資格はユーザーが解約するまで、または猶予期間の有効期限まで維持する必要があるためです。猶予期間中の subscriptionState フィールドの値は SUBSCRIPTION_STATE_IN_GRACE_PERIOD となります。定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

Google Play は猶予期間中のユーザーに対して、支払いが承認されなかったことを通知し、Google Play ストアの支払い方法の問題解決を促すメッセージを表示します。ユーザーが猶予期間に入ったときには、支払いの不承認が自発的なものでないケースがあるため、ユーザーに支払い方法の修正を促すようにしてください。In-App Messaging API を使用すれば、簡単に通知ができます。ユーザーがアプリを開いたときに、この API を呼び出すと、一時的なスナックバーに Play メッセージが表示され、支払いが承認されなかったことをユーザーに通知します。このメッセージには、ユーザーが Google Play で支払い方法を修正できるディープリンクも含まれています。

ユーザーが支払い方法を修正すると、定期購入は元の更新日に更新され、更新の説明に従って、更新を処理できるようになります。

ユーザーが猶予期間中に支払い方法を修正しなかった場合、定期購入はアカウントの一時停止ステータスとなり、利用資格が失われます。

猶予期間中のアクセスと再開

図 2 は、定期購入が猶予期間に入り、その後ユーザーが支払い方法を修正して定期購入が再開されるまでのタイムラインを示しています。猶予期間が終了すると、ユーザーは定期購入の利用資格を失い、アカウントの一時停止となります。

図 2. 定期購入が猶予期間に入り、猶予期間終了前に再開されるまでのタイムライン

次の点に留意する必要があります。

  • 猶予期間中、ユーザーは定期購入の特典に引き続きアクセスできます。
  • 猶予期間中に定期購入が再開された場合、更新日はリセットされません。
  • 猶予期間を延長すると(例: 7 日から 14 日に)、猶予期間中のユーザーは定期購入の特典により長くアクセスできるようになります。
  • 猶予期間を短くした場合、以前の猶予期間に入っており、新しい猶予期間を過ぎているユーザーは、定期購入の特典が即座に無効になります。たとえば、猶予期間を 14 日から 7 日に短縮した場合、以前は猶予期間だった 8 日目から 14 日目に入っているユーザーは、定期購入の特典が即座に無効になります。
  • 定期購入は有効な状態のままであり、サイレント猶予期間が終了するまで猶予期間の RTDN は届きません。

サイレント猶予期間

猶予期間を 0 日に設定できますが、お支払いの再試行に十分な時間を確保するために、Google Play は最低 1 日待機します。このサイレント猶予期間は、支払い処理のセーフティ ネットとなります。この 24 時間の間、定期購入は ACTIVE ステータスのままです。

定期購入のステータスの変化を常に把握するための最善の方法は、リアルタイム デベロッパー通知(RTDN)をリッスンして対応することです。定期購入のステータスをより正確に取得するには、有効期限ではなく RTDN の時刻に purchases.subscriptionsv2.get() メソッドを呼び出します。

24 時間のサイレント猶予期間後の定期購入のステータスに応じて、次のいずれかの通知が届きます。

  • SUBSCRIPTION_ON_HOLD(有効の場合)
  • SUBSCRIPTION_CANCELED(キャンセルされた場合)
  • SUBSCRIPTION_EXPIRED(期限切れの場合)
  • SUBSCRIPTION_RENEWED(正常に更新された場合)

24 時間のサイレント猶予期間の後、いつでも subscriptionV2.get() メソッドを呼び出して、定期購入の最新ステータスを取得することもできます。

アカウントの一時停止

定期購入の更新でお支払いに関する問題が発生した場合、猶予期間が終了すると、アカウントの一時停止期間が開始します。定期購入のステータスがアカウントの一時停止になった場合は、定期購入の利用資格へのアクセスをブロックする必要があります。

アカウントの一時停止中は、必要に応じて引き続き定期購入の解約、再開、再購入を処理します。定期購入が一時停止中でも、ユーザーがそのような変更を行うことは可能であるためです。

アカウントの一時停止期間に入ると、RTDN から通知が送信されるため、定期購入へのアクセスが停止された理由を速やかにユーザーに通知できます。In-App Messaging API を使用すれば、簡単に通知ができます。ユーザーがアプリを開いたときにこの API を呼び出すと、一時的なスナックバーにメッセージが表示され、支払いが承認されなかったことがユーザーに通知されます。このメッセージには、ユーザーが Google Play で支払い方法を修正できるディープリンクも含まれています。

ユーザーがアプリ外の定期購入コンテンツにアクセスできる場合は、アプリ以外からアクセスできなくなったことに気が付く可能性があります。プッシュ通知またはメールをユーザーに送信して、支払いの不承認により定期購入がアクティブでなくなったことを知らせることをおすすめします。

アカウントの一時停止中の定期購入は queryPurchasesAsync() メソッドから返されないため、アプリでこのメソッドを使用して既存の購入を表示している場合は、デフォルトでアカウントの一時停止をサポートする必要があります。

リアルタイム デベロッパー通知では、定期購入がアカウントの一時停止ステータスになると、タイプ SUBSCRIPTION_ON_HOLDSubscriptionNotification メッセージが送信されます。定期購入の最新情報を取得するには、安全なバックエンド サーバーから purchases.subscriptionsv2.get を呼び出します。アカウントの一時停止中は、定期購入リソースexpiryTime フィールドは過去のタイムスタンプに設定され、subscriptionState フィールドは SUBSCRIPTION_STATE_ON_HOLD に設定されます。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

アクセスを再開するには、ユーザーは支払い方法を修正する必要があります。Google Play はアカウントの一時停止中のユーザーに、支払いが不承認になったことを通知します。同時に、支払い方法の修正をユーザーに促すようにしてください。

ユーザーが支払い方法を修正して定期購入がアクティブな状態に戻った場合、定期購入されたコンテンツへのアクセスを復元する必要があります。この場合の購入トークンはアカウントの一時停止前と同じものです。同じ購入が再開され、タイプ SUBSCRIPTION_RECOVERED の RTDN を受け取ります。

分割払いの定期購入の場合、個々のお支払い試行で支払いの不承認や回収が発生することがあります。

再開後、Play Billing Library は queryPurchasesAsync() メソッドから定期購入を再度返します。このメソッドを使用してユーザーに定期購入の利用資格があるかどうかを判断している場合、アプリはアカウントの一時停止から再開する定期購入を自動的に処理します。

タイプ SUBSCRIPTION_RECOVEREDSubscriptionNotification メッセージをリッスンし、定期購入が再開されたときに通知されるようにする必要があります。これにより、ユーザーはアクセス権を再取得できます。この通知を受け取った後に定期購入を照会すると、expiryTime フィールドは将来のタイムスタンプに設定され、subscriptionState フィールドは再度 SUBSCRIPTION_STATE_ACTIVE に設定されています。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      ...
    }
  ],
}

アカウントの一時停止期間が終了する前にユーザーが支払い方法を修正しなかった場合は、代わりにタイプ SUBSCRIPTION_CANCELED の RTDN が送信されます。解約の処理手順については、解約をご覧ください。このようにして解約された定期購入を照会した場合、返される expiryTime フィールドは過去のタイムスタンプに設定されています。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

アカウントの一時停止中に解約が通知された直後に、タイプ SUBSCRIPTION_EXPIRED の RTDN も送信されます。これはユーザーが有料の利用資格を失い、解約により定期購入が終了したためです。この終了の処理は通常どおりに行います。

ユーザーは同じ定期購入プラン、または元の購入のアカウントの一時停止期間中にアプリからおすすめした他のプランを再購入して、再度アクセス権を取得できます。その場合、新しい購入トークンが発行され、新しい値がこの新規のインスタンスを表す SUBSCRIPTION_PURCHASED イベントの一部として返されます。

アカウントの一時停止中のアクセスと再開

図 3 は、定期購入がアカウントの一時停止ステータスとなり、ユーザーが支払い方法を修正して定期購入が再開されるまでのタイムラインを示しています。

図 3. 定期購入がアカウントの一時停止ステータスに入り、一時停止期間終了前に再開されるまでのタイムライン

前の例と同様に図 4 では、定期購入がまず猶予期間に入り、その後アカウントの一時停止ステータスになり、一時停止中に再開されるまでのタイムラインを示しています。

図 4. 定期購入が猶予期間に入り、その後アカウントの一時停止ステータスになり、アカウントの一時停止期間が終了する前に最終的に再開されるまでのタイムライン

次の点に留意する必要があります。

  • 定期購入がアカウントの一時停止ステータスになる前に、Google Play は支払い方法に対する請求を追加で最大 48 時間再試行します。この期間中、ユーザーは定期購入の特典を引き続き利用できます。この再試行期間が終了すると、定期購入はアカウントの一時停止ステータスになり、ユーザーは定期購入の特典にアクセスできなくなります。
  • 支払い方法のエラーが発生している状態で定期購入が一時停止ステータスから再開すると、定期購入はそのままアカウントの一時停止ステータスに入ります。
  • 定期購入がアカウントの一時停止から再開されると、更新日はリセットされます。

有効期限切れ

定期購入の有効期限が切れると、ユーザーは定期購入にアクセスできなくなります。この場合、タイプ SUBSCRIPTION_EXPIREDSubscriptionNotification メッセージが送信されます。この通知を受け取った場合は、Google Play Developer API をクエリして、最新の定期購入リソースを取得してください。subscriptionStateSUBSCRIPTION_STATE_EXPIRED であることを確認後、利用資格を削除し、バックエンドで購入ステータスを無効にします。定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time_in_past,
      ...
    }
  ],
}

解約

ユーザーは自主的に Play の定期購入センターから定期購入を解約できます。またはアカウントの一時停止になった後で再開をしなかった場合、定期購入は自動的に解約されます。また、デベロッパーが purchases.subscriptions.cancel で解約をトリガーすることもできます。定期購入が解約された場合、ユーザーは現在の請求期間が終了するまではコンテンツにアクセスできます。請求期間が終了すると、アクセスできなくなります。

分割払い以外の自動更新の定期購入を解約すると、SUBSCRIPTION_CANCELED 通知がトリガーされます。この通知を受け取ると、Google Play Developer API から返された定期購入リソースsubscriptionState フィールドは SUBSCRIPTION_STATE_CANCELED と設定され、expiryTime フィールドにはユーザーが定期購入にアクセスできなくなる日付が入ります。この日付が過去の日付である場合、ユーザーは直ちに利用資格を失います。たとえば、支払いの不承認によるアカウントの一時停止中に、ユーザーが定期購入を解約した場合が該当します。

解約された定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

分割払いの定期購入の場合、ユーザーが解約を開始したときに、コミットメント期間の支払いが残っている場合は SUBSCRIPTION_CANCELLATION_SCHEDULED 通知が送信されます。解約は保留中であり、現在の契約期間の終了時に有効になります。この通知を受け取ると、Google Play Developer API から返された定期購入リソースの subscriptionState フィールドは SUBSCRIPTION_STATE_ACTIVE に設定されます。これは、分割払いの定期購入がコミットメント期間の終了まで有効であるためです。ただし、空の pendingCancellation オブジェクトが存在します。コミットメント期間の終了時に、SUBSCRIPTION_CANCELED 通知が送信され、その後 SUBSCRIPTION_EXPIRED が送信されます。

解約待ちの分割払いの定期購入の定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_plan01",
      "expiryTime": expiration_time,
      "autoRenewingPlan": {
        "autoRenewEnabled": true,
        "recurringPrice": {
          "currencyCode": "USD",
          "units": "1",
          "nanos": 990000000
        },
        "installmentDetails": {
          "initialCommittedPaymentsCount": 6,
          "remainingCommittedPaymentsCount": 5,
          "pendingCancellation": {}
      ...
        }
      }
    }
  ],
}

定期購入リソースの canceledStateContext フィールドで、定期購入が解約された理由(ユーザーによる解約、システムによる解約、自身による解約など)を確認できます。ユーザーが定期購入を解約した場合は、userInitiatedCancellation フィールドで、定期購入が解約された理由を確認できます。この情報はコミュニケーション戦略において役に立ちます。

定期購入が解約されていても期限切れでない場合は、引き続き queryPurchasesAsync() から返されます。定期購入が解約されたことをユーザーに知らせ、有効期限を示すメッセージをアプリに表示できます。

取り消し

定期購入は、purchases.subscriptionsv2.revoke を使用したバックエンドによる定期購入の取り消しやチャージバックなど、さまざまな理由で取り消される場合があります。このような場合は、ユーザーの利用資格を直ちに取り消します。取り消すと、タイプ SUBSCRIPTION_REVOKEDSubscriptionNotification メッセージが送信されます。この通知を受け取ると、Google Play Developer API から返された定期購入リソースsubscriptionState フィールドは SUBSCRIPTION_STATE_EXPIRED に設定されます。

取り消された購入の定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ]
}

定期購入の延長

さまざまな理由で、ユーザーの利用資格を延長する場合があります。たとえば、特別なプロモーションとしてユーザーに無料アクセスを提供する場合があります。1 週間映画の購入を無料にしたり、感謝のしるしとしてユーザーが無料でアクセスできるようにしたりするケースが該当します。Play Developer API の purchases.subscriptions.defer メソッドを使用すると、自動更新による定期購入の次回の更新日を延長できます。この操作を行うと、タイプ SUBSCRIPTION_DEFERREDSubscriptionNotification メッセージが送信されます。延期期間中、ユーザーは完全なアクセス権で定期購入コンテンツを利用できますが、課金はされません。定期購入の更新日は、新しい日付で更新されます。

プリペイド プランでは、Defer Billing API を使用して有効期限を延長できます。

延長された定期購入の定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      ...
    }
  ],
}

定期購入の一時停止

ユーザーが定期購入を一時停止できるようにすることで、自主的な解約を削減できます。一時停止機能を有効にすると、契約期間の間隔に応じて、ユーザーは 1 週間から 3 か月の間、定期購入を一時停止できます。

定期購入の自動更新 毎週 毎月 3 か月 6 か月 年単位
利用可能な一時停止時間* 1 週間
2 週間
3 週間
4 週間
1 か月
2 か月
3 か月
1 か月
2 か月
3 か月
1 か月
2 か月
3 か月
なし
*随時変更される可能性があります。

定期購入の一時停止が有効になるのは、現在の請求対象期間が終了した後に限られます。定期購入の一時停止期間中、ユーザーは定期購入にアクセスできず、更新に伴う料金は発生しません。一時停止期間が終了すると、定期購入が再開され、Google は定期購入の更新を試みます。正常に再開できれば、定期購入が再びアクティブになります。支払いに関する問題で再開できなかった場合、図 5 と 6 に示すように、ユーザーはアカウントの一時停止ステータスになります。

図 5. ユーザーが定期購入を一時停止した後で再開した場合
図 6. ユーザーが定期購入を一時停止した後でアカウントの一時停止ステータスになった場合

図 6 に示すように、ユーザーは一時停止期間中、いつでも手動で定期購入を再開できます。ユーザーが手動で再開した場合、請求日は手動で再開した日付に変更されます。

ユーザーの定期購入が一時停止されている場合、Play Billing Library は queryPurchasesAsync() メソッドからその定期購入を返しません。定期購入が再開されると、queryPurchasesAsync() メソッドは再びその定期購入を返すようになります。

RTDN をリッスンし、ユーザーが定期購を一時停止したときに把握できるようにします。また、この通知により、定期購入が一時停止になっておりアクセスできないことを、アプリでユーザーに通知できるようになります。さらに、Google Play へのディープリンクを使用して、ユーザーがいつでも手動で定期購入を再開できるようにしてください。

タイプ SUBSCRIPTION_PAUSE_SCHEDULE_CHANGEDSubscriptionNotification メッセージは、ユーザーが定期購入の一時停止を開始したときに送信されます。この時点では、ユーザーは次回の更新日まで定期購入にアクセスでき、定期購入リソースには autoRenewEnabled = true が含まれています。この時点での subscriptionState フィールドの値は SUBSCRIPTION_STATE_ACTIVE です。

一時停止が有効になると、タイプ SUBSCRIPTION_PAUSEDSubscriptionNotification メッセージが送信されます。メッセージが送信されると、ユーザーは定期購入にアクセスできなくなり、定期購入リソースには autoRenewEnabled = true が含まれ、subscriptionState フィールドは SUBSCRIPTION_STATE_PAUSED に設定されます。定期購入が再び更新される予定日を確認するには、PausedStateContext オブジェクトを確認します。

タイプ SUBSCRIPTION_RENEWEDSubscriptionNotification メッセージは、一時停止期間の終了時に定期購入が自動的に再開された場合、またはユーザーが手動で定期購入を再開した場合に送信されます。これは更新の記載に従って処理します。

一時停止後に定期購入を再開しようとしたときに支払いでエラーが発生すると、タイプ SUBSCRIPTION_ON_HOLDSubscriptionNotification メッセージが送信されます。これはアカウントの一時停止に記載されているとおりに処理する必要があります。

再度定期購入

自動更新による定期購入の基本プランの場合、Google Play ストアに [再度定期購入] ボタンが表示されることがあります。このボタンにより、ユーザーは定期購入に再びアクセスできるようになります。なお、定期購入がかなり前に期限切れになっている場合など、さまざまな理由でこのボタンが表示されないことがあります。

図 7. Google Play ストア アプリの [アカウント] > [定期購入] セクションで、解約済みの定期購入とともに表示されている [再度定期購入] ボタン

ボタンには常に [再度定期購入] というラベルが付けられていますが、その機能は定期購入のステータスによって異なります。

定期購入が解約されてまだ期限切れになっていない間は、ユーザーは定期購入を継続し、定期購入の特典を受けています。ユーザーが [再度定期購入] をタップすると、解約は取り消され、定期購入は引き続き更新されます。この操作は、Play のデベロッパー向けドキュメントと API では「再開」と呼ばれています。

自動更新による定期購入の有効期限が切れた後、ユーザーが同じ定期購入の基本プランを購入できるようにすることが可能です。この操作は、Play のデベロッパー向けドキュメントと API では「再度定期購入」と呼ばれています。このオプションは、Google Play Console で、または API を使用して基本プランごとに設定できます。

有効期限切れ前の再開

ユーザーに定期購入の利用資格があるかどうかをアプリが queryPurchasesAsync() メソッドのみに基づいて判断している場合、解約された購入を queryPurchasesAsync() メソッドが引き続き有効期限までは返すため、アプリは再開を自動的に処理します。再開された定期購入は、解約されなかった場合と同じように引き続き更新されます。

アプリが定期購入のステータスをバックエンドと同期している場合は、タイプ SUBSCRIPTION_RESTARTEDSubscriptionNotification メッセージをリッスンする必要があります。この RTDN を受信後、アプリは通知に応答して、定期購入が更新に設定されたことを記録し、再開に関するメッセージがアプリに表示されないようにします。定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date
      ...
    }
  ],
}

有効期限切れ後の再度定期購入

自動更新による基本プランが Google Play Console または API を使用して再度定期購入できるように設定されている場合、ユーザーは期限切れの定期購入を Google Play ストアで再購入できます。

この場合は新規購入となるため、Google Play は新しい購入トークンを発行し、バックエンドはタイプ SUBSCRIPTION_PURCHASED の RTDN を受け取ります。このタイプのアプリ外で行われた購入のステータスには、元の購入に関連付けられている linkedPurchaseToken は含まれません。これは元の定期購入が完全に期限切れになっているためです。このような新規購入は他の購入と同様に、バックエンドが処理して承認する必要があります。

アップグレード、ダウングレード、再度定期購入

ユーザーが定期購入の有効期限切れ前にアプリから解約をし、その後登録、アップグレード、ダウングレードをした場合、以前の定期購入は無効になり、新しい購入トークンで新規の定期購入が作成されます。

さらに、Google Play Developer API から返される定期購入リソースには、ユーザーがアップグレード、ダウングレード、再度定期購入をした元の購入を示す linkedPurchaseToken フィールドが含まれます。このフィールドの購入トークンを使用して以前の定期購入を検索し、既存のユーザー アカウントを特定することで、新しい購入を同じアカウントに関連付けることができます。

アップグレード、ダウングレード、再度定期購入のオプションをアプリでユーザーに提示する前に、既存の定期購入を承認する必要があります。既存の定期購入が承認待ちである場合、プランの変更や再度定期購入はブロックされます。

ユーザーがアップグレード、ダウングレード、再度定期購入を正常に購入した場合、これは新規購入になるため、承認する必要があります。購入の承認には Google Play Developer API を使用することをおすすめします。定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "linkedPurchaseToken": old_purchase_token,
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

価格の変更

自動更新による定期購入の価格を変更する方法と、必要に応じてユーザーに通知する方法については、価格変更に関するベスト プラクティスをご確認ください。

既存の定期購入者に価格変更をオプトインとして適用した場合、ユーザーが新しい価格に対する同意または拒否の操作を行うと、RTDN が送信されます。

オプトインによる価格変更に対するユーザーの同意を処理する

ユーザーが定期購入の値上げに同意すると、タイプ SUBSCRIPTION_PRICE_CHANGED_CONFIRMEDSubscriptionNotification メッセージが送信されます。オプトアウトによる値下げの場合、または定期購入の値上げが更新された場合、タイプの SUBSCRIPTION_RENEWEDSubscriptionNotification メッセージが届きます。この通知は他の更新と同様に処理してください。

オプトインによる値上げが同意されなかったケースを処理する

ユーザーが値上げ価格での更新期日までに、オプトインによる値上げに同意しなかった場合、定期購入が自動的に解約され、デベロッパーはタイプ SUBSCRIPTION_CANCELEDSubscriptionNotification メッセージを受け取ります。このイベントは解約の説明に沿って処理します。

また、ユーザーは同じ仕組みで、オプトアプトによる値上げに対して、定期購入を解約できます。

プリペイド プランのライフサイクルを処理する

自動更新による定期購入と同様に、新規購入のたびにプリペイド プランを承認する必要があります。プリペイド プランの場合、ユーザーは毎回購入フローを進む必要があるため、初回の購入とチャージの両方をすべて処理する必要があります。

プリペイド プランの期間は短い場合があるため、できる限り早く購入を承認することが重要です。期間が 1 週間以上のプリペイド プランは、3 日以内に承認する必要があります。期間が 1 週間未満のプリペイド プランは、プラン期間の半分が経過する前に承認する必要があります。たとえば、3 日間のプリペイド プランの購入の承認期限は 1.5 日間です。

図 8. 定期購入のライフサイクルのステータスと遷移イベント

チャージを含め、プリペイド プランの定期購入が購入されるたびに、タイプ SUBSCRIPTION_PURCHASEDSubscriptionNotification メッセージが RTDN クライアントに送信されます。purchases.subscriptionsv2.get メソッドを呼び出して、最新のプリペイド プランの定期購入のステータスを確認します。

チャージ購入に対して新しい購入トークンが発行され、新しい定期購入の購入ステータスの一部として、linkedPurchaseToken フィールドに以前の購入トークンを受け取ります。購入トークンは定期購入の登録後から有効期限の 60 日後まで有効です。この期間を経過すると、購入トークンは無効となり、それを使用して Google Play Developer API を呼び出すことはできなくなります。

プリペイド プラン購入の定期購入リソースは次の例のようになります。

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "prepaid_plan01",
      "expiryTime": expiry_date,
      "prepaidPlan": {
        "allowExtendAfterTime": timestamp_after_which_topups_are_allowed
      }
    }
  ]
}

expiryTime フィールドで利用資格の終了日を確認できます。チャージの購入によって、利用資格期間が追加され延長されます。つまり、ユーザーが元の利用資格の終了前にチャージをした場合、元の有効期限に新しい期間が追加されます。

プリペイド プランの定期購入期間がチャージによって延長されることをユーザーに通知するメッセージをアプリに表示できます。ユーザーがチャージできるタイミングを把握するには、定期購入リソースの allowExtendAfterTime フィールドを確認します。

プリペイド プランは自動更新されないため、解約はできません。ユーザーがプリペイド プランを解約したい場合には、有効期限が切れるまで待ちます。