開発者コンソール

アプリ内課金(IAP)アプリのレシート検証

アプリ内課金(IAP)アプリのレシート検証

レシート検証サービス(RVS)を使用すると、アプリのユーザーが行った購入を検証できます。

RVSの概要

次の画像は、レシート検証を使用する購入ワークフローを表しています。RVSは、アプリ内課金(IAP)APIによる購入が完了した後に開始され、購入レシートをアプリに返します。

次の表の手順番号は、上図の引き出し線の番号に対応しています

手順 コンポーネント タスク
1 IAP API IAP APIがユーザーとやり取りして購入を完了します。IAP APIからアプリに購入レシートが返されます。
2 アプリ アプリがアプリサーバーに購入レシートを転送します。
3 アプリサーバー アプリサーバーがRVSサーバーにレシート検証リクエストを送信します。
4 RVSサーバー レシートが有効であることをRVSサーバーが確認します。
5 アプリサーバー アプリサーバーがユーザーに対してコンテンツを利用可能にします。

また、RVSでは、アプリ以外のプラットフォーム(ウェブサイトなど)で購入された定期購入型アイテムへのアクセスを有効にすることもできます。ただし、その購入がAmazonを通じて行われた場合に限ります。このワークフローは次のようになります。

  1. アプリのユーザーが、アプリ提供元のウェブサイトからAmazonを通じて定期購入型アイテムを購入します。
  2. アプリが、購入された定期購入型アイテムのレシートを受け取ります。
  3. アプリがレシートの情報をアプリサーバーに送信します。アプリサーバーがRVSに問い合わせを送信して、このトランザクションを検証します。成功すればアクセスが有効になります。

RVSのセットアップ

RVSには、アプリが開発/テスト段階にあるか、Amazonアプリストアで公開されているかに応じて、2つの環境オプションが用意されています。

  • RVS Cloud Sandbox: アプリの開発中およびテスト中は、RVSサンドボックス環境を使用して、App Testerテストツールで生成されたレシートを検証します。RVS Cloud Sandboxをセットアップするには、RVS Cloud Sandboxの使用を参照してください。
  • RVS本番サーバー: アプリをAmazonアプリストアに公開した後は、Amazon RVS本番サーバーを使用できます。RVS本番環境のセットアップを参照してください。

RVSリクエストの構文

RVSは、PurchaseResponseオブジェクト(英語のみ)またはPurchaseUpdatesResponseオブジェクト(英語のみ)を検証するために使用します。これらのレスポンスオブジェクトから、ユーザーを一意に識別するUserIdを抽出できます。PurchaseResponseオブジェクトにはReceiptIdが含まれています。これをUserIdと共に使用して、サーバー側で購入のアウトオブバンド検証を実行します。アプリサーバーから送信するリクエストには、共有シークレットを渡す必要があります。これによって身元確認が行われ、セキュリティが確保されます。

リクエストの形式は次のとおりです。

<Protocol>//<Server>[/<sandbox>]/version/<Operation_version_number>/verifyReceiptId/developer/<Shared_Secret>/user/<UserId>/receiptId/<ReceiptId>

山かっこで囲まれた用語はリクエストパラメーターです。以下を参考に、検証対象のトランザクションに応じた値に置き換えてください。

  • Protocol: サーバーまたはRVS Sandboxとの通信に使用するプロトコル(httpsなど)。
  • Server: 通信相手となるRVSサーバーのURL。
    • RVS Cloud SandboxサーバーとRVS本番サーバーはどちらも「appstore-sdk.amazon.com」というURLを使用します。
  • sandbox: RVS Cloud Sandboxサーバーを使用している場合は、「sandbox」という値を使用します。RVS本番サーバーを使用している場合は、このパラメーターを省略します。
  • Operation_version_numberverifyReceiptIdオペレーションのバージョン番号。このバージョン番号は、IAPのバージョン番号とは関係ありません。現在のverifyReceiptIdバージョン番号は「1.0」です。
  • Shared_secret: リクエストを発行した開発者を識別するための共有シークレット。共有シークレットは、Amazonアプリストアの開発者アカウントの [共有キー] ページ(https://developer.amazon.com/sdk/shared-key.html)で確認できます。RVSSandboxの場合は、空でない任意の文字列を共有シークレットとして使用できます。
  • UserId: Amazonアプリストアで公開したアプリを使用する個々のAmazonユーザーを表すID (PurchaseResponse.getUserData().getUserId())。
  • ReceiptId: 購入を一意に識別するID (PurchaseResponse.getReceipt().getReceiptId()またはPurchaseUpdatesResponse.getReceipts()Receipt.getReceiptId())。

RVSレスポンスの構文

RVSは、RESTfulなJSON APIインターフェイスを提供します。ベストプラクティスとして、RVSサーバーから返されたJSONレスポンスを読み取るには、JSONパーサークラスを使用することをお勧めします。

トランザクションの検証をリクエストすると、RVSサーバーまたはRVS Sandboxから、リクエストが成功したかどうかを示すレスポンスコードが返されます。成功した場合、JSONレスポンスにはトランザクションに関する情報が含まれています。

以下は、リクエストに成功した場合のレスポンスの例です。

   {
    "autoRenewing":false,
    "betaProduct":false,
    "cancelDate":null,
    "cancelReason":null,
    "freeTrialEndDate":null,
    "fulfillmentDate":null,
    "fulfillmentResult":null,
    "gracePeriodEndDate":null,
    "parentProductId":null,
    "productId":"com.amazon.iapsamplev2.gold_medal",
    "productType":"CONSUMABLE",
    "promotions":null,
    "purchaseDate":1399070221749,
    "purchaseMetadataMap":null,
    "quantity":1,
    "receiptId":"wE1EG1gsEZI9q9UnI5YoZ2OxeoVKPdR5bvPMqyKQq5Y=:1:11",
    "renewalDate":null,
    "term":null,
    "termSku":null,
    "testTransaction":true
    }

RVSのレスポンスコード

レシート検証サービスは、応答として次のいずれかのコードを返します。各コードは、検証チェックの結果を示しています。

レスポンスコード 説明
HTTP 200 成功しました。 レシートID、ユーザーID、共有シークレットがすべて有効です。商品タイプは、 「ENTITLED」(非消費型アイテム)、「CONSUMABLE」(消費型アイテム)、「SUBSCRIPTION」(定期購入型アイテム)のいずれかです。
HTTP 400 このreceiptIdで表されるトランザクションが無効です。または、このreceiptIdに対応するトランザクションが見つかりませんでした。
HTTP 410 このreceiptIdで表されるトランザクションが無効になりました。キャンセルされたレシートとして処理されます。
HTTP 429 リクエストがスロットリングされました。呼び出しの頻度を減らして、しばらくしてから再試行してください。
HTTP 496 sharedSecretが無効です。
HTTP 497 ユーザーIDが無効です。
HTTP 500 内部サーバーエラーが発生しました。

成功したトランザクションのRVSレスポンスフィールド

次の表は、成功したトランザクションのRVSレスポンスに含まれるフィールドとその説明をまとめたものです。

フィールド データ型 説明
autoRenewing ブール型 ユーザーの定期購入が自動更新されるかどうかを示します。
betaProduct ブール型 購入商品がライブアプリテスト商品かどうかを示します。
cancelDate 長整数 購入をキャンセルした日、または定期購入の期限が切れた日。購入がキャンセルされていない場合、このフィールドはnullになります。時間はミリ秒単位です。
cancelReason 整数 商品がキャンセルされた理由を示します。指定できる値は、null、0、1、2です。各整数はキャンセル理由を表します。
null - 購入がキャンセルされていない。
0 - 現時点ではキャンセル理由が特定されていないため、後で表示される。
1 - ユーザーが注文をキャンセルした。
2 - 購入がAmazonのシステムによってキャンセルされた(定期購入型アイテム購入時のユーザーの支払いが無効で、その購入が猶予期間内に完了しなかった場合など)。このコードは、Amazonカスタマーサポートがユーザーのリクエストに応じて注文をキャンセルした場合にも返されます。
freeTrialEndDate 長整数 定期購入が無料トライアル期間中であることを示します。定期購入の無料トライアル期間の終了日をエポック(ミリ秒)単位で提供します。定期購入が無料トライアル期間中でない場合、このフィールドはnullになります。
fulfillmentDate 長整数 定期購入でアイテム付与完了が通知された日付。エポックからのミリ秒数として格納されます。定期購入のアイテム付与が確認されていない場合はnullになります。消費型アイテムと非消費型アイテムでは常にnullです。
fulfillmentResult 文字列 定期購入でのアイテム付与のステータス。有効な値は次のとおりです。
  • FULFILLED: コンテンツを提供し、ユーザーがそのコンテンツを使用しました。
  • UNAVAILABLE: ユーザーにコンテンツを提供できませんでした。
定期購入のアイテム付与が確認されていない場合はnullになります。消費型アイテムと非消費型アイテムでは常にnullです。
gracePeriodEndDate 長整数 定期購入が猶予期間中であることを示します。定期購入の猶予期間の終了日をエポック(ミリ秒)単位で提供します。定期購入が猶予期間中でない場合、このフィールドはnullになります。
parentProductId 文字列 null。将来使用するために予約されています。
productId 文字列 アプリ内でこのアイテムに対して定義したSKU。
productType 文字列 購入された商品の種類。有効な商品タイプは、CONSUMABLE(消費型アイテム)、SUBSCRIPTION(定期購入型アイテム)、ENTITLED(非消費型アイテム)です。
promotions リスト<Promotion> 定期購入型アイテムのプロモーション価格の詳細です。プロモーションがない場合はnullになります。詳細については、RVSのプロモーション価格を参照してください。
purchaseDate 長整数 購入日。エポックからのミリ秒数として格納されます。定期購入型アイテムの場合、purchaseDateは最初の購入日を表します。それ以降の更新日を表すものではありません。
purchaseMetadataMap [マップ] <文字列, 文字列> 購入がクイック定期購入を通じて開始された場合、値は{"QuickSubscribe":true}になります。それ以外の場合はnullになります。
quantity 整数 購入された数量。常にnullまたは1になります。
receiptId 文字列 購入の一意の識別子。
renewalDate 長整数 定期購入型アイテムの更新が必要となる日付。エポックからのミリ秒で計算されます。
term 文字列 定期購入型IAPアイテムの有効期間(期間は購入日から始まります)。数字と期間(日、週、月、年)で構成されます(「1週間」、「2か月」など)。
termSku 文字列 定期購入期間に対応する一意のSKU。
testTransaction ブール型 この購入が、Amazonによる公開・テストプロセスの一部として実行されたものかどうかを示します。

RVSのプロモーション価格

プロモーション価格を設定する方法の詳細については、プロモーション価格の設定を参照してください。ユーザーが定期購入型アイテムをプロモーション価格で購入した場合、RVSから返されるレシートにはプロモーションの詳細が含まれます。前のセクションで説明したJSONレスポンスには、promotionsフィールドが含まれています。このセクションでは、このpromotionsフィールドについて詳しく説明します。プロモーションの詳細は、ユーザーが定期購入型アイテムをプロモーション価格で購入したレシートにのみ表示されます。

レシートに関連付けられたプロモーションがない場合、promotionsフィールドはnullになります。プロモーションが関連付けられている場合は、このフィールドにPromotionオブジェクトのリストが含まれ、次のフィールドも表示されます。

フィールド データ型 説明
promotionType 文字列 プロモーションのタイプ。有効な値は Introductory PricePromotional Priceです。有効な値の説明を参照してください。
promotionStatus 文字列 このユーザーのプロモーションのステータス。有効な値は QueuedInProgressCompletedです。有効な値の説明を参照してください。

例:

"promotions": [
    {
            "promotionType":"Introductory Price - All customers",
            "promotionStatus":"Completed"
    }
]

有効な値の説明

promotionTypeフィールドで有効な値は次のとおりです。

  • Introductory Price - All customers - すべてのユーザー(新規ユーザーおよび休眠ユーザーを含む)に提供される価格。
  • Promotional Price - Lapsed customers - 休眠ユーザーにのみ提供される価格。

promotionStatusフィールドで有効な値は次のとおりです。

  • Queued - ユーザーが定期購入型アイテムをプロモーション価格で購入しました。現在は無料トライアル期間であり、まだプロモーション期間は始まっていません。
  • InProgress - ユーザーは現在、プロモーション価格の期間中です。
  • Completed - ユーザーのプロモーション期間が終了しました。

プロモーション価格に関するよくある質問(FAQ)

Q: ユーザーの定期購入型アイテムのレシートには必ずプロモーションの詳細が表示されているのですか?
いいえ。プロモーションの詳細情報は、定期購入型アイテムをプロモーション価格で購入したレシートにのみ表示されます。
Q: プロモーションの詳細は、レシートがキャンセルされた後も表示されますか?
はい。ユーザーの定期購入がキャンセルされた場合は、プロモーションの詳細がCompletedと表示されます。
Q: ユーザーが無料トライアル中に定期購入型アイテムをキャンセルし、プロモーションプランを更新しなかった場合、プロモーションのステータスはどうなりますか?
ユーザーのプロモーション期間が開始しなかったため、レシートには関連付けられているプロモーションの詳細がありません。

キャンセル日と更新日

renewalDateフィールドには、自動更新される定期購入型アイテムの購入が次に更新される日付が格納されます。このフィールドは、定期購入型アイテムの購入にのみ適用されます。ユーザーが月額制の定期購入型アイテムを所有している場合、その定期購入型アイテムは、初回購入日と同じ日付で毎月更新されます。翌月に同じ日付がない場合は、最も近い前の日付が更新日となります。次に例を示します。

  • ユーザーが1月2日に定期購入型アイテムを購入した場合、次の3か月間の更新日は、2月2日、3月2日、4月2日になります。
  • ユーザーが1月31日に定期購入型アイテムを購入した場合、次の3か月の更新日は、2月28日(うるう年の場合は2月29日)、3月31日、4月30日になります。

cancelDateフィールドには、定期購入型アイテムの購入が期限切れになった日付、またはAmazonカスタマーサービスが購入をキャンセルした日付が格納されます。キャンセル日は、ユーザーがコンテンツにアクセスできなくなった日付を表します。ユーザーが自動更新をオフにして定期購入をキャンセルした場合は、次の更新予定日がキャンセル日となります。

renewalDateフィールドとcancelDateフィールドは、ミリ秒単位の時間として格納されます。この値を日付オブジェクトに変換するには、java.util.Date(timeInMillis)を使用します。

消費型アイテムまたは非消費型アイテムの購入

有効なレシートでは、キャンセル日と更新日はどちらもnull値になります。キャンセル日フィールドがnullでない場合、その値は、Amazonカスタマーサービスが購入をキャンセルした日付を表します。

定期購入型アイテムの購入

有効な定期購入型アイテムのレシートでは、キャンセル日はnullになります。cancelDateフィールドがnullでない場合、その値は、定期購入型アイテムが期限切れになった日付、またはAmazonカスタマーサービスが購入をキャンセルした日付を表します。

renewalDateフィールドには、自動更新される定期購入型アイテムの購入が次に更新される日付が格納されます。自動更新が設定されていない定期購入型アイテムでは、このフィールド値はnullになります。

例として、ユーザーがキャンセルした定期購入型アイテムがあるとします。

  • この定期購入型アイテムは、2016年1月1日から2016年3月1日までアクティブでした。レシートでは、この定期購入型アイテムのpurchaseDateは2016年1月1日に設定され、cancelDateは2016年3月1日に設定されます。
  • この定期購入型アイテムが2016年4月1日に再びアクティブにされた場合、2つ目のレシートが生成されます。2つ目のレシートでは、purchaseDateは2016年4月1日、cancelDateはnullとなります。

RVS SandboxとRVS本番環境の例

レシート検証サービス(RVS)の例を参照してください。


Last updated: 2023年12月6日