定期購入専用機能の追加

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

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

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

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

このようなユースケースに対処するには、Google Play 請求サービス ライブラリ、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 請求サービス ライブラリから responseCode(タイプ BillingClient.BillingResponse)が返されます。

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

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

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

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

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

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

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

    http://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 をプログラマティックに判断するには、個々のユーザーに関連付けられている定期購入のリストをアプリのバックエンドで照会します。必要なサーバーサイド ロジックの例については、ClassyTaxi サンプルアプリ内の queryCurrentSubscriptions() メソッドをご覧ください。

「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 請求サービス ライブラリを使用して 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 から定期購入を削除しないようにしてください。ユーザーに対する支払いが必要なコンテンツを削除すると、ペナルティが発生します。詳細については、定期購入を作成するの「解約」をご覧ください。

定期購入を再開する

注: すべてのアプリで一貫したユーザー エクスペリエンスを提供するため、2019 年 4 月 15 日以降、Google は、定期購入を有効にしているすべてのデベロッパーに対して再開機能をデフォルトで有効にします。再開を適切に処理できるか確認するため、この日付より前に再開機能をテストすることを強くおすすめします。簡単に移行できるよう、Google はすべてのライセンス テスト アカウントの再開を有効にしました。定期購入のテストの詳細については、定期購入固有の機能をテストするをご覧ください。

コードの変更が必要であり、2019 年 4 月 15 日までに変更を完了できない場合は、Google Play Console 内でオプトアウトすることができます。[ストアでの表示] > [アプリ内アイテム] > [定期購入の設定] に移動して、[ユーザーが Google Play で定期購入を再開することを許可します] チェックボックスをオフにしてください。また、2019 年 4 月 15 日に変更が有効になった後に、オプトアウトすることもできます。

解約された定期購入は、有効期限まで Play ストア アプリに表示されたままになります。ユーザーは、有効期限が切れる前に 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 請求サービス ライブラリを使用して、Android アプリ内で購入フローを開始します。これは新しい定期購入と同じプロセスですが、デベロッパーは、ユーザーが利用できる SKU を決定できます。

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

次のステップ

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