定期購入を販売する

このトピックでは、更新や有効期限など、定期購入のライフサイクル イベントを処理する方法について説明します。また、プロモーションの提供やユーザーによる定期購入の管理など、その他の定期購入機能についても説明します。

アプリの定期購入アイテムを構成していない場合は、アイテムを作成して構成するをご覧ください。

定期購入の概要

定期購入は、指定された期間にユーザーが利用できる特典のセットを表します。たとえば、定期購入により、ユーザーは音楽ストリーミング サービスの利用資格を獲得できます。

同じアプリ内に複数の定期購入を設定して、異なる特典セットや、単一の特典セットの異なる階層(シルバー階層、ゴールド階層など)を提供できます。

基本プランと特典を使用して、同じ定期購入アイテムについて複数の構成を作成できます。たとえば、アプリを定期購入したことがないユーザーを対象とするお試し特典を作成できます。同様に、すでに定期購入しているユーザーを対象とするアップグレード特典を作成できます。

定期購入商品、基本プラン、特典の詳細については、Google Play Console ヘルプセンターのドキュメントをご覧ください。

プリペイド プランの統合

プリペイド プランは、有効期限が切れても自動的に更新されません。ユーザーが定期購入の利用資格を中断なしで延長するには、同じ定期購入にプリペイド プランをチャージする必要があります。

チャージするには、元の購入の場合と同様に請求フローを開始します。購入がチャージであることを示す必要はありません。

プリペイド プランのチャージでは常に IMMEDIATE_AND_CHARGE_FULL_PRICE 比例配分モードが使用されるため、このモードを明示的に設定する必要はありません。ユーザーは直ちに請求対象期間の全額を請求され、チャージで指定した期間について利用資格が延長されます。

チャージされると、最新のチャージ購入を反映するために、Purchase 結果オブジェクトの以下のフィールドが更新されます。

  • 注文 ID
  • 購入時間
  • 署名
  • 購入トークン
  • 承認済み

Purchase の以下のフィールドには、常に元の購入と同じデータが格納されます。

  • パッケージ名
  • 購入ステータス
  • アイテム
  • 自動更新

プリペイド購入の承認

自動更新される定期購入と同様に、デベロッパーはプリペイド プランも購入後に承認する必要があります。初回購入とチャージの両方で承認が必要です。詳細については、購入を処理するをご覧ください。

プリペイド プランの期間が短い可能性があるため、できるだけ早く購入を承認することが重要です。

期間が 1 週間以上のプリペイド プランは、3 日以内に承認する必要があります。

期間が 1 週間未満のプリペイド プランは、プラン期間の半分以内に承認する必要があります。たとえば、3 日間のプリペイド プランの承認期限は 1.5 日間です。

デベロッパーは、ユーザーが定期購入を簡単に管理できるようにする必要があります。そのため、アプリの設定画面に、ユーザーが定期購入を管理するためのリンクを組み込みます。図 4 に、このリンクの例を示します。

「定期購入を管理」するリンクの例(画像内の [Google Play Subscriptions] ボタン)。
図 4. 「定期購入を管理」するリンクの例(画像内の [Google Play Subscriptions] ボタン)。

ユーザーがアプリ内で有効期限内の定期購入を利用している(expiryTime が将来の日付に設定されているか、autoRenewingtrue に設定されている)かどうかを判断するロジックを、このリンクのクリック ハンドラに追加します。

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

ユーザーに有効期限が切れていない定期購入がある場合は、次のような URL にユーザーを誘導できます。「your-sub-product-id」と「your-app-package」は、実際の定期購入 ID とアプリ パッケージ情報に置き換えてください。

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

有効期限が切れていない定期購入がユーザーのアプリ内にない場合は、次の URL を使用して、図 5 と図 6 に示すように、他の定期購入がすべて表示されているページにユーザーを誘導します。

https://play.google.com/store/account/subscriptions
Play ストアの定期購入画面には、ユーザーのすべての定期購入のステータスが表示されます。
図 5. Play ストアの定期購入画面には、ユーザーのすべての定期購入のステータスが表示される。
さらに詳しい情報を表示するには、定期購入をタップします。
図 6. さらに詳しい情報を表示するには、定期購入をタップする。

定期購入リンクロジックのサンプルコードは、Classy Taxi のサンプルアプリにあります。

ユーザーが定期購入をアップグレード、ダウングレード、変更できるようにする

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

このアプリには 2 つの定期購入階層が含まれています
図 7. このアプリにある 2 つの定期購入階層。

ユーザーが定期購入をアップグレードまたはダウングレードするには、図 7 のような画面にアクセスできる必要があります。定期購入をアップグレードまたはダウングレードする場合は、比例配分モードを設定して、変更が定期購入者に与える影響を指定できます。

次の表に、利用可能な比例配分モードを示します。

比例配分モード説明
IMMEDIATE_WITH_TIME_PRORATION 定期購入は直ちにアップグレードまたはダウングレードされます。残りの期間は価格の差に応じて調整され、次回の請求日との差分が新しい定期購入に充当されます。これがデフォルト設定です。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE 定期購入は直ちにアップグレードされますが、請求期間は変わりません。ユーザーには残りの期間の差額が請求されます。
IMMEDIATE_WITHOUT_PRORATION 定期購入は直ちにアップグレードまたはダウングレードされ、定期購入の更新時に新しい価格が請求されます。請求期間は変わりません。
DEFERRED 定期購入は、更新時にのみアップグレードまたはダウングレードされます。
IMMEDIATE_AND_CHARGE_FULL_PRICE 定期購入がアップグレードまたはダウングレードされると、ユーザーには新しい利用資格の全額が直ちに課金されます。以前の定期購入の残額は、同じ利用資格に引き継がれるか、別の利用資格への切り替え時に期間内で比例配分されます。

ユーザーが定期購入の利用資格を変更する場合は、実行時に比例配分率を指定する必要があります。利用資格を変更する場合、Google Play Console でデフォルトの比例配分モードを指定することはできません。

ユーザーが定期購入の利用資格を変更しない場合は、Google Play Console で設定されたデフォルトの比例配分モードを使用できます。SubscriptionUpdateParams で比例配分モードを指定して、この動作をオーバーライドすることもできます。次の制限事項にご注意ください。

  • 定期購入をアップグレードまたはダウングレードする場合、あるいはプリペイド プランまたは自動更新プランからプリペイド プランへと切り替える場合、許容される比例配分モードは IMMEDIATE_AND_CHARGE_FULL_PRICE のみです。他の比例配分モードを指定すると、購入は失敗し、ユーザーに対してエラーが表示されます。
  • 同じ定期購入内でプランをプリペイド プランから自動更新プランへと切り替える場合、有効な比例配分モードは IMMEDIATE_AND_CHARGE_FULL_PRICEIMMEDIATE_WITHOUT_PRORATION です。他の比例配分モードを指定すると、購入は失敗し、ユーザーに対してエラーが表示されます。

比例配分の例

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

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

4 月 15 日に、Tier 2 定期購入の年間バージョンにアップグレードすることにしました。これには動画のアップデートが含まれ、料金は年間 3,600 円です。

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

IMMEDIATE_WITH_TIME_PRORATION
ユーザーの Tier 1 の定期購入は直ちに終了します。ユーザーは 1 か月分(4 月 1~30 日)をすでに支払っていますが、定期購入期間が半分経過した時点でアップグレードしたことで、月次定期購入分の残り半分(100 円)は新しい定期購入に適用されます。ただし、この新しい定期購入の年間料金が 3,600 円であることから、100 円のクレジット残高の支払いは 10 日分(4 月 16~25 日)のみとなります。したがって 4 月 26 日に新しい定期購入について 3,600 円、以降の毎年 4 月 26 日に 3,600 円が請求されます。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE
このモードは、Tier 2 の定期購入の単位時間あたり価格(3,600 円/年 = 300 円/月)が、Tier 1 の定期購入の単位時間あたり価格(200 円/月)よりも大きいために使用できます。ユーザーの Tier 1 の定期購入は直ちに終了します。ユーザーは 1 か月分をすでに支払っていますが、半分しか使用しておらず、月次定期購入分の残り半分(100 円)は新しい定期購入に適用されます。ただし、新しい定期購入の料金が 3,600 円/年であり、残りの 15 日分の料金が 150 円であるため、新しい定期購入については差分の 50 円が課金されます。5 月 1 日には新しい定期購入の 3,600 円が課金され、以後毎年 5 月 1 日に 3,600 円が課金されます。
IMMEDIATE_WITHOUT_PRORATION
ユーザーの Tier 1 の定期購入は直ちに追加料金なしで Tier 2 にアップグレードされます。5 月 1 日には新しい定期購入について 3,600 円が課金され、以後毎年 5 月 1 日に 3,600 円が課金されます。
DEFERRED
ユーザーの Tier 1 定期購入は 4 月 30 日に有効期限が切れるまで継続します。5 月 1 日に Tier 2 定期購入が有効になり、新しい Tier の定期購入に対して 3,600 円が課金されます。
IMMEDIATE_AND_CHARGE_FULL_PRICE
ユーザーの Tier 1 定期購入は直ちに終了します。その日に Tier 2 定期購入が開始され、3,600 円が課金されます。ユーザーは 1 か月分をすでに支払っていますが、半分しか使用しておらず、月次定期購入分の残り半分(100 円)は新しい定期購入に適用されます。新しい定期購入の料金は年間 3,600 円であるため、1 年の 1/36(概算で 10 日)が定期購入期間に追加されます。したがって、次回の請求はその日から 1 年と 10 日後で、3,600 円になります。それ以降は毎年 3,600 円が課金されます。

比例配分モードを選択する際は、比例配分の推奨事項をご確認ください。

アプリでは、購入フローの開始と同じ手順でアップグレードまたはダウングレードを提供できます。ただし、アップグレードまたはダウングレードする場合は、次の例に示すように、現在の定期購入、将来(アップグレードまたはダウングレード)の定期購入、使用する比例配分モードの詳細を指定する必要があります。

String offerToken = productDetails
                        .getSubscriptionOfferDetails(selectedOfferIndex)
                        .getOfferToken();

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmuableList.of(
            ProductDetailsParams.newBuilder()
                // fetched via queryProductDetailsAsync
                .setProductDetails(productDetails)
                // offerToken can be found in
                // ProductDetails=>SubscriptionOfferDetails
                .setOfferToken(offerToken)
                .build()))
    .setSubscriptionUpdateParams(
        SubscriptionUpdateParams.newBuilder()
            // purchaseToken can be found in Purchase#getPurchaseToken
            .setOldSkuPurchaseToken("old_purchase_token")
            .setReplaceSkusProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
            .build())
    .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

// process purchase results from PurchasesUpdatedListener registered with BillingClient
public void onPurchaseUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
  // check BillingResult
  // process returned Purchase list, e.g. grant entitlement
}

即時交換比例配分モードの場合、アプリは PurchasesUpdatedListener で新しい購入を受け取ります。購入は BillingClient.queryPurchasesAsync() でも利用できます。購入トークンを受け取ったら、新しい購入トークンを検証する場合と同じ検証プロセスを行います。Google Play Billing Library の BillingClient.acknowledgePurchase()、または Google Play Developer API の Purchases.subscriptions:acknowledge を使用して購入を承認します。

Google Play Developer API は、定期購入リソースlinkedPurchaseToken を返します。 サービスに対するアクセスに以前のトークンが使用されないように、linkedPurchaseToken 内で提供されるトークンは必ず無効にしてください。アップグレードとダウングレードの購入の処理については、アップグレード、ダウングレード、再登録をご覧ください。

DEFERRED 交換モードの場合、アプリは PurchasesUpdatedListener に対する呼び出し、元の定期購入プランの購入、アップグレードまたはダウングレードが正常に処理されたかどうかを示すステータスを受け取ります。交換が有効になるまで、BillingClient.queryPurchasesAsync() は引き続き元の定期購入プランに従って購入を返します。新しいプランが有効になると、queryPurchasesAsync() は新しい定期購入の購入データを返し、安全なバックエンド サーバーに SUBSCRIPTION_RENEWED 通知が送信されます。DEFERRED 交換の場合は、この通知をリッスンし、Purchases.subscriptions:acknowledge を使用して購入を承認することを強くおすすめします。定期購入リソースの linkedPurchaseToken を使用して、定期購入バックエンドのどのユーザー(該当する場合)を新しい利用権で更新する必要があるかを判断できます。プランの変更が有効になってから 3 日以内にユーザーがアプリを開かない可能性があるため、ユーザーがアプリを開いて BillingClient.acknowledgePurchase() を通じて承認することを前提にすべきではありません。

無料試用またはお試し価格でのアップグレード

無料試用の利用資格の設定は、ユーザーがアップグレードまたはダウングレードするときに適用されます。Google Play Console で無料試用の利用資格の設定を調整できます。

次の点にご注意ください。

  • ユーザーがアプリで利用できるすべての定期購入において無料試用を 1 回しか利用できない場合、変更したプランには無料試用やお試し価格が適用されません。
  • 定期購入アイテムごとに 1 回の無料試用を提供する場合、ユーザーが変更するプランには無料試用またはお試し価格が適用されます。

次の表に、新しいプランと以前のプランの両方に無料試用があり、ユーザーが無料試用中にアップグレードする場合の各比例配分モードの動作を示します。

アプリごとに 1 回の無料試用 定期購入アイテムごとに 1 回の無料試用
IMMEDIATE_WITH_TIME_PRORATION ユーザーは直ちに無料試用を失います。残りの無料試用期間は、価格差に基づいて新しい階層の無料期間に換算されます。 ユーザーは以前の無料試用を失いますが、すぐに新しい無料試用が開始されます。また、以前の階層の残りの無料試用期間は、新しい階層と同等の無料期間に変換され、新しい無料試用期間に追加されます。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE

ユーザーは直ちに無料試用を失います。ユーザーには残りの期間の差額が請求されます。次回の請求日は変更されません。

注: このオプションは、時間単位の料金が引き上げられる定期購入のアップグレードでのみ利用できます。

IMMEDIATE_WITHOUT_PRORATION このユーザーはすぐに新しい階層にアップグレードされます。以前の請求対象期間が終了するまで、新しい階層への無料試用のアクセス権は保持されます。
DEFERRED ユーザーは次回の請求日まで、以前の定期購入の無料試用を利用できます。
IMMEDIATE_AND_CHARGE_FULL_PRICE ユーザーは直ちに無料試用を失います。新しい定期購入の料金がユーザーに課金されます。次回の請求日は、新しい定期購入の期間に無料試用の残りの期間を加えた日付です。

アプリごとに 1 回の無料試用でデフォルトの無料試用の移行がどのように行われるかについては、次のシナリオをご覧ください。

あるユーザーが「Country Gardener」というアプリのオンライン コンテンツを定期購入しているとします。現在は、そのコンテンツの Tier 1(テキストのみ)バージョンを月次定期購入しています。月額は 1,000 円で、4 月 1 日に定期購入しました。初回の定期購入で 30 日間の無料試用を利用しているため、5 月 1 日に初めて支払いが行われます。

4 月 15 日に、Tier 2(動画のアップデートを含む)の定期購入にアップグレードすることにしました。月額は 2,000 円になります。この 2 回目の定期購入でも 30 日間の試用期間が有効です。

以下に、各比例配分モードの無料試用の移行方法を示します。

  • IMMEDIATE_WITH_TIME_PRORATION - ユーザーは直ちに Tier 2 にアップグレードされます。ユーザーが定期購入期間が半分経過した時点でアップグレードしたため、定期購入の半月分(1,000 円/月の 15 日分)が新しい定期購入に適用されます。ただし、新しい定期購入は月額が 2,000 円のため、残りの 15 日分の残額は 7.5 日分になります。ユーザーがさらに Tier 2 の無料試用を利用できる場合は、4 月 22 日より月額 2,000 円が課金されます。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE - このモードは、Tier 2 の定期購入の単位時間あたり価格(2,000 円/月)が、Tier 1 の定期購入の単位時間あたり価格(1,000 円/月)よりも大きいために使用できます。ユーザーの Tier 1 の定期購入が Tier 2 に直ちにアップグレードされ、ユーザーは無料試用を失います。次回の請求日は 5 月 1 日であるため、4 月の後半分として本日 1,000 円が請求されます。その後、5 月 1 日から毎月 2,000 円が課金されます。
  • IMMEDIATE_WITHOUT_PRORATION - ユーザーの Tier 1 定期購入は直ちに Tier 2 にアップグレードされます。ユーザーは 4 月 30 日まで無料試用を保持し、Tier 2 のコンテンツにアクセスできます。5 月 1 日以降、毎月 2,000 円が課金されます。
  • DEFERRED - ユーザーの Tier 1 定期購入は、次回のお支払い日である 5 月 1 日まで継続します。5 月 1 日に Tier 2 定期購入が有効になり、毎月 1 日に 2,000 円が課金されます。
  • IMMEDIATE_AND_CHARGE_FULL_PRICE - ユーザーの Tier 1 定期購入は直ちに Tier 2 にアップグレードされ、ユーザーは無料試用を失います。その日に 2,000 円が課金されます。無料試用期間が 15 日残っているため、次回の請求日は 1 か月に加えてその日から 15 日後、つまり 7 月 1 日になります。7 月 1 日以降は毎月 2,000 円が課金されます。

次のリストは、デベロッパーが定期購入ごとに 1 回の無料試用を許可している場合の移行がどのように行われるかを示しています。

  • IMMEDIATE_WITH_TIME_PRORATION - ユーザーは直ちに Tier 2 にアップグレードされます。ユーザーが定期購入期間が半分経過した時点でアップグレードしたため、定期購入の半月分(1,000 円/月の 15 日分)が新しい定期購入に適用されます。ただし、新しい定期購入は月額が 2,000 円のため、残りの 15 日分の残額は 7.5 日分になります。ユーザーは Tier 2 の無料試用を利用できるため、さらに 37.5 日間は課金されません。5 月 22 日以降、毎月 2,000 円が課金されます。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE - このモードは、Tier 2 の定期購入の単位時間あたり価格(2,000 円/月)が、Tier 1 の定期購入の単位時間あたり価格(1,000 円/月)よりも大きいために使用できます。ユーザーの Tier 1 の定期購入が Tier 2 に直ちにアップグレードされ、ユーザーは無料試用を失います。次回の請求日は 5 月 1 日であるため、4 月の後半分として本日 1,000 円が請求されます。その後、5 月 1 日から毎月 2,000 円が課金されます。
  • IMMEDIATE_WITHOUT_PRORATION - ユーザーの Tier 1 定期購入は直ちに Tier 2 にアップグレードされます。ユーザーは 4 月 30 日まで無料試用を保持し、Tier 2 にアクセスできます。
  • DEFERRED - ユーザーの Tier 1 定期購入は、次回のお支払い日である 5 月 1 日まで継続します。5 月 1 日に Tier 2 定期購入が有効になり、毎月 1 日に 2,000 円が課金されます。
  • IMMEDIATE_AND_CHARGE_FULL_PRICE - ユーザーの Tier 1 定期購入は直ちに Tier 2 にアップグレードされ、ユーザーは無料試用を失います。その日に 2,000 円が課金されます。無料試用期間が 15 日残っているため、次回の請求日は 1 か月に加えてその日から 15 日後、つまり 7 月 1 日になります。7 月 1 日以降は毎月 2,000 円が課金されます。

比例配分に関する推奨事項

次の表に、さまざまな比例配分のシナリオと、各シナリオでの推奨事項を示します。

シナリオ 推奨される比例配分モード 結果
より高額な階層へのアップグレード IMMEDIATE_AND_CHARGE_PRORATED_PRICE ユーザーは、同じ請求対象期間を維持しながら、直ちにアクセスできるようになります。
安価な階層へのダウングレード DEFERRED ユーザーはすでにより高額な階層で支払い済みであるため、次の請求日までアクセスが継続されます。
同じ階層での契約期間の変更(月単位から年単位など) DEFERRED ユーザーは次回の請求日に新しい料金を支払います。
無料試用期間中のアップグレード IMMEDIATE_WITHOUT_PRORATION ユーザーは無料試用の利用権を保持し、試用期間の残りの期間は上位階層にアップグレードされます。
無料試用期間中のアップグレード - 無料試用へのアクセスの終了 IMMEDIATE_AND_CHARGE_PRORATED_PRICE ユーザーはすぐに新しい階層にアクセスできますが、無料試用期間は終了します。

顧客管理

リアルタイム デベロッパー通知を使用すると、ユーザーの解約をリアルタイムに検出できます。定期購入が期限切れになる前にユーザーが解約した場合は、ユーザーにプッシュ通知またはアプリ内メッセージを送信して、再度定期購入するように促すことができます。

ユーザーが定期購入を解約した後、アプリ内または Play ストアでユーザーの再獲得を試みることができます。次の表に、さまざまな定期購入のシナリオ、および関連する再獲得のための操作とアプリの要件を示します。

定期購入の有効期限前 定期購入の有効期限後
アプリ内 Play ストア内 アプリ内 Play ストア内
再獲得機能 アプリ内定期購入 再開 アプリ内定期購入 再度定期購入
ユーザーが購入手続きを行う ×
ユーザーの定期購入は同一の SKU に関連付けられた状態を保持する ユーザーは同一または異なる SKU に登録できる ユーザーは同一または異なる SKU に登録できる
新しい購入トークンを作成する ×
デフォルトで有効 × ○すべてのデベロッパーがサポートを必要とする ×

Billing Library 2.0 以降を使用しないアプリ: ×

Billing Library 2.0 以降を使用するアプリ: ○デベロッパーは Console でオプトアウトできる

ユーザーに請求が行われた場合

同一の SKU を使用する場合: 現在の請求対象期間の終了

異なる SKU を使用する場合: 比例配分モードによって異なる

現在の請求対象期間の終了 すぐに すぐに
実装が必要 アプリに再登録 UI を表示する

定期購入のステータスの変化を検出する

Play ストアへのディープリンク

アプリに再登録 UI を表示する アプリ外購入を処理する

定期購入の有効期限前 - アプリ内

定期購入が解約済みであっても有効期限が切れていない場合は、新規の定期購入者と同じアプリ内のアイテム購入フローを適用すると、定期購入者はアプリ内で定期購入を再開できるようになります。UI がユーザーに既存の定期購入がある状態を反映していることを確認します。たとえば、ユーザーの現在の有効期限と再開価格とともに [再有効化] ボタンを表示することが考えられます。

ほとんどの場合は、次のように、ユーザーが定期購入に登録していた時点と同一の価格と SKU をユーザーに提示する必要があります。

  • 同一の SKU で新規の定期購入の購入を開始します。
  • 新しい定期購入は、以前の定期購入に代わって同じ有効期限で更新されます。古い定期購入は直ちに期限切れとしてマークされます。
  • たとえば、あるユーザーが「Example Music App」というアプリを定期購入していたとします。定期購入の有効期限は 8 月 1 日です。7 月 10 日に、同じ月額で 1 か月分再度定期購入するとします。新しい定期購入は残りのクレジットに基づいて比例配分され、すぐに有効になり、8 月 1 日に更新されます。

別の価格(たとえば、新しい無料試用や再獲得割引)を提示する場合は、ユーザーに異なる SKU を提示できます。

  • 比例配分モード IMMEDIATE_WITHOUT_PRORATION を使用して、異なる SKU でアップグレードまたはダウングレードを開始します。
  • 新しい定期購入は、以前の定期購入に代わって同じ有効期限で更新されます。元の有効期限日に、新しい SKU の価格(お試し価格を含む)がユーザーに課金されます。難読化されたアカウント ID を使用して以前の定期購入を作成した場合は、アップグレードとダウングレードのために同じ ID を BillingFlowParams に渡す必要があります。
  • たとえば、あるユーザーが「Example Music App」というアプリを定期購入していたとします。定期購入の有効期限は 8 月 1 日です。7 月 10 日に、お試し価格で 1 年分再度定期購入するとします。新しい定期購入は直ちにアクティブになり、ユーザーに対して 8 月 1 日にお試し価格が請求されます。
  • 無料試用またはお試し価格を再獲得用 SKU に含める場合は、Google Play Console で、アプリごとの無料試用を 1 回に制限する [Allow one free trial per app] チェックボックスをオフにして、ユーザーを対象に含めます。

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

定期購入の有効期限前 - Play ストア内

解約済みであっても定期購入が有効である間は、ユーザーは Google Play 定期購入センターで [再度定期購入](以前の [再開])をクリックすることで、定期購入を再開できます。それにより、同じ定期購入と購入トークンが維持されます。

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

定期購入の再開の詳細については、再開をご覧ください。

定期購入の有効期限後 - アプリ内

有効期限が切れた定期購入者がアプリ内で再度定期購入できるようにするには、新規の定期購入者と同じアプリ内のアイテム購入フローを適用します。次の点にご注意ください。

  • ユーザーに割引を適用するには、特別価格を設定した定期購入用のアイテム ID を提供する必要があります。これは再獲得用 SKU とも呼ばれます。この特典はアプリで提供することも、メールなどアプリ以外の方法でユーザーに通知することもできます。
  • 再獲得用の定期購入を開始するには、Google Play Billing Library を使用して、Android アプリ内で購入フローを開始します。これは新しい定期購入と同じプロセスですが、デベロッパーは、ユーザーが利用できる SKU を決定できます。
  • 無料試用またはお試し価格を再獲得用 SKU に含める場合は、Google Play Console で、アプリごとの無料試用を 1 回に制限する [Allow one free trial per app] チェックボックスをオフにして、ユーザーを対象に含めます。
  • 同じ SKU に再登録した場合、ユーザーは無料試用期間やお試し価格の対象ではなくなります。UI がこれを反映していることを確認します。

購入トークンを受け取ったら、新しい定期購入の場合と同様に購入を処理します。定期購入リソースで linkedPurchaseToken を受け取ることはありません。

定期購入の有効期限後 - Play ストア内

再登録が有効になっている場合、ユーザーは Google Play 定期購入センターで [再度定期購入] をクリックすることで、有効期限から最長 1 年間同じ SKU に再登録できます。それにより、新しい定期購入と購入トークンが生成されます。

解約済みと期限切れの定期購入が [再度定期購入] ボタンおよび [削除] ボタンとともに表示された Google Play ストア アプリの [定期購入] セクション
図 9. Google Play ストア アプリの [アカウント] > [定期購入] セクション(解約済みと期限切れの定期購入が [再度定期購入] ボタンおよび [削除] ボタンとともに表示されている)。

再度定期購入はアプリ外での購入と見なされるため、アプリ外で行われた購入の処理のおすすめの方法を実施してください。

定期購入を宣伝する

プロモーション コードを作成して、既存の定期購入の無料試用の延長特典を特定のユーザーに提供できます。詳細については、プロモーション コードをご覧ください。

無料試用の場合、Google Play は、無料試用期間が始まる前に、ユーザーが有効な支払い方法を設定しているかどうかを確認します。ユーザーによっては、この確認が支払い方法に対する保留または請求として表示されることがあります。この保留または請求は一時的なものであり、後で取り消されるか払い戻されます。

試用期間後は、ユーザーのお支払い方法に対して正規の定期購入価格が請求されます。

ユーザーが無料試用中に定期購入を解約した場合、試用期間が終了するまで定期購入は継続され、無料試用期間が終了しても請求は発生しません。

解約、払い戻し、取り消し

Google Play Developer API を使用して、定期購入の解約払い戻し取り消しができます。この機能は Google Play Console でも利用できます。

  • 解約: ユーザーは Google Play で定期購入を解約できます。アプリまたはウェブサイトでユーザーが解約できるオプションを用意することもできます。アプリでは取り消しの説明に沿って、これらの解約を処理する必要があります。
  • 払い戻し: 払い戻しを行った後も、ユーザーは引き続き定期購入を利用できます。払い戻しは、たとえば、技術的なエラーによってユーザーがアイテムにアクセスできなかったものの、エラーが解決された場合に行うことができます。最新のお支払い額を超える金額を払い戻す場合、または一部払い戻しを行う場合は、Google Play Console を使用する必要があります。
  • 取り消し: 取り消しを行うと、ユーザーは直ちに定期購入を利用できなくなります。取り消しは、たとえば、技術的なエラーによってユーザーがアイテムにアクセスできなくなり、ユーザーがアイテムを使用し続けることを望まない場合に行うことができます。アプリでは取り消しの説明に沿って、これらの解約を処理する必要があります。

次の表に、解約、払い戻し、取り消しの違いを示します。

更新を停止する 料金を払い戻す アクセス権を取り消す
解約 × ×
払い戻し × ×
取り消し

定期購入者の課金を延期する

Google Play Developer API の Purchases.subscriptions:defer を使用すると、自動更新される定期購入の次回の課金日を延期できます。延期期間中、ユーザーは完全なアクセス権で定期購入コンテンツを利用できますが、課金はされません。定期購入の更新日は、新しい日付で更新されます。

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

課金を延期することで、次のことが可能になります。

  • 特別優待の一環として、映画の購入について 1 週間の無料期間を設けるなど、無料アクセス権を付与する。
  • 感謝の印としてユーザーに無料アクセス権を付与する。

課金の延期は、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 日です。

延期した場合は、メールまたはアプリ内で請求日が変更されたことをユーザーに通知することもできます。

支払い方法の不承認を処理する

請求期間の終わりにお支払い方法に関する問題が発生した場合、Google は解約までの一定の期間、定期購入の更新を定期的に試みます。 更新を試みる期間は最大 30 日間で、猶予期間が指定されている場合は、さらにその期間が加えられます。この間、Google はお支払い方法を更新するよう求めるメールと通知もユーザーに送信します。

お支払い方法が不承認となった時点で、猶予期間が有効であれば、定期購入はまずその猶予期間に入ります。猶予期間中も、ユーザーが定期購入にアクセスできるようにする必要があります。

猶予期間が終了すると、定期購入は最大 30 日間のアカウントの一時停止期間に入ります。アカウントの一時停止期間中は、定期購入へのアクセスをブロックできます。

お支払い方法が不承認となっている間に定期購入が再開される可能性を最大限に高めるよう、お支払いに関する問題があることをユーザーに伝えて修正を求めることができます。

これは、猶予期間アカウントの一時停止のセクションに記載されているように、デベロッパー自身で行えます。また、In-App Messaging API を実装し、Google がアプリでユーザーにメッセージを表示することもできます。

アプリ内メッセージング

InAppMessageCategoryId.TRANSACTIONAL で In-App Messaging を有効にした場合は、Google Play が猶予期間とアカウントの一時停止期間中に 1 日に 1 回、ユーザーにメッセージを表示し、アプリを終了せずにお支払い方法を修正する機会をユーザーに提供します。

お支払い方法を修正するようユーザーに伝えるスナックバー
図 20. お支払い方法を修正するようユーザーに伝えるスナックバー

ユーザーがアプリを開くたびにこの API を呼び出し、メッセージを表示するかどうかを指定することをおすすめします。

ユーザーが定期購入を再開すると、SUBSCRIPTION_STATUS_UPDATED のレスポンス コードが購入トークンと一緒に返されます。この購入トークンを使用して Google Play Developer API を呼び出し、アプリで定期購入のステータスを更新します。

In-App Messaging を統合する

アプリ内メッセージをユーザーに表示するには、BillingClient.showInAppMessages() を使用します。

以下に、In-App Messaging のフローをトリガーする例を示します。

Kotlin

val inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build()

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        object : InAppMessageResponseListener() {
            override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) {
                if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        })

Java

InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build();

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        new InAppMessageResponseListener() {
            @Override
            public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) {
                if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        });