【Amazon】定期購入で本番RVSとサンドボックスを使ってレシート検証する
これまで、Google のアプリ内課金については何度か記事を書いてきましたが、アプリ内課金には他にも Apple や Amazon など種類があります。
今回は、アマゾンサブスクのアプリ内課金(Amazon Inapp Purchase)について調査する機会があったのですが、ドキュメントからは読み取れない部分があり色々と悩まされました。
API リファレンスやレシート検証の方法など、ドキュメントと挙動が異なる部分もありましたので、気になったことを洗い出しておきます。
Google については以下にまとめていますので参考程度に。
Amazonのドキュメント
Amazon のアプリ内課金を実装するために、以下のドキュメントが公式サイトに用意されています。
アプリ内課金(IAP)APIを使用すると、デジタルコンテンツや定期購入型アイテムの表示、処理、アイテム付与までをアプリ内で行うことができます。Amazonでは、Androidアプリとウェブアプリの両方でIAP APIをサポートしています。
アプリ内課金(IAP)について
ただ、何年も情報が更新されてなさそうなので、ドキュメントが古いのか、アプリ内課金に新しい機能が追加されていないのかわかりにくいです。
Google は Google I/O、Apple は WWDC などで今後のアプリ内課金のロードマップが公開されています。
(Apple は動画に日本語字幕も付きました)
それと比べると、Amazon のアプリ内課金に対する温度感が低く感じられてしまいますね・・・。
サンドボックス環境
Google や Apple にもテスト用のサンドボックス環境がありましたが、Amazon にも同様のテスト手段が用意されています。
・テスト用のレシート
・テスト用のレシート検証サーバ
ただ、Amazon のサンドボックス向けのレシート検証サーバは、外部にある Amazon のサーバではなく、自前のサーバを用意しなければいけません。
と言っても、war ファイルが提供されているので、それをローカルやクラウド上の Tomcat などで起動すればすぐに使えるという点はありがたいです。
war ファイルは、下記のサイトで提供されている Android SDK に含まれているので、ダウンロードした zip ファイルを解凍して取得してください。
アプリ内課金(IAP)APIを使用すると、デジタルコンテンツや定期購入型アイテムの表示、処理、アイテム付与をアプリ内で行うことができます。
SDKのダウンロード
Docker を使う場合は、「tomcat:9.0.16-jre8-alpine」などのイメージを使うと簡単なので、実際に動作確認した Dockerfile のサンプルを紹介しておきます。
ローカルの war ファイルを、サーバ上のドキュメントルートに配備してあげればアプリが起動します。
FROM tomcat:9.0.16-jre8-alpine
WORKDIR /usr/local/tomcat/webapps
COPY RVSSandbox.war RVSSandbox.war
サンドボックスのメリット
ここでサンドボックス環境の良いところと悪いところに触れておきたいと思います。
良い点は、自前のサーバに配備できるのでプラットフォーム側の負荷を気にしないでいいところです。
本番のレシート検証は秒間 10 リクエストまで許容していると書かれていましたので、サンドボックスでもそこまで捌ければ OK でしょう。
・負荷に合わせてスペック調整できる
・war ファイルが用意されている
サンドボックスのデメリット
悪い点には、致命的な問題が 1 つあって、サブスクのレシートをサンドボックスで検証した際に、「renewalDate」の項目が常に null で返されます。
定期購入型アイテムの更新が必要となる日付。エポックからのミリ秒で計算されます。
RVSレスポンスの構文(renewalDate)
これではサブスクの一連の流れが確認できません・・・。
また、本番環境でレシート検証してみたところ、上記に記載されているレスポンスに存在しない項目が 5 つほどありました。
将来的に使われる拡張項目(猶予とか次の更新タイミングで上位プランに変更など)なのかもしれませんが、購読状態と見受けられる「autoRenewing」の項目はフラグも実際に変動しているので説明は必要でしょう。
レスポンスの項目についてはサンドボックスに限ったことではありませんが、これだとサンドボックスは使わずに、自前でモックサーバを用意した方が本番に近い状態をエミュレートできそうです。
・レスポンスのドキュメントが不足している
・renewalDate が常に null
レシート検証のレスポンスイメージ
あれこれ書いてきましたが、具体的なレシート検証のレスポンスイメージを紹介しておきます。
{
"autoRenewing": false,
"betaProduct": false,
"cancelDate": null,
"deferredDate": null,
"deferredSku": null,
"freeTrialEndDate": null,
"gracePeriodEndDate": null,
"parentProductId": null,
"productId": "xxxxxxxxxx",
"productType": "SUBSCRIPTION",
"purchaseDate": 1598886000000,
"quantity": null,
"receiptId": "xxxxxxxxxx",
"renewalDate": null,
"term": "1 Month",
"termSku": "xxxxxxxxxx",
"testTransaction": false
}
ドキュメントに記載がなかった項目は以下の 5 つです。
・autoRenewing
・deferredDate
・deferredSku
・freeTrialEndDate
・gracePeriodEndDate
ドキュメントに記載がなかった項目(1)
この記事を書いた数日後に 3 項目だけ反映されました。
ただ、freeTrialEndDate ではなくて isFreeTrial なんですね。
現在も isFreeTrial の項目は存在しなくて、freeTrialEndDate の項目がレスポンスで返ってくるのですが。
September 21, 2020
Receipt Verification Service Enhancements
New data fields added for RVS: autoRenewing, gracePeriodEndDate, and isFreeTrial. For additional information, see Receipt Verification for IAP Apps.
ドキュメントに記載がなかった項目(2)
さらに 1 週間後に isFreeTrial 項目の修正が入りました。
やはり、freeTrialEndDate が正しかったようです。
実際に、無料トライアル中のレシートには freeTrialEndDate が設定されてレスポンスされてきます。
term 項目も無料トライアルの期間の設定になっているので、この freeTrialEndDate は正式に採用しても大丈夫そうですね。
September 21, 2020
Receipt Verification Service Enhancements
The data field isFreeTrial is now freeTrialEndDate. freeTrialEndDate provides the end date of a subscription’s free trial period. For additional information, see Receipt Verification for IAP Apps.
ドキュメントに記載がなかった項目(3)
さらに 2020 年 12 月に cancelReason の項目が追加されました。
ユーザの解約理由ではなく、解約に至ったのがユーザのキャンセルなのか、Amazon のシステムのキャンセル(ユーザが猶予期間内に決済不備などで更新できなかった場合)なのかが入ってきます。
December 2, 2020
Receipt Verification Service Enhancements
New data field cancelReason added for RVS. For additional information.
ちなみにドキュメントは、日本語ではなく英語(English)に切り替えないと最新版が確認できないので注意してください。
また、以下のページの推奨事項の段落に、レシートの有効期限に関係なく、定期的にキャンセルを確認することが望ましいと書かれています。
アクティブなレシートごとに72時間以内にRVSを呼び出すプロセスを作成して、キャンセルされたレシートの傾向をモニタリングします。
IAPのベストプラクティス:ユーザーの購入傾向の追跡
これにより、autoRenewing の項目が false になったタイミングで、次の有効期限でキャンセルとなるだろうという判断ができますが、管理しているアクティブなレシートが数百個ならまだしも、何万・何十万もある場合は、3 日に 1 回という頻度は現実的ではないですよね。
ちなみにレシートの有効期限を迎えた場合、どのタイミングで「継続更新」または「キャンセル」の状態がレシートに反映されるのか、開発者の立場だと気になるとことだと思います。
こちらは、まだサンプルがそれほど多くないのですが、有効期限を過ぎてから 1 時間以内に切り替わるというイメージで大丈夫そうです。
まとめ
Amazon のアプリ内課金について、気になることを洗い出してみました。
Google や Apple に比べると、利用者側としても開発者側としても関わる頻度は少ないと思います。
ただし、その分、情報やノウハウも不足ガチになるので、今回の記事が少しでも参考になれば幸いです。