Androidアプリに価格帯別の定期購入アイテムを統合する方法
アプリのコードを更新する前に、アプリ内に定期購入型アイテムを別々のSKUとして作成してください。アプリ内課金(IAP)アイテムを設定する手順については、価格帯別の定期購入型アイテムを開発者コンソールでセットアップする方法を参照してください。定期購入型アイテムの変更リクエストを使用すると、アプリに価格帯別の定期購入型アイテムを実装できます。
定期購入型アイテムの変更リクエスト
この実装プロセスは、Amazonアプリストアのアプリ内課金(IAP)のpurchase()メソッドを使用する場合と同様です。purchase()メソッドの詳細については、PurchasingServiceを参照してください。
purchase()メソッドを呼び出すと、Appstore SDKによってonPurchaseResponse()コールバックが呼び出されます。同様に、modifySubscription()メソッドを呼び出すと、Appstore SDKによってonModifySubscriptionResponse()コールバックが呼び出されます。
購入リクエストと定期購入型アイテムの変更リクエストの主な違いは次のとおりです。
modifySubscription()メソッドは、リクエスト内でProrationModeパラメーターとSKUパラメーターを受け取りますが、purchase()メソッドはSKUのみを受け取ります。ProrationModeパラメーターは、プランの変更がいつ有効になるかを指定します。ModifySubscriptionResponseオブジェクトでは複数のレシートが使用されるのに対し、PurchaseResponseオブジェクトで使用されるレシートは1つだけです。
modifySubscription()メソッドは、現在のユーザーの定期購入型アイテムを特定し、新しい期間SKUで更新します。定期購入型アイテムの変更リクエストに渡すSKUは、ユーザーの移行先の期間SKUです。リクエストに渡すProrationModeは、IMMEDIATEまたはDEFERREDという値を持つ列挙型で、変更がいつ有効になるかを指定します。ModifySubscriptionResponseオブジェクトは、プランの変更に関連付けられている一連のレシートを提供します。
modifySubscription()メソッドで使用できるのは期間SKUのみです。定期購入型アイテムの比例配分モードの変更
定期購入型アイテムの比例配分モードは、ProrationMode列挙型で設定します。このセクションでは、ProrationModeに指定できる2つの値、IMMEDIATEとDEFERREDについて詳しく説明します。
比例配分の即時(Immediate)モード
ProrationModeをIMMEDIATEに設定すると、ユーザーの現在の定期購入プランが終了し、新しいプランが即座に有効となります。終了した定期購入プランの残りの期間分は返金となり、ユーザーは新しい定期購入プランで課金されます。また、ユーザーには、以前のプランの返金額と新しいプランの詳細を明記したEメールが送信されます。
現行のプランは返金額が日割り計算されて終了し、新しいプランが別の注文で開始されるため、このレスポンスには次の2つのレシートが含まれます。
- 対象となる定期購入の最後の有効なレシート(以前の定期購入プランの終了を確認したキャンセル日が記載されています)
- 変更後のプランの新しいレシート
ユーザーが支払いを済ませたアイテムを即座に提供するには、両方のレシートを処理する必要があります。
即時(Immediate)のサンプルレスポンス
この例では、期間SkuXから期間SkuYへの切り替えが即時に実施されます。購入日は1月16日です。元のSkuXは1月2日に購入されています。このシナリオでは、以下の内容のメッセージがAmazonから返されます。
receipts: [{
"receiptId": "oeUY1ip2mJWgLoOuGtAxndQS1LDJRGvmKLr6kq4u9G8=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 16 09:25:25 GMT+05:30 2020",
"termSku": "SkuY"
}, {
"receiptId": "1bxFJrJVLPr8qpub8SijMWdAqXqWWGNUYPDpynoSusE=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 02 12:41:44 GMT+05:30 2020",
"endDate": "Thu Jan 16 09:25:26 GMT+05:30 2020",
"termSku": "SkuX"
}]
比例配分の繰延(Deferred)モード
ProrationModeをDEFERREDに設定すると、予定された更新日時に定期購入プランが切り替わります。更新までは、ユーザーは現行のプランを引き続き利用できます。新しいプランの料金は、更新時に請求されます。また、ユーザーには、繰延(Deferred)定期購入の詳細と変更予定日を記したEメールが送信されます。
以前の定期購入プランは終了せず効力が持続するため、Modify Subscriptionのレスポンスには有効なレシートのみが含まれます。このレシートには、繰延期間のSKUと繰延日が記載されます。指定された日付に、このレシートのデータを使用して検証を行い、新しいプランへのアクセスを提供する必要があります。レシートIDは更新後も同じく有効ですが、最新の定期購入情報で更新されます。
繰延(Deferred)のサンプルレスポンス
この例では、SkuAからSkuBへの期間変更が、deferredDateで指定された更新日時に実施されます。
receipts: [{
"receiptId": "oeUY1ip2mJWgLoOuGtAxndQS1LDJRGvmKLr6kq4u9G9=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 16 10:25:25 GMT+05:30 2020",
"deferredDate": "Thu Jan 23 10:25:26 GMT+05:30 2020",
"deferredSku": "SkuA",
"termSku": "SkuB"
}]
定期購入型アイテムの変更の実装
以下のコード例は、定期購入型アイテムの変更リクエストとレスポンスをアプリ内で適切に処理する方法を示しています。
サンプルリクエスト
RequestId requestId = PurchasingService.modifySubscription("SKU", ProrationMode);
レスポンスの例
onModifySubscriptionResponse()メソッドは、定期購入型アイテムの変更リクエストからのレスポンスを処理します。このメソッドは、getRequestStatus()を使用してModifySubscriptionResponse.RequestStatus変数にステータスを格納します。そのステータスに応じて、getReceipts()でレシートを出力するか、エラーを処理します。
@Override
public void onModifySubscriptionResponse(ModifySubscriptionResponse response) {
final String requestId = response.getRequestId().toString();
final String userId = response.getUserData().getUserId();
final ModifySubscriptionResponse.RequestStatus status = response.getRequestStatus();
Log.d(TAG, "onModifySubscriptionResponse: requestId (" + requestId
+ ") userId ("
+ userId
+ ") modifySubscriptionRequestStatus ("
+ status
+ ")");
Log.d(TAG, "ModifySubscriptionResponse " + response.toString());
switch (status) {
case SUCCESSFUL:
for(Receipt receipt : response.getReceipts()) {
Log.d(TAG, "onModifySubscriptionResponse: JSON形式のレシート:" + receipt.toJSON());
iapManager.handleReceipt(response.getRequestId().toString(), receipt, response.getUserData());
}
break;
case INVALID_SKU:
Log.d(TAG,
"onModifySubscriptionResponse: SKUが無効です。購入ボタンは、onProductDataResponseによって既に無効にされています。");
break;
case FAILED:
case NOT_SUPPORTED:
Log.d(TAG, "onModifySubscriptionResponse: 失敗しました。ローカルストレージから購入リクエストを削除してください。");
iapManager.purchaseFailed(response.getRequestId().toString());
break;
}
}
Last updated: 2025年4月7日

