このトピックでは、更新や有効期限など、定期購入のライフサイクル イベントを処理する方法について説明します。また、プロモーションの提供やユーザーによる定期購入の管理など、その他の定期購入機能についても説明します。
このトピックを読む前に、Google Play Billing Library をアプリに統合して、アプリ内のアイテムの販売と管理に関する一般的な手順をご確認ください。
アプリの定期購入アイテムを構成していない場合は、アイテムを作成して構成するをご覧ください。
定期購入の概要
定期購入は、指定された期間にユーザーが利用できる特典のセットを表します。たとえば、定期購入により、ユーザーは音楽ストリーミング サービスの利用資格を獲得できます。
同じアプリ内に複数の定期購入を設定して、異なる特典セットや、単一の特典セットの異なる階層(シルバー階層、ゴールド階層など)を提供できます。
基本プランと特典を使用して、同じ定期購入アイテムについて複数の構成を作成できます。たとえば、アプリを定期購入したことがないユーザーを対象とするお試し特典を作成できます。同様に、すでに定期購入しているユーザーを対象とするアップグレード特典を作成できます。
定期購入アイテム、基本プラン、特典の詳細については、Google Play Console ヘルプセンターのドキュメントをご覧ください。
定期購入ライフサイクルの処理
定期購入のステータスはライフサイクルを通してさまざまに変化するので、アプリは個々の変化に対応する必要があります。アプリで定期購入のステータスを確認するには、Google Play Billing Library の BillingClient.queryPurchasesAsync()
または Google Play Developer API の Purchases.subscriptionsv2:get
を使用して照会します。
BillingClient.queryPurchasesAsync() |
Purchases.subscriptionsv2:get |
|||||
ステータス | Is returned? | isAutoRenewing | Is returned? | expiryTime | subscriptionState | autoRenewing |
有効 | ○ | True | ○ | 将来 | SUBSCRIPTION_STATE_ACTIVE |
True |
解約済み | ○ | False | ○ | 将来 | SUBSCRIPTION_STATE_CANCELED |
False |
猶予期間中 | ○ | True | ○ | 将来(猶予期間の終了時) | SUBSCRIPTION_STATE_IN_GRACE_PERIOD |
True |
保留中 | × | なし | ○ | 過去(想定される有効期間の終了時、または猶予期間が存在する場合は猶予期間の終了時) | SUBSCRIPTION_STATE_ON_HOLD |
True |
一時停止 | × | なし | ○ | 過去 | SUBSCRIPTION_STATE_PAUSED |
True |
期限切れ | × | なし | ○ | 過去 | SUBSCRIPTION_STATE_EXPIRED |
False |
定期購入のステータスが安全なバックエンド サーバーに保存されている場合は、リアルタイム デベロッパー通知を使用してステータス変更をリッスンし、ステータスを常に同期しておく必要があります。更新や解約など、定期購入のステータスに影響するイベントに対しては、SubscriptionNotification
が送信されます。
アプリで処理する必要があるステータスの変更については、以降のセクションで説明します。
新しい定期購入
新しい購入の処理の推奨事項に沿うようにしてください。定期購入が購入されると、BillingClient.queryPurchasesAsync()
によって定期購入が返され、SUBSCRIPTION_PURCHASED
タイプの SubscriptionNotification
通知が送信されます。この通知を受け取った場合は、Google Play Developer API に照会して最新の定期購入のステータスを取得する必要があります。定期購入リソースは次の例のようになります。デベロッパーが購入を承認するまで、リソースの acknowledgementState
は ACKNOWLEDGEMENT_STATE_PENDING
になることに注意してください。
{
"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
}
}
],
}
更新
正常に更新されると、定期購入は引き続き BillingClient.queryPurchasesAsync()
によって返されます。
定期購入が更新されると 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
}
}
]
}
有効期限
定期購入の有効期限が切れると、BillingClient.queryPurchasesAsync()
で定期購入が返されなくなり、ユーザーは定期購入にアクセスできなくなります。
定期購入の有効期限が切れた場合には、SUBSCRIPTION_EXPIRED
タイプの SubscriptionNotification
も送信されます。この通知を受け取った場合は、Google Play Developer API に照会して最新の定期購入のステータスを取得する必要があります。定期購入リソースは次のようになります。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time_in_past,
...
}
],
}
解約
ユーザーは、自主的に Play ストアから定期購入を解約する、またはアカウントの一時停止後に再開を希望しない場合には自動的に定期購入を解約できます。定期購入を解約したユーザーは、現在の請求期間が終了するまでコンテンツにアクセスできます。請求期間が終了すると、アクセスできなくなります。
定期購入が解約されても期限切れでない場合は、BillingClient.queryPurchasesAsync()
から返されます。定期購入を解約すると、SUBSCRIPTION_CANCELED
通知がトリガーされます。この通知を受け取った場合、Google Play Developer API から返された定期購入リソースには "SUBSCRIPTION_STATE_CANCELED" に設定された subscriptionState
が含まれ、expiryTime
にはユーザーが定期購入にアクセスできなくなる日付が含まれます。expiryTime
が過去である場合、ユーザーは直ちに利用権を失います。過去でない場合、ユーザーは期限切れになるまで利用権を保持します。定期購入リソースは次のようになります。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time,
...
}
],
}
アプリは Google Play Developer API から返された定期購入リソース内の cancelReason
を確認することで、定期購入が解約された理由(お客様の解約、請求に関する問題など)を知ることができます。ユーザーが定期購入を解約した場合は、cancelSurveyResult
フィールドで、定期購入が解約された理由を確認できます。
アプリには、「定期購入は _somedate に期限切れになります」のように、定期購入が解約されたことをユーザーに通知するメッセージを表示できます。またアプリには、ユーザーが定期購入を再開できるように、Google Play ストアへのディープリンクを設定することもできます。
このメッセージを表示する場合は、ユーザーがメッセージを常に非表示にできるようにする必要もあります。
また解約に関するメッセージは、ユーザーに不快感を与える可能性があります。支払い方法が期限切れになって解約になったのではなく、ユーザー自身の手で定期購入を解約している場合は特にそうです。自主的に定期購入を解約したユーザーには、通知を表示しないことをおすすめします。
取り消し
定期購入は、Purchases.subscriptions:revoke
を使用した定期購入の取り消しやチャージバックなど、さまざまな理由でユーザーから取り消される場合があります。そのような場合、アプリではユーザーの利用権を直ちに取り消す必要があります。取り消された定期購入は BillingClient.queryPurchasesAsync()
から返されなくなります。この場合は、SUBSCRIPTION_REVOKED
タイプの SubscriptionNotification
も送信されます。この通知を受け取った場合、Google Play Developer API から返された定期購入リソースには "SUBSCRIPTION_STATE_EXPIRED"
に設定された subscriptionState
が含まれ、expiryTime
にはユーザーが定期購入にアクセスできなくなる日付が含まれます。定期購入リソースは次のようになります。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": expiration_time,
...
}
],
}
アカウントの一時停止
アカウントの一時停止は、ユーザーのお支払い方法で支払いができず、解決されないまま関連する猶予期間が終了した場合に開始される定期購入のステータスです。定期購入のステータスがアカウントの一時停止になった場合は、コンテンツやサービスへのアクセスをブロックする必要があります。アカウントの一時停止期間は最大 30 日間です。
アカウントの一時停止中は、BillingClient.queryPurchasesAsync()
から定期購入が返されません。
アカウントの一時停止中は、必要に応じて定期購入の解約、再開、再購入を処理します。
ユーザーのアカウントが一時停止になった場合は、リアルタイム デベロッパー通知を活用して、定期購入へのアクセスが停止された理由をユーザーに通知します。アプリ内に、支払い方法を修正して定期購入に再びアクセスするための方法を記載したメッセージを表示します。ユーザーが支払い方法を修正できるように、Google Play の定期購入の設定へのリンクをメッセージ内に記載する必要があります。たとえば次のようなメッセージを使用します。
"There is a problem with your subscription. Click here to go to the
Google Play subscription settings to fix your payment method."
ユーザーがアプリ外の定期購入コンテンツにアクセスできる場合は、定期購入がアクティブでなくなったことを知らせるためにプッシュ通知またはメールをユーザーに送信することをおすすめします。
お客様が支払いに関する問題を解決できたら、定期購入が再開されたことをユーザーに知らせるメッセージをアプリ内に表示できます。たとえば次のようなメッセージを使用します。
"Your form of payment was updated, and your subscription has
been recovered."
リアルタイム デベロッパー通知を使用すると、定期購入でアカウントが一時停止になったときに、SUBSCRIPTION_ON_HOLD
タイプの SubscriptionNotification
を受け取ります。定期購入の最新情報を取得するには、安全なバックエンド サーバーから Google Play Developer API を呼び出します。アカウントの一時停止中、定期購入リソースの expiryTime
は過去のタイムスタンプに設定されます。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_past,
...
}
],
}
ユーザーが支払い方法を修正して定期購入がアクティブな状態に戻った場合は、定期購入されたコンテンツへのアクセスを復元する必要があります。
ユーザーが定期購入の対象かどうかをアプリが queryPurchasesAsync()
のみに基づいて判断している場合、アプリはアカウントの一時停止から再開する定期購入を自動的に処理します。
アプリが定期購入のステータスをサーバーと同期している場合は、SUBSCRIPTION_RECOVERED
タイプの SubscriptionNotification
をリッスンし、定期購入が再開されたときに通知されるようにする必要があります。これにより、ユーザーはアクセス権を再取得できます。この通知を受け取った後に定期購入を照会すると、expiryTime
は将来のタイムスタンプに設定されています。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date,
...
}
],
}
アカウントの一時停止期間が終了する前にユーザーが支払い方法を修正しなかった場合は、SUBSCRIPTION_CANCELED
リアルタイム デベロッパー通知が届きます。解約の処理手順については、定期購入の解約をご覧ください。このようにして解約された定期購入を照会すると、返される expiryTime
は過去のタイムスタンプに設定されています。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_past,
...
}
],
}
アカウントの一時停止中のアクセスと再開
次の例は、定期購入のステータスが「アカウントの一時停止」になり、ユーザーがお支払い方法を修正して定期購入が再開されるまでのタイムラインを示しています。
このタイムラインは前の例と同様に、「アカウントの一時停止」になる前の猶予期間に入った定期購入を表しています。
次の点に注意してください。
- 猶予期間中、ユーザーは定期購入の特典に引き続きアクセスできます。
- 定期購入のステータスが「アカウントの一時停止」になる前に、Google はお支払い方法に対する請求を追加で最大 24 時間試みます。この期間中、ユーザーは定期購入の特典を引き続き利用できます。この再試行期間が終了すると、定期購入のステータスが「アカウントの一時停止」になり、ユーザーは定期購入の特典にアクセスできなくなります。
- 猶予期間中に定期購入が再開された場合、更新日はリセットされません。
- 定期購入が「アカウントの一時停止」から回復すると、更新日はリセットされます。
猶予期間
猶予期間を有効にすると、請求期間の終了時に支払いの問題がある場合、定期購入は猶予期間に入ります。この期間中でも、Google Play で定期購入の更新が試行されている間は、ユーザーが定期購入にアクセスできるようにする必要があります。猶予期間の長さは、Google Play Console のアプリ内アイテムの設定で指定できます。
ユーザーが定期購入の対象かどうかをアプリが queryPurchasesAsync()
のみに基づいて確認している場合、解約された購入を queryPurchasesAsync()
が引き続き有効期限までは返すため、アプリは猶予期間を自動的に処理します。
アプリが定期購入のステータスをバックエンドと同期している場合は、SUBSCRIPTION_IN_GRACE_PERIOD
タイプの SubscriptionNotification
をリッスンし、ユーザーが猶予期間に入ったときに通知されるようにする必要があります。ユーザーが猶予期間中の場合、定期購入リソースには autoRenewEnabled = true
が含まれます。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": timestamp_in_future,
"autoRenewingPlan": {
"autoRenewEnabled": true
}
}
],
}
ユーザーが猶予期間に入った場合には、支払い方法の修正方法をユーザーに知らせるメッセージをアプリ内に表示します。支払い方法を修正しないと、猶予期間が終了したときに、ユーザーは定期購入にアクセスできなくなります。ユーザーが定期購入を管理できるように、このメッセージには Google Play ストアへのディープリンクを設定できます。
ユーザーが支払い方法を修正すると定期購入が更新され、アプリが更新の説明に沿って更新を処理できるようになります。
猶予期間中にユーザーがお支払い方法を修正しなかった場合、定期購入のステータスはアカウントの一時停止になります。
アカウントの一時停止がない場合の猶予期間中のアクセスと復元
次の例は、定期購入が猶予期間に入り、ユーザーがお支払い方法を修正して定期購入が再開されるまでのタイムラインを示しています。この例では、定期購入はアカウントの一時停止に対応していないため、猶予期間が終了すると、ユーザーは定期購入の特典を失うことになります。
次の点に注意してください。
- 猶予期間中、ユーザーは定期購入の特典に引き続きアクセスできます。
- 猶予期間中に定期購入が再開された場合、更新日はリセットされません。
一時停止中の定期購入
ユーザーが定期購入を一時停止できるようにすることで、自主的な解約を防ぐことができます。一時停止機能を有効にすると、契約期間の間隔に応じて、ユーザーは 1 週間から 3 か月の間、定期購入を一時停止できます。一時停止機能を有効にすると、定期購入センターと解約フローの両方に表示されます。年間定期購入は一時停止できません。1 週間や 3 か月の一時停止期限は、随時変更される可能性があります。
ユーザーが定期購入を一時停止できるようにする手順は次のとおりです。
- Google Play Console にログインします。
- アプリを選択して、[ストアでの表示] > [アプリ内アイテム] > [定期購入] に移動します。
- [定期購入の設定] を展開します。
- [一時停止を有効にする] チェックボックスをオンにします。
定期購入の一時停止が有効になるのは、現在の請求対象期間が終了した後に限られます。定期購入が一時停止している間、ユーザーは定期購入にアクセスできません。一時停止期間が終了すると、定期購入が再開され、Google は定期購入の更新を試みます。正常に再開できれば、定期購入が再びアクティブになります。支払いに関する問題で再開できなかった場合、図 1 に示すように、ユーザーはアカウント一時停止状態になります。

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

ユーザーの定期購入が一時停止されている場合、queryPurchasesAsync()
は定期購入を返しません。定期購入が再開されると、queryPurchasesAsync()
によって定期購入が返されます。
アプリが定期購入のステータスを安全なバックエンド サーバーと同期している場合は、ステータスを維持するためにリアルタイム デベロッパー通知をリッスンする必要があります。これらの通知により、定期購入が一時停止になってアクセスできないことを、アプリ内でユーザーに通知することもできます。また、Google Play へのディープリンクを使用して、ユーザーが手動で定期購入を再開する方法を提供する必要もあります。
SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED
タイプの SubscriptionNotification
は、ユーザーが定期購入の一時停止を開始したときに送信されます。ユーザーはこの時点で、定期購入に対するアクセス権を保持している必要があります。定期購入リソースには、autoRenewing = true
、paymentState = 1
(支払いが受領済み)、さらに expiryTime
と autoResumeTimeMillis
の将来の値が含まれます。
一時停止が有効になると、SUBSCRIPTION_PAUSED
タイプの SubscriptionNotification
が送信されます。ユーザーはこの時点で、定期購入を利用できなくなります。定期購入リソースには、autoRenewing = true
、paymentState = 0
(保留中)、autoResumeTimeMillis
の将来の値、expiryTime
の過去の値が含まれます。
SUBSCRIPTION_RENEWED
タイプの SubscriptionNotification
は、一時停止期間の終了時に定期購入が自動的に再開された場合、またはユーザーが手動で定期購入を再開した場合に送信されます。これは、更新に記載されているとおりに処理する必要があります。
定期購入の再開の試行時に支払いが失敗した場合は、SUBSCRIPTION_ON_HOLD
タイプの SubscriptionNotification
が送信されます。これは、アカウントの一時停止セクションに記載されているとおりに処理する必要があります。
再開
解約された定期購入は、有効期限まで Play ストア アプリに表示されたままになります。ユーザーは、Google Play ストア アプリ内の [定期購入] セクションで [再度定期購入](以前の [再開])をクリックすることにより、有効期限が切れるまでは解約した定期購入を再開できます。また、[再度定期購入] オプションを使って設定することにより、有効期限が切れた後で自動更新の基本プランをユーザーが再度定期購入できるようにすることも可能です。
![解約済みの定期購入が [再度定期購入] ボタンとともに表示された Google Play ストア アプリの [定期購入] セクション](https://developer.android.com/static/images/google/play/billing/resubscribe.jpg?authuser=1&hl=ja)
有効期限が切れる前の再開
ユーザーが定期購入の対象かどうかをアプリが queryPurchasesAsync()
のみに基づいて判断している場合、解約された購入を queryPurchasesAsync()
が引き続き有効期限までは返すため、アプリは再開を自動的に処理します。再開された定期購入は、解約されなかった場合と同様に引き続き更新されます。
アプリが定期購入のステータスをバックエンドと同期している場合は、SUBSCRIPTION_RESTARTED
タイプの SubscriptionNotification
をリッスンする必要があります。アプリは受け取った通知に応答し、定期購入が更新されるように設定されたことを記録して、再開に関するメッセージがアプリ内で表示されないようにできます。定期購入リソースは次のようになります。
{
"kind": "androidpublisher#subscriptionPurchaseV2",
...
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
...
"lineItems": [
{
"productId": "sub_variant_plan01",
"expiryTime": next_renewal_date
...
}
],
}
有効期限が切れた後の再度定期購入
有効期限が切れた後の再度定期購入ができるように定期購入商品が設定されている場合、ユーザーが Play ストア アプリから購入を開始する可能性があります。この場合、Google Play は新規の購入トークンを発行し、バックエンドは SUBSCRIPTION_PURCHASED
リアルタイム デベロッパー通知を受け取ります。このタイプの購入の購入ステータスには linkedPurchaseToken
が含まれません。また、完全に期限が切れているため、このケースで元の購入に関連付けられている難読化されたアカウント ID も含まれません。
有効期限が切れた後で再度定期購入するには、ユーザーはアプリを開く必要があります。デベロッパーは、このタイプの購入を他のアプリ外で行われた購入と同じ方法で処理することになります。
アップグレード、ダウングレード、再登録
ユーザーがアプリからアップグレード、ダウングレード、または定期購入の有効期限前の再登録を行うと、以前の定期購入は無効になり、新しい購入トークンで新しい定期購入が作成されます。
さらに、Google Play Developer API から返される定期購入リソースには、ユーザーがアップグレード、ダウングレード、または再度定期購入を行った、以前の購入を示す linkedPurchaseToken
が含まれます。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
}
}
],
}
プリペイド プランの統合
プリペイド プランは、有効期限が切れても自動的に更新されません。ユーザーが定期購入の利用資格を中断なしで延長するには、同じ定期購入にプリペイド プランをチャージする必要があります。
チャージするには、元の購入の場合と同様に請求フローを開始します。購入がチャージであることを示す必要はありません。
プリペイド プランのチャージでは常に IMMEDIATE_AND_CHARGE_FULL_PRICE
比例配分モードが使用されるため、このモードを明示的に設定する必要はありません。ユーザーは直ちに請求対象期間の全額を請求され、チャージで指定した期間について利用資格が延長されます。
チャージされると、最新のチャージ購入を反映するために、Purchase
結果オブジェクトの以下のフィールドが更新されます。
- 注文 ID
- 購入時間
- 署名
- 購入トークン
- 承認済み
Purchase
の以下のフィールドには、常に元の購入と同じデータが格納されます。
- パッケージ名
- 購入ステータス
- アイテム
- 自動更新
プリペイド購入の承認
自動更新される定期購入と同様に、デベロッパーはプリペイド プランも購入後に承認する必要があります。初回購入とチャージの両方で承認が必要です。詳細については、購入を処理するをご覧ください。
プリペイド プランの期間が短い可能性があるため、できるだけ早く購入を承認することが重要です。
期間が 1 週間以上のプリペイド プランは、3 日以内に承認する必要があります。
期間が 1 週間未満のプリペイド プランは、プラン期間の半分以内に承認する必要があります。たとえば、3 日間のプリペイド プランの承認期限は 1.5 日間です。
ディープリンクを使用してユーザーが定期購入を管理できるようにする
デベロッパーは、ユーザーが定期購入を簡単に管理できるようにする必要があります。そのため、アプリの設定画面に、ユーザーが定期購入を管理するためのリンクを組み込みます。図 4 に、このリンクの例を示します。
![「定期購入を管理」するリンクの例(画像内の [Google Play Subscriptions] ボタン)。](https://developer.android.com/static/images/google/play/billing/manage-subscription-link_2x.webp?authuser=1&hl=ja)
ユーザーがアプリ内で有効期限内の定期購入を利用している(expiryTime
が将来の日付に設定されているか、autoRenewing
が true
に設定されている)かどうかを判断するロジックを、このリンクのクリック ハンドラに追加します。
各定期購入の 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


定期購入リンクロジックのサンプルコードは、Classy Taxi のサンプルアプリにあります。
ユーザーが定期購入をアップグレード、ダウングレード、変更できるようにする
デベロッパーは基本階層やプレミアム階層など、さまざまな定期購入の階層をユーザーに提供できます。2 つの定期購入の階層を提供する画面を図 7 に示します。

ユーザーが定期購入をアップグレードまたはダウングレードするには、図 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_PRICE
とIMMEDIATE_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 ストア アプリの [定期購入] セクション](https://developer.android.com/static/images/google/play/billing/resubscribe.jpg?authuser=1&hl=ja)
定期購入の再開の詳細については、再開をご覧ください。
定期購入の有効期限後 - アプリ内
有効期限が切れた定期購入者がアプリ内で再度定期購入できるようにするには、新規の定期購入者と同じアプリ内のアイテム購入フローを適用します。次の点にご注意ください。
- ユーザーに割引を適用するには、特別価格を設定した定期購入用のアイテム 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 ストア アプリの [定期購入] セクション](https://developer.android.com/static/images/google/play/billing/resubscribe-remove.jpg?authuser=1&hl=ja)
再度定期購入はアプリ外での購入と見なされるため、アプリ外で行われた購入の処理のおすすめの方法を実施してください。
定期購入を宣伝する
プロモーション コードを作成して、既存の定期購入の無料試用の延長特典を特定のユーザーに提供できます。詳細については、プロモーション コードをご覧ください。
無料試用の場合、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 Play Console を使用して定期購入の価格を変更する方法については、Google Play Console ヘルプセンターのドキュメントをご覧ください。
新規購入の価格変更を管理する
基本プランまたは特典の価格を変更すると、追加の操作を行わなくても、数時間以内にすべての新規購入で新しい価格が有効になります。新規購入には、次のいずれかが該当します。
- 現在、ユーザーがアプリで定期購入を行っていない場合。
- ユーザーがすでに自動更新プランを購入しており、より長い請求対象期間や上位のサービス階層など、別のプランを購入する場合。
- プリペイド プランのユーザーがチャージを購入する場合。
新規購入は、通常の購入と同様に処理する必要があります。
既存の自動更新定期購入プランの購入で価格変更を管理する
自動更新の基本プランの価格は、いつでも変更できます。デフォルトでは、既存の定期購入者は影響を受けません。これらの定期購入者は以前の価格コホートに据え置かれ、更新時も引き続き元の基本プランの価格を支払います。コホートはいつでも終了でき、これらのユーザーを現在の基本プランの価格に移行することが可能です。
同様に、スペシャル オファーや個別の価格フェーズの価格変更も、既存の定期購入者には影響しません。これらの定期購入者は引き続き、定期購入の購入時に表示された価格を支払います。
以前の価格コホートを使用する方法の詳細については、Google Play Console ヘルプセンターをご覧ください。
Google Play Developer API で定期購入の価格を変更する
定期購入の基本プランの価格をプログラムで変更するには、monetization.subscriptions.patch
メソッドを使用します。このメソッドは、変更対象の定期購入アイテム構成を含む Subscription
オブジェクトを受け取ります。新しい価格は、定期購入の basePlans
コレクションに含まれる適切な基本プランの RegionalBasePlanConfig
オブジェクトで設定します。これは、所有する大規模なカタログのすべてのアイテムを短期間で更新する必要がある場合や、変更が発生したときに Google Play 請求サービスの定期購入アイテムに自動的に変更を加える商品カタログ管理システムがある場合に便利です。
Google Play Console で基本プランの価格を変更するには、Google Play Console ヘルプセンターをご覧ください。
以前の価格コホートを終了する
以前の価格コホートを終了すると、自動更新基本プランの以前の料金を支払っているユーザーは、現在の基本プランの価格に移行されます。Google Play Console で以前の価格を終了するには、Google Play Console ヘルプセンターをご覧ください。
Google Play Developer API で以前の価格コホートを終了する
以前の価格コホートをプログラムで終了するには、monetization.subscriptions.basePlans.migratePrices
メソッドを使用します。このメソッドにより、過去の定期購入価格が適用されている定期購入者は、指定された地域の現在の基本プランの価格に移行されます。このメソッドは、指定されたタイムスタンプより前の価格が現在適用されているユーザーに対する価格変更通知の送信をトリガーします。定期購入者が新しい価格に同意しなければ、定期購入は次回の更新の際に終了します。
価格変更が有効になるタイミング
以前の価格コホートを終了すると、該当ユーザーを現在の基本プランの価格に移行するプロセスが開始されます。値上げの場合も値下げの場合も、Google Play は予定されている価格変更を該当ユーザーに通知します。
値下げ
現在の基本プランの価格が以前よりも低い場合、Google Play はメールでユーザーに通知します。ユーザーは、次回の更新日から、値下げされた基本プランの料金を支払います。
値上げ
現在の基本プランの価格が以前よりも高い場合、Google Play はメールとプッシュ通知でユーザーに通知します。ユーザーは、37 日間の事前通知期間を過ぎた後の最初の更新日から、値上げされた料金を請求されます。最初の 7 日間は待機期間で、その後の 30 日間に、ユーザーに通知を送信し始めることができます。
ユーザーは、値上げされた価格で最初に請求される前に、事前通知期間中に Play ストアで新しい価格に同意する必要があります。同意しなければ、Google Play により自動的に定期購入が解約されます。Google Play は、最初の請求の 1 日前と 30 日前に、メールとプッシュ通知でユーザーに通知します。
価格の変更をユーザーに知らせる
基本プランの価格を変更するか以前の価格コホートを終了するときは、必ず既存の定期購入者に通知する必要があります。値上げする場合は、ユーザーに事前通知を送って、値上げに対する同意が必要であることを知らせてください。
定期購入の価格を値上げする場合は、以前のコホートを終了して既存の定期購入者に価格変更を通知してから Google Play が直接通知を開始するまで、少なくとも 7 日間あります。この期間中は、元の価格に戻すことで保留中の値上げを実質的にキャンセルできます。影響を受けるユーザーに対して Google Play より前に通知を送ることもできます。
アプリ内で、影響を受けるユーザーに通知し、ユーザーが新しい価格に簡単に同意できるように、Play ストアの定期購入画面へのディープリンクを提供することをおすすめします。
ユーザーは、図 13 のようなダイアログが表示される Play ストアの定期購入画面で値上げを確認できます。

例
例 1(月単位の定期購入): SuperStreamz は、プレミアム動画ストリーミングの定期購入である SuperStreamz Pro について、3 月 3 日に以前の価格コホートを終了し、価格を値上げします。以前の価格コホート(100 円)のユーザーは、現在の基本プランの価格(200 円)に移行されます。価格変更の発効日は 4 月 9 日(3 月 3 日から 37 日後)です。
- ユーザーはすでに定期購入しており、次回の更新日は 3 月 5 日です。発効日の後の最初の更新日は 5 月 5 日です。したがって、3 月 5 日および 4 月 5 日は元の価格(100 円)で更新されます。5 月 5 日に再度定期購入すると、新しい料金(200 円)が請求されます。Google Play は、4 月 5 日に価格変更の通知を開始します。これは、新しい価格での最初の更新日の 30 日前にあたります。
- ユーザーはすでに定期購入しており、次回の更新日は 3 月 29 日です。3 月 29 日には、価格変更がまだ有効になっていないため、以前の価格(100 円)で更新されます。4 月 29 日に再度更新すると、新しい料金(200 円)が請求されます。最初の価格変更の通知は 3 月 30 日に届きます。これは、新しい価格での最初の更新日の 30 日前にあたります。
例 2(3 か月単位の定期購入): FindMyLove は 3 月 3 日に、FindMyLove Premium の以前の価格コホートを終了し、3 か月間の価格を 100 円から基本プランの価格である 200 円に値上げします。価格変更の発効日は 4 月 9 日(3 月 3 日から 37 日後)です。
- ユーザーはすでに定期購入しており、次回の更新日は 3 月 5 日です。価格変更がまだ有効になっていないため、以前の価格(100 円)で更新されます。6 月 5 日に再度定期購入すると、新しい料金(200 円)が請求されます。最初の価格変更通知は 5 月 6 日に届きます。これは、新しい価格での最初の更新日の 30 日前にあたります。
- ユーザーはすでに定期購入しており、次回の更新日は 4 月 11 日です。4 月 11 日は発効日の後であるため、新しい価格(200 円)で更新されます。最初の価格変更通知は 3 月 12 日に届きます。これは、新しい価格での最初の更新日の 30 日前にあたります。
例 3(週単位の定期購入): CutePetsNews は 3 月 3 日に、Weekly Dog Alerts の以前の価格コホートを終了し、週単位の価格を 100 円から 200 円に値上げします。価格変更の発効日は 4 月 9 日です。
- ユーザーはすでに定期購入しており、次回の更新日は 3 月 6 日です。3 月 6 日、3 月 13 日、3 月 20 日、3 月 27 日、4 月 3 日は、価格変更がまだ有効になっていないため、元の価格(100 円)で更新されます。4 月 10 日に再度更新すると、新しい料金(200 円)が請求されます。最初の価格変更通知は 3 月 11 日に届きます。これは、新しい価格での最初の更新日の 30 日前にあたります。
例 4(月単位の定期購入、複数回の価格変更): この例では、複数回の価格変更がどのように処理されるかを示します。
SuperStreamz は 3 月 3 日に、プレミアム動画ストリーミングの定期購入である SuperStreamz Pro の価格を、月額 100 円から 200 円に値上げします。3 月 10 日には 2 回目の価格変更を行い、月額 300 円に値上げします。
初回の価格変更の発効日は 4 月 9 日(3 月 3 日から 37 日後)です。2 回目の価格変更の発効日は 4 月 16 日(3 月 10 日から 37 日後)です。
- あるユーザーの次回の更新日が 3 月 5 日であるとします。発効日の後の最初の更新日は 5 月 5 日です。したがって、3 月 5 日および 4 月 5 日は元の価格(100 円)で更新されます。5 月 5 日に再度定期購入すると、新しい価格(200 円)が請求されます。価格変更は 7 日間の凍結期間中に行われたため、ユーザーには 2 回目の価格変更に関する通知だけが届きます。最初の価格変更通知は 4 月 5 日に届きます。これは、新しい価格での最初の更新日の 30 日前です。
価格変更に対するユーザーの同意の処理
ユーザーが定期購入の値上げに同意すると、デベロッパーは SUBSCRIPTION_PRICE_CHANGED_CONFIRMED
タイプの SubscriptionNotification
を受け取ります。オプトアウト付きの値下げまたは定期購入の値上げが更新されると、SUBSCRIPTION_RENEWED
タイプの SubscriptionNotification
を受け取ります。この通知は、他の更新と同様に処理する必要があります。
値上げが同意されなかった場合の処理
ユーザーが値上げ価格での更新期日までに値上げに同意しなかった場合、定期購入が自動的に解約され、デベロッパーは SUBSCRIPTION_CANCELED
タイプの SubscriptionNotification
を受け取ります。このイベントは解約の説明に沿って処理できます。
誤った価格変更
定期購入の価格を誤って変更した場合は、すぐに変更を元に戻してください。価格を 7 日以内に元に戻せば、既存の定期購入者に誤った価格変更が通知されることはありません。ただし、最初の価格変更から元に戻すまでの間に、新規の定期購入者に誤った価格の通知が届く可能性があるのでご注意ください。
2 回連続の価格変更の処理
定期購入の価格を 7 日以内に 2 回変更した場合、影響を受けるユーザーは最新の価格変更にのみ同意すれば済みます。たとえば、価格を値上げして以前の価格コホートを終了した後で価格を再度変更した場合は、2 回目の価格変更のみが適用されるようになったため、利用資格を持つユーザーは最初の価格変更に対応する必要がなくなりました。
価格変更は、必ず一度に 1 件ずつ行う必要があります。テスト目的でユーザーの料金を変更しないでください。
お支払い方法の不承認の処理
請求期間の終わりにお支払い方法に関する問題が発生した場合、Google は解約までの一定の期間、定期購入の更新を定期的に試みます。 更新を試みる期間は最大 30 日間で、猶予期間が指定されている場合は、さらにその期間が加えられます。この間、Google はお支払い方法を更新するよう求めるメールと通知もユーザーに送信します。
お支払い方法が不承認となった時点で、猶予期間が有効であれば、定期購入はまずその猶予期間に入ります。猶予期間中も、ユーザーが定期購入にアクセスできるようにする必要があります。
猶予期間が終了すると、定期購入は最大 30 日間のアカウントの一時停止期間に入ります。アカウントの一時停止期間中は、定期購入へのアクセスをブロックできます。
お支払い方法が不承認となっている間に定期購入が再開される可能性を最大限に高めるよう、お支払いに関する問題があることをユーザーに伝えて修正を求めることができます。
これは、猶予期間とアカウントの一時停止のセクションに記載されているように、デベロッパー自身で行えます。また、In-App Messaging API を実装し、Google がアプリでユーザーにメッセージを表示することもできます。
In-App Messaging
InAppMessageCategoryId.TRANSACTIONAL
で In-App Messaging を有効にした場合は、Google Play が猶予期間とアカウントの一時停止期間中に 1 日に 1 回、ユーザーにメッセージを表示し、アプリを終了せずにお支払い方法を修正する機会をユーザーに提供します。

ユーザーがアプリを開くたびにこの 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. } } });