6 月 3 日の「#Android11: The Beta Launch Show」にぜひご参加ください。

定期購入固有の機能の追加

定期購入を設定するには、Android Play Console を使用します。定期購入を設定したら、定期購入の購入フローを有効にするために Google Play 請求サービスをアプリに追加できます。定期購入には、請求対象期間、猶予期間、無料試用期間など、Google Play 請求サービスの概要に記載されている多くの特性があります。読み進める前に、これらの概要を理解しておいてください。

詳細については、定期購入に関する動画(最新版)をご覧ください。

また、このページの残りの部分を読む前に、リアルタイム デベロッパー通知を有効にすることをおすすめします。リアルタイム デベロッパー通知を活用することで、ステータスの変更に積極的に対応し、ユーザーを増やし、ユーザー離れを軽減することができます。通知を有効にするには、リアルタイム デベロッパー通知についてのページをご覧ください。

Google Play 請求サービス全般に該当する定期購入のユースケースには次のようなものがあります。

このようなユースケースに対処するには、Google Play Billing Library、Google Play Developer API、リアルタイム デベロッパー通知を組み合わせて使用します。

リアルタイム デベロッパー通知を使用して定期購入関連のステータスを処理する

リアルタイム デベロッパー通知はサーバー プッシュ通知であり、この通知を介して SUBSCRIPTION_PURCHASEDSUBSCRIPTION_RECOVERED といった定期購入のステータス変更をモニタリングできます。リアルタイム デベロッパー通知を活用することで、ステータスの変更に積極的に対応し、ユーザーを増やし、ユーザー離れを軽減することができます。通知を有効にするには、リアルタイム デベロッパー通知についてのページをご覧ください。

リアルタイム デベロッパー通知を有効にすると、定期購入のステータス変更のみをアラートする通知を安全なバックエンド サーバーで受け取れます。リアルタイム デベロッパー通知の受信後は、Developer API を呼び出して完全なステータスを取得し、バックエンド ステータスを更新する必要があります。これらの通知は、定期購入のステータスが変更されたことのみを通知するもので、定期購入のステータスの詳細は通知されません。

Developer API をチェックする際は、必ず次の処理を行います。

  • expiryTimeMillis が将来の日付の場合は、常に利用権を付与します。
  • autoRenewing = false の場合は、有効期限に達すると定期購入が終了するため、ユーザーに再登録を依頼します。
  • paymentState = 0 の場合は、支払いに関する問題を解決するため、定期購入センターのディープリンクを使用して、ユーザーを定期購入センターに誘導します。

将来的には、期限切れ後の定期購入の再開など、ユーザーの利用権に影響するステータス変更が追加される可能性があります。このような機能を統合できるようにするには、Developer API を呼び出して上記の処理を行い、不明確な通知に対処してください。

猶予期間中のユーザー - SUBSCRIPTION_IN_GRACE_PERIOD

猶予期間は、Google Play Console のアプリ内アイテムの設定に基づいて一定期間続きます。この猶予期間中に、Google Play によって定期購入の更新が試みられます。 支払いに関する問題についてユーザーに通知するには、支払い方法の修正方法をユーザーに知らせるメッセージをアプリ内に表示します。支払い方法を修正しないと、ユーザーは定期購入にアクセスできなくなります。たとえば、「アカウントの停止を防ぐため、Google Play の定期購入の設定に移動して Google Play のお支払い方法を修正してください」といったメッセージを表示します。このメッセージに Google Play の定期購入の設定へのリンクを記載して、ユーザーが支払い方法を修正できるようにします。

ユーザーの猶予期間を調べるには、Google Play Developer API を呼び出します。Google Play により、猶予期間が終了するまで expiryTimeMillis 値が動的に延長されます。この期間中に、ユーザーが定期購入の解約、更新、一時停止を行ったかチェックする必要があります。expiryTimeMillis が経過した後に、ユーザーの現在の定期購入のステータスをチェックして、定期購入の最新のステータスを取得する必要があります。

下記のスニペットに示すように、JSON レスポンスの内容は定期購入のステータスによって異なります。たとえば、猶予期間中(支払い方法に問題がある場合)に定期購入を照会すると、expiryTimeMillis は将来のタイムスタンプに動的に更新され、paymentState は 0 に設定されます。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": timestamp_in_future,
      "autoRenewing": true,
      ...
      "paymentState": 0  # Payment pending
    }
    

定期購入が正常に更新された後(支払い方法が更新された後)に定期購入を照会すると、expiryTimeMillis は将来のタイムスタンプに設定され、paymentState は 1 に設定されます。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": timestamp_in_future,
      "autoRenewing": true,
      ...
      "paymentState": 1  # Payment received
    }
    

猶予期間が経過した後に定期購入を照会すると、定期購入は一時停止(Google Play Console 内でアカウントの一時停止を有効にしている場合)または解約(Google Play Console 内でアカウントの一時停止を有効にしていない場合)の状態になります。SUBSCRIPTION_ON_HOLDSUBSCRIPTION_CANCELLED のサンプル JSON レスポンスについては、アカウントの一時停止 - SUBSCRIPTION_ON_HOLD をご覧ください。

アカウントの一時停止 - SUBSCRIPTION_ON_HOLD

アカウントの一時停止期間は 30 日間です。アカウントの一時停止期間中に、ユーザーが定期購入の解約、再開、再購入を行ったかチェックする必要があります。 アカウントの一時停止中に、定期購入へのアクセスが停止された理由をユーザーに通知します。ユーザーに通知するには、支払い方法を修正して定期購入に再びアクセスするための方法を記載したメッセージをアプリ内に表示します。たとえば、「定期購入に問題があります。Google Play の定期購入の設定に移動して、Google Play のお支払い方法を修正してください」といったメッセージを表示します。このメッセージに Google Play の定期購入の設定へのリンクを記載して、ユーザーが支払い方法を修正できるようにします。また、必要に応じて以下のような追加処理を行います。

  • ユーザーが支払い方法を更新して定期購入が再開された場合、定期購入されたコンテンツへのアクセスをアプリ内で復元する必要があります。詳細については、定期購入の再開 - SUBSCRIPTION_RECOVERED をご覧ください。ただし、一時停止期間中に定期購入が再開されなかった場合、定期購入は解約され、ユーザーは新しい定期購入を購入する必要があります。
  • アプリ外の定期購入にアクセスすることを想定したアプリの場合は、定期購入がアクティブでなくなったことを知らせるためにプッシュ通知またはメールをユーザーに送信することをおすすめします。ユーザーがアプリを開いたときにのみ定期購入にアクセスできる場合は、次回ユーザーがアプリを開いたときにのみ定期購入の中断について通知する必要があります。

アカウントが一時停止中であることを検証するため、ユーザーがアプリで定期購入しているコンテンツにアクセスを試みるたびに、ユーザーの現在の定期購入のステータスを確認する必要があります。

下記のスニペットに示すように、JSON レスポンスの内容は定期購入のステータスによって異なります。たとえば、アカウントの一時停止中(支払い方法に問題がある場合)に定期購入を照会すると、expiryTimeMillis は過去のタイムスタンプに設定され、paymentState は 0 に設定されます。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": timestamp_in_past,
      "autoRenewing": true,
      ...
      "paymentState": 0  # Payment pending
    }
    

定期購入が再開された後(支払い方法が更新された後)に定期購入を照会すると、expiryTimeMillis は将来のタイムスタンプに設定され、paymentState は 1 に設定されます。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": timestamp_in_future,
      "autoRenewing": true,
      ...
      "paymentState": 1  # Payment received
    }
    

30 日間の一時停止の経過後に解約された定期購入を照会すると、expiryTimeMillis は過去のタイムスタンプに設定され、cancelReason は 1 に設定されます。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": timestamp_in_past,
      "autoRenewing": false,
      ...
      "cancelReason": 1  # The system canceled the subscription
    }
    

定期購入の再開 - SUBSCRIPTION_RECOVERED

定期購入の再開後、購入トークンは通常、ユーザーのアカウント一時停止が開始される前のものと同じになります。ただし、ユーザーが一時停止期間中に定期購入を再購入することで、定期購入しているコンテンツへのアクセスを取り戻す場合があります。この場合、定期購入の新しいインスタンスを表すために、新しい購入トークンの値が返されます。

サーバーに新しい定期購入のデータを登録したら、定期購入が再開されたことをユーザーに知らせるメッセージをアプリに表示できますたとえば、「更新されたお支払い方法が記録され、定期購入が再開されました」といったメッセージを表示します。

定期購入の解約 - SUBSCRIPTION_CANCELLED

ユーザーは、手動で Play ストアから定期購入を解約したり、一時停止後に再開を希望しない場合は自動的に定期購入を解約したりすることができます。安全なバックエンド サーバーで SUBSCRIPTION_CANCELLED リアルタイム デベロッパー通知を受信した場合は、次のようになります。

  • 定期購入が解約されたことをユーザーに通知するメッセージをアプリ内に表示します。たとえば、「定期購入は **日付** に期限切れになります。Google Play の定期購入の設定に移動して、定期購入を再開してください」といったメッセージを表示します。ユーザーが定期購入を更新できるように、メッセージ内に Google Play の定期購入の設定へのリンクを記載します。
  • メッセージを今後表示しないという選択肢も提供します。

新しい購入トークンを受け取ったら、購入トークンを確認する手順を行います。

注: 解約に関するメッセージは、ユーザーに不快感を与える可能性があります。ユーザー自身の手で定期購入を解約している(支払い方法が期限切れになって解約になったのではなく)場合は、特にそうです。手動で定期購入を解約したユーザーには、通知しないという選択肢もあります。

ユーザーによる定期購入の一時停止 - SUBSCRIPTION_PAUSED

現在一時停止中の定期購入を照会したとき、expiryTimeMillis が過去の日付で、autoResumeTimeMillis が将来の日付の場合は、コンテンツに対するユーザー アクセスを一時停止し、ユーザーの利用権を「一時停止中」と見なします。

    {
      "kind": "androidpublisher#subscriptionPurchase",
      ...
      "expiryTimeMillis": $subscription_entitlement_end_time (in the past)
      "autoRenewing": true,
      "paymentState": 1  # Payment received
      ...
      "autoResumeTimeMillis": $subscription_auto_resume_time (in the future)
    }
    

定期購入の価格を変更する

警告:Google で購読」の定期購入の場合は、価格を変更しないでください。

Google Play Console を使用すると、アプリ内で提供する定期購入の価格を変更できます。この機能は、特定の定期購入に関連付けられているコンテンツの量やアプリ内特典の範囲を変更する場合に役立ちます。

定期購入の価格を更新するには、Google Play Console で次の手順を行います。

  1. 価格を変更する定期購入を含むアプリに移動します。
  2. [ストアでの表示] > [アプリ内アイテム] を選択して、[定期購入] タブを開きます。
  3. 変更する価格の横にある [編集] リンクを選択します(図 1 を参照)。

    定期購入価格の横にある [編集] リンク
    図 1. 定期購入の価格の編集
  4. 定期購入の新しい価格を入力します。

    価格を変更すると、図 2 に示すように、警告ダイアログが表示されます。 このダイアログでは、新しい定期購入ユーザーに対しては価格の変更がすぐに有効になり、価格の変更に同意した既存の定期購入ユーザーに対しては 30 日以内に価格の変更が有効になることが説明されています。

    定期購入の価格変更の警告ダイアログ
    図 2. 定期購入の価格変更が有効になるタイミングに関する警告

価格の変更をユーザーに知らせる

デベロッパーは、Google Play で通知が開始されるまでの間(少なくとも 7 日間)に、価格の変更について既存の定期購入ユーザーに連絡する必要があります。Google Play によるユーザーへの通知は、図 3 のようなダイアログで表示されます。 このダイアログには、以前の価格、新しい価格、新しい価格が有効になる日付が表示されます。

定期購入の価格変更の一般的なダイアログ
図 3. 定期購入の価格変更をユーザーに通知する一般的なダイアログ

次の方法で、このダイアログをアプリ内に表示できます。

価格変更確定フローを起動する

アプリの起動時にダイアログを表示するには、課金クライアント クラスに次のロジックを追加します。

Kotlin

    val priceChangeFlowParams = PriceChangeFlowParams.newBuilder()
            .setSkuDetails(changedPriceSubscriptionSkuDetails)
            .build()

    billingClient.launchPriceChangeConfirmationFlow(activity,
            priceChangeFlowParams,
            object : PriceChangeConfirmationListener() {
                override fun onPriceChangeConfirmationResult(responseCode: Int) {
                    if (responseCode == BillingResponse.OK) {
                        // User has confirmed the price change.
                    } else if (responseCode == BillingResponse.USER_CANCELED) {
                        // User hasn't confirmed the price change.
                    }
                }
            })
    

Java

    PriceChangeFlowParams priceChangeFlowParams = PriceChangeFlowParams.newBuilder()
            .setSkuDetails(changedPriceSubscriptionSkuDetails)
            .build();

    billingClient.launchPriceChangeConfirmationFlow(activity,
            priceChangeFlowParams,
            new PriceChangeConfirmationListener() {
                @Override
                public void onPriceChangeConfirmationResult(int responseCode) {
                    if (responseCode == BillingResponse.OK) {
                        // User has confirmed the price change.
                    } else if (responseCode == BillingResponse.USER_CANCELED) {
                        // User hasn't confirmed the price change.
                    }
                }
            });
    

Google Play の価格変更ダイアログを表示する前に、価格変更の理由を説明する独自のメッセージやダイアログを表示できます。このようなカスタム メッセージを作成して表示すると、ユーザーが新しい価格で定期購入を更新することを選択する可能性が高くなります。

ユーザーがカスタム ダイアログに応答すると、アプリが再びアクティブになり、Google Play Billing Library から responseCode(タイプ BillingClient.BillingResponse)が返されます。

デベロッパーは、PriceChangeConfirmationListener の実装によってユーザーのレスポンスを処理できます。たとえば、ユーザーが価格変更に同意した場合に、カスタマイズしたお礼メッセージを表示することもできます。

価格変更に対するユーザーの同意を処理する

定期購入の新しい価格にユーザーが同意すると、ライブラリから請求サーバーにも通知が送信されます。デベロッパーは、Google のリアルタイム デベロッパー通知機能により、ダイアログに対するユーザーのレスポンスに関する通知を受け取ることができます。ユーザーが価格の変更に同意した場合、タイプ SUBSCRIPTION_PRICE_CHANGE_CONFIRMED の通知を受け取ります。

価格変更が不承認となったケースを処理する

ユーザーがアプリの PriceChangeConfirmationListener で価格変更に同意しない場合もあります。このような場合、ユーザーの以前の定期購入は継続されますが、次の更新日に期限切れとなります。以前の定期購入が期限切れとなるまでにユーザーが価格変更に同意しなかった場合、定期購入は解約され、デベロッパーはタイプ SUBSCRIPTION_CANCELEDリアルタイム デベロッパー通知を受け取ります。

定期購入をサポートしているアプリの場合、ユーザーが定期購入を管理するためのリンクを設定画面に組み込みます。図 4 にリンクの例を示します。ユーザーがアプリ内で有効期限内の定期購入を利用している状態(expiryTimeMillis が将来の日付に設定されている状態、あるいはautoRenewingtrue に設定されている状態)かどうかを判断するロジックを、このリンクのクリック ハンドラに追加します。

  • アプリ内に有効期限内の定期購入がない場合は、次の URL を使用して、他のすべての定期購入を表示するページに移動します(図 5 を参照)。

        https://play.google.com/store/account/subscriptions
        
  • これに対し、有効期限内の定期購入がある場合は、次の URL を使用して、その定期購入に直接移動できます(図 6 を参照)。

        https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package
        

各定期購入の SKU は、Play Console 内で作成したときに割り当てたアイテム ID と一致します。プログラマティックに既存の定期購入の SKU を確認するには、個々のユーザーに関連付けられている定期購入のリストをアプリのバックエンドで照会します。

「Google Play Subscriptions」というボタンを含む設定画面
図 4.「定期購入を管理」するリンクの例(画像内の [Google Play Subscriptions] ボタン)
ユーザーのすべてのアプリの定期購入を表示する定期購入の詳細画面
図 5. ユーザーがアプリ外で購入したすべての定期購入を表示する画面(アプリ内の定期購入がない場合)
特定のアプリでユーザーが購入した特定の定期購入を表示する定期購入の詳細画面
図 6. ユーザーがアプリ内で購入した特定の定期購入の詳細情報を表示する画面(アプリ内の定期購入がある場合)

定期購入のアップグレードやダウングレードを許可する

デベロッパーは基本階層やプレミアム階層など、さまざまな定期購入の階層をユーザーに提供できます。 2 つの定期購入の階層を提供する画面を図 7 に示します。

図 7. 定期購入の階層

ユーザーは同様の画面にアクセスし、別の階層の定期購入を購入することにより、定期購入のアップグレードまたはダウングレードを行える必要があります。この場合、アプリ内アイテムの購入を有効にするの説明にある元の定期購入の購入に使用されたのと同じアプリ内アイテムの購入フローを使用する必要があります。ただし、アップグレードまたはダウングレードを処理する際は、setOldSku() メソッドを使用して、現在の定期購入のアイテム ID と今後(アップグレード後またはダウングレード後)の定期購入のアイテム ID を BillingFlowParams オブジェクトに渡します。以下に例を示します。

Kotlin

    val flowParams = BillingFlowParams.newBuilder()
            .setSkuDetails(newSkuDetails)
            .setOldSku(currentId)
            .build()
    val responseCode = billingClient.launchBillingFlow(activity, flowParams)
    

Java

    BillingFlowParams flowParams = BillingFlowParams.newBuilder()
            .setSkuDetails(newSkuDetails)
            .setOldSku(currentId)
            .build();
    int responseCode = billingClient.launchBillingFlow(flowParams);

    

購入トークンを受け取ったら、新しい購入トークンの確認に使用するのと同じ確認手続きを行います。詳しくは、購入を確認するをご覧ください。Google Play Developer API は、定期購入リソース内で linkedPurchaseToken を返しますが、サービスに対するアクセスに以前のトークンが使用されないように、linkedPurchaseToken 内で提供されるトークンは必ず無効にしてください。

ユーザーがアップグレードまたはダウングレードを行うと、SUBSCRIPTION_PURCHASED ステータスが安全なバックエンド サーバーに送信されます。SUBSCRIPTION_PURCHASED を処理するには、SUBSCRIPTION_PURCHASED を処理する場合の説明をご覧ください。

比例配分モードを設定する

定期購入のアップグレードまたはダウングレードを行う場合、BillingFlowParams クラス内で replaceSkusProrationMode を設定することで、定期購入の変更時に適用される比例配分に関する詳細を指定できます。

Kotlin

    val flowParams = BillingFlowParams.newBuilder()
            .setSkuDetails(skuDetails)
            .setOldSku(oldSku)
            .setReplaceSkusProrationMode(replaceSkusProrationMode)
            .build()
    val responseCode = billingClient.launchBillingFlow(activity, flowParams)
    

Java

    BillingFlowParams flowParams = BillingFlowParams.newBuilder()
            .setSkuDetails(skuDetails)
            .setOldSku(oldSku)
            .setReplaceSkusProrationMode(replaceSkusProrationMode)
            .build()
    int responseCode = billingClient.launchBillingFlow(activity, flowParams);
    

下記の表に、すべての比例配分モードを示します。

IMMEDIATE_WITH_TIME_PRORATION 切り替えは直ちに有効になり、新しい有効期限が比例配分され、ユーザーへの入金または請求が行われます。これが現在のデフォルトの動作です。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE 切り替えは直ちに有効になりますが、請求期間は変わりません。残りの期間の価格に対する請求が行われます。

: このオプションは定期購入のアップグレードでのみ利用可能です。

IMMEDIATE_WITHOUT_PRORATION 切り替えは直ちに有効になり、新しい価格が次回契約期間に請求されます。請求サイクルは変わりません。
DEFERRED 切り替えは次回契約期間に有効になります。

各モードの仕組みを理解するために、次の事例について考えてみましょう。

あるユーザーが「Country Gardener」というアプリのオンライン コンテンツを定期購入しているとします。現在は、そのコンテンツの Tier 1 バージョンを月次定期購入しています(コンテンツはテキストのみ)。月額は 200 円で毎月 1 日に契約が更新されます。

4 月 15 日に、Tier 2 の定期購入にアップグレードすることにしました(動画のアップデートが含まれます)。月額は 300 円になります。

デベロッパーは定期購入のアップグレードに、比例配分モードを選択しています。各比例配分モードがユーザーの定期購入にどのように影響するのかを、以下のリストに示します。

  • IMMEDIATE_WITH_TIME_PRORATION - このモードを使用すると、ユーザーの Tier 1 の定期購入は直ちに終了します。ユーザーは 1 か月分(4 月 1~30 日)をすでに支払っていますが、半分しか使用しておらず、月次定期購入分の残り半分(100 円)は新しい定期購入に適用されます。ただし、新たな登録は月 300 円のため、100 円のクレジット残高は 10 日分にしかなりません。よって、このユーザーのクレジットは、4 月 15~25 日の分に当てられます。4 月 26 日に新しい定期購入契約の 300 円が課金され、翌月以降、毎月 26 日に 300 円が課金されるようになります。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE - このモードを使用すると、ユーザーの Tier 1 の定期購入は直ちに終了します。ユーザーは 1 か月分(4 月 1~30 日)をすでに支払っていますが、半分しか使用しておらず、月次定期購入分の残り半分(100 円)は新しい定期購入に適用されます。ただし、新たな登録は月 300 円のため、残りの 15 日分の価格は 150 円になります。そのため、新たな定期購入の差額分 50 円が課金され、翌月以降、毎月 1 日に 300 円が課金されるようになります。
  • IMMEDIATE_WITHOUT_PRORATION - このモードを使用すると、ユーザーの Tier 1 の定期購入は直ちに追加料金なしで Tier 2 にアップグレードされます。新しい定期購入の 300 円は 5 月 1 日に課金され、翌月以降、毎月 1 日に 300 円が課金されるようになります。
  • DEFERRED - このモードを使用すると、ユーザーの Tier 1 定期購入は 4 月 30 日に有効期限が切れるまで継続します。5 月 1 日に Tier 2 定期購入が有効になり、新しい階層の定期購入の 300 円が課金されるようになります。

定期購入を一時停止する

ユーザーが定期購入を一時停止できるようにすることで、自発的な解約を防ぐことができます。一時停止機能を有効にすると、契約期間の長さに応じて、ユーザーは 1 週間から 3 か月の間で定期購入を一時停止できます。一時停止機能を有効にすると、定期購入センターと解約フローの両方に表示されます。1 週間~3 か月という一時停止期間の制限は、随時変更される可能性があります。また、年次定期購入は一時停止できません。

重要: 一時停止を有効にするには、アカウントの一時停止も有効にする必要があります。

ユーザーが定期購入を一時停止できるようにする手順は次のとおりです。

  1. Google Play Console にログインします。
  2. アプリを選択して、[ストアでの表示] > [アプリ内アイテム] > [定期購入] に移動します。
  3. [定期購入の設定] を展開します。
  4. [一時停止を有効にする] チェックボックスをオンにします。

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

定期購入の一時停止状態からアカウントの一時停止状態に移行する図。
図 8. ユーザーが定期購入を一時停止した後にアカウント一時停止状態になるケース

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

定期購入の一時停止状態から再開状態に移行する図。
図 9. ユーザーが定期購入を一時停止した後で再開したケース

定期購入が一時停止になっている場合は、一時停止中のために定期購入にアクセスできないことをアプリ内でユーザーに通知することをおすすめします。また、Google Play へのディープリンクを使用して、ユーザーが容易に手動で定期購入を再開できるようにしておくとよいでしょう。

定期購入の一時停止および再開のタイミングは、次のいずれかの方法で確認できます。

  • Google Play Developer API を使用して、Purchases.subscriptions レスポンス内の expiryTimeMillis フィールドと autoResumeTimeMillis フィールドを確認します。

    • ユーザーが今後一時停止状態になる場合expiryTimeMillisautoResumeTimeMillis の両方に将来の日付が格納されます。
    • ユーザーが現在一時停止状態にある場合autoResumeTimeMillis には将来の日付が格納され、expiryTimeMillis には過去の日付が格納されます。
    • ユーザーが定期購入を再開した場合、レスポンスにはアクティブな定期購入データが格納されます。
    • ユーザーがアカウント一時停止状態になった場合、レスポンスにはアカウントの一時停止を示すデータが格納されます。
  • リアルタイム デベロッパー通知(RTDN)を使用します。定期購入の一時停止に関する最新情報を確実に取得するには、認識されないタイプを含めて、すべての RTDN 通知タイプに対応する Google Play Developer API を呼び出す必要があります。定期購入の一時停止に関連する通知タイプは次のとおりです。

    • SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED: 一時停止が有効になる前に、ユーザーが定期購入の一時停止または再開を選択しました。
    • SUBSCRIPTION_PAUSED: 定期購入は現在一時停止中です。
    • SUBSCRIPTION_RENEWED: 定期購入は正常に再開されました。
    • SUBSCRIPTION_ON_HOLD: 定期購入を再開できませんでした。定期購入は現在、アカウントの一時停止状態です。
  • Android デバイス上で、アプリが起動するたびに Google Play Billing Library を使用して queryPurchases() を呼び出します。アプリの実行中は PurchasesUpdatedListener を使用して最新情報を受信します。onPurchasesUpdated() 内の Purchase オブジェクトのリストには、一時停止中の定期購入は含まれません

再度定期購入できるようにする

定期購入がまだ期限切れになっていない場合でも、ユーザーは、解約した定期購入を再度定期購入できます。 解約された定期購入と同じアイテム ID を使用し、同じアプリ内アイテム購入フローを適用することで、ユーザーがアプリ内で再度定期購入できるようになります。

再度定期購入すると、アクティブな定期購入があればそれと置き換わり、元の定期購入と同じ有効期限となります。たとえば、あるユーザーが「Example Music App」というアプリを定期購入していたとします。現在の定期購入の有効期限は 8 月 1 日です。7 月 10 日に、同じ月額で 1 か月分再度定期購入するとします。新しい定期購入は、残りのクレジットに基づいて比例配分され、すぐに有効になり、8 月 1 日に更新されます。

デベロッパーは、再度定期購入するための適切な UI を表示する必要があります。

  • アクティブな定期購入がないユーザーには、アプリ内に [購入] ボタンを表示します。
  • 解約した定期購入(SUBSCRIPTION_CANCELLED)があるユーザーには、アプリ内に [再度定期購入] ボタンを表示します。詳細については、SUBSCRIPTION_CANCELLED を処理する場合の説明をご覧ください。

購入トークンを受け取ったら、新しい購入トークンの確認に使用するのと同じ確認手続きを行います。詳しくは、購入を確認するをご覧ください。 Google Play Developer API は、定期購入リソース内で linkedPurchaseToken を返しますが、サービスに対するアクセスに以前のトークンが使用されないように、linkedPurchaseToken 内で提供されるトークンは必ず無効にしてください。

定期購入のプロモーション コードを提供する

プロモーション(プロモーション コード)を実装して、限られた数のユーザーに 1 回限りのアイテムや定期購入の試用期間を無料で提供することができます。定期購入の試用のプロモーション コードを提供するには、プロモーションを実装するをご覧ください。

定期購入の料金を払い戻す

Google Play では、定期購入の払い戻し期間は設けられていません。代わりに、ユーザーは払い戻しを直接要求する必要があります。ユーザーは Play ストアの [ご注文履歴] ページを使用するか、デベロッパーに直接問い合わせて払い戻しを要求できます。

払い戻しのリクエストを受け取った場合、デベロッパーは Google Play Developer API または Merchant Center を使用して以下を行います。

  1. 定期購入を解約します(Purchases.subscriptions:cancel)。
  2. 定期購入がすでに解約されていることを確認します(HTTP レスポンス コード 200 が返されます)(Purchases.subscriptions:cancel)。
  3. 定期購入を解約せずにユーザーの支払い額を払い戻します(Purchases.subscriptions:refund)。

直近の支払い以前の分まで払い戻す場合は、Merchant Center を通じて、追加の払い戻し処理を行います。

定期購入が解約されると、SUBSCRIPTION_CANCELLED ステータスが安全なバックエンド サーバーに送信されます。SUBSCRIPTION_CANCELLED を処理するには、SUBSCRIPTION_CANCELLED を処理する場合の説明をご覧ください。

定期購入を取り消す

デベロッパーは、Google Play Developer APIPurchases.subscriptions:revoke を使用することで、定期購入を取り消すことができます。 定期購入を取り消すと、直ちに定期購入にアクセスできなくなります。定期購入の取り消しは通常、デベロッパーや Google が不正行為を疑う場合に行われます。

定期購入を解約する

ユーザーは、Play ストア アプリから定期購入を解約できます。デベロッパーは、Google Play Developer APIPurchases.subscriptions:cancel を使用することで、定期購入を解約できます。

注: この API は通常、ユーザーが [ご注文履歴] ページから払い戻しをリクエストした場合に使用されます。詳細については、定期購入の料金を払い戻すをご覧ください。

ユーザーは現在の請求期間が終了するまで、コンテンツに引き続きアクセスできます。請求期間が終了すると、アクセスできなくなります。

重要: コンテンツの利用権を持つユーザーがいる間は、Google Play から定期購入を削除しないようにしてください。ユーザーに権利のあるコンテンツを削除すると、ペナルティが発生します。詳しくは、定期購入の作成の「解約」セクションをご覧ください。

定期購入を再開する

注: 再開機能はデフォルトで有効になっており、定期購入を有効にしたすべてのデベロッパーが利用できます。再開機能をテストして、再開を適切に処理できるかどうかを確認しておくことを強くおすすめします。テストを簡単に実施できるよう、すべてのライセンス テスト アカウントの再開機能を有効にしてあります。定期購入のテストの詳細については、定期購入固有の機能をテストするをご覧ください。

この機能は Google Play Console でオプトアウトできます。その場合、[ストアでの表示] > [アプリ内アイテム] > [定期購入の設定] に移動して、[ユーザーが Google Play で定期購入を再開することを許可します] チェックボックスをオフにします。

解約された定期購入は、有効期限まで Play ストア アプリに表示されたままになります。ユーザーは、有効期限が切れる前に解約した定期購入を再開できます。それには、図 10 に示すように Play ストア アプリ内の [定期購入] で [再開] をクリックします。

図 10. Play ストア アプリの [アカウント] > [定期購入]

定期購入がいつ再開されたかは、次の 2 つの方法で確認できます。

  1. アプリに SUBSCRIPTION_RESTARTED 通知が届きます。詳細については、リアルタイム デベロッパー通知についての説明をご覧ください。
  2. アプリの起動時に、毎回 getPurchases() メソッドを呼び出します。なお、定期購入が再開されると、purchaseToken は定期購入の解約前と同じものになります。

ユーザーは次の手順で、解約した定期購入を再開できます。

  1. Google Play Console にログインします。
  2. アプリを選択して、[ストアでの表示] > [アプリ内アイテム] に移動します。
  3. [定期購入] タブを選択し、[定期購入の設定] を展開します。
  4. 図 11 に示すように、[ユーザーが Google Play で定期購入を再開することを許可します] チェックボックスをオンにして、[保存] をクリックします。
    図 11. Google Play Console の [ユーザーが Google Play で定期購入を再開することを許可します] チェックボックス

課金を延期する

デベロッパーは、Google Play Developer APIPurchases.subscriptions:defer を使用することで、定期購入ユーザーの次回の課金日を延期することができます。 ユーザーは、定期購入コンテンツに引き続きアクセスすることができ、延期期間中は課金されません。定期購入の更新日は、新しい日付を反映して更新されます。 課金を延期することで、次のことが可能になります。

  • セット販売割引やスペシャル オファーの一環として無料アクセスを提供します(印刷版の雑誌の定期購読を申し込んだユーザーに、ウェブ コンテンツへの無料アクセス権限を付与するなど)。
  • 感謝の印としてユーザーに無料アクセス権限を付与します。

課金の延期は、API 呼び出し 1 回あたり最短で 1 日、最長で 1 年間です。次回の課金日の前に再度 API を呼び出すことで、さらに延期できます。

たとえば、あるユーザーが「Fishing Quarterly」というアプリのオンライン コンテンツを月次定期購入しているとします。普段は毎月 1 日に、125 円を支払っています。3 月に、アプリ パブリッシャーが実施したオンライン調査に回答しました。パブリッシャーは謝礼として 6 週間分を無料にし、次のお支払いを 5 月 15 日まで延期することにしました(予定されていた次回請求日 4 月 1 日の 6 週間後)。このユーザーは 4 月 1 日と 5 月 1 日には課金されませんが、通常どおりコンテンツにはアクセスできます。5 月 15 日には、これまでどおり 125 円が定期購入料金として課金されます。次の更新日は、6 月 15 日になります。

請求日が延期された(変更された)ことをユーザーに知らせるために、ユーザーに通知する(メールを使用するかアプリ内で表示する)ことができます。

解約を思いとどまらせるための特典を提供する

サービスを長期利用していたユーザーが解約を行った場合、特別価格を設定した定期購入アイテム ID(「再獲得 SKU」)を提供してはどうでしょうか。ユーザーに対しては、特典をアプリ内で提供することも、メールで通知することもできます。再獲得用の定期購入を開始するには、Google Play Billing Library を使用して、Android アプリ内で購入フローを開始します。これは新しい定期購入と同じプロセスですが、デベロッパーはユーザーが利用できる SKU を決定できます。

最新のニュースとリソース

次のステップ

定期購入固有の機能を追加したら、ベスト プラクティスに進みます。