アプリ内課金

【Amazonサブスク】本番RVSとサンドボックスを使ってレシート検証する

これまで、Google のアプリ内課金については何度か記事を書いてきましたが、アプリ内課金には他にも Apple や Amazon など種類があります。

今回は、アマゾンサブスクのアプリ内課金(Amazon Inapp Purchase)について調査する機会があったのですが、ドキュメントからは読み取れない部分があり色々と悩まされました。

API リファレンスやレシート検証の方法など、ドキュメントと挙動が異なる部分もありましたので、気になったことを洗い出しておきます。

Google については以下にまとめていますので参考程度に。

【Googleサブスク】レシート検証をPHPとKotlinで実現する前回、GooglePlayBilling(Android)の都度課金についてまとめてみましたが、最近は月額課金のサービスが多くなり、都度...

Amazonのドキュメント

Amazon のアプリ内課金を実装するために、以下のドキュメントが公式サイトに用意されています。

アプリ内課金(IAP)について

アプリ内課金(IAP)APIを使用すると、デジタルコンテンツや定期購入型アイテムの表示、処理、アイテム付与までをアプリ内で行うことができます。Amazonでは、Androidアプリとウェブアプリの両方でIAP APIをサポートしています。

ただ、何年も情報が更新されてなさそうなので、ドキュメントが古いのか、アプリ内課金に新しい機能が追加されていないのかわかりにくいです。

Google は Google I/O、Apple は WWDC などで今後のアプリ内課金のロードマップが公開されています。
(Apple は動画に日本語字幕も付きました)

それと比べると、Amazon のアプリ内課金に対する温度感が低く感じられてしまいますね・・・。

サンドボックス環境

Google や Apple にもテスト用のサンドボックス環境がありましたが、Amazon にも同様のテスト手段が用意されています。

・テスト用のレシート
・テスト用のレシート検証サーバ

ただ、Amazon のサンドボックス向けのレシート検証サーバは、外部にある Amazon のサーバではなく、自前のサーバを用意しなければいけません。

と言っても、war ファイルが提供されているので、それをローカルやクラウド上の Tomcat などで起動すればすぐに使えるという点はありがたいです。

Docker を使う場合は、「tomcat:9.0.16-jre8-alpine」などのイメージを使うと簡単なので、実際に動作確認した Dockerfile のサンプルを紹介しておきます。

ローカルの war ファイルを、サーバ上のドキュメントルートに配備してあげればアプリが起動します。

サンドボックスのメリット

ここでサンドボックス環境の良いところと悪いところに触れておきたいと思います。

良い点は、自前のサーバに配備できるのでプラットフォーム側の負荷を気にしないでいいところです。

本番のレシート検証は秒間 10 リクエストまで許容していると書かれていましたので、サンドボックスでもそこまで捌ければ OK でしょう。

・負荷に合わせてスペック調整できる
・war ファイルが用意されている

サンドボックスのデメリット

悪い点には、致命的な問題が 1 つあって、サブスクのレシートをサンドボックスで検証した際に、「renewalDate」の項目が常に null で返されます。

RVSレスポンスの構文(renewalDate)

定期購入型アイテムの更新が必要となる日付。エポックからのミリ秒で計算されます。

これではサブスクの一連の流れが確認できません・・・。

また、本番環境でレシート検証してみたところ、上記に記載されているレスポンスに存在しない項目が 5 つほどありました。

将来的に使われる拡張項目(猶予とか次の更新タイミングで上位プランに変更など)なのかもしれませんが、購読状態と見受けられる「autoRenewing」の項目はフラグも実際に変動しているので説明は必要でしょう。

・レスポンスのドキュメントが不足している
・renewalDate が常に null

レスポンスの項目についてはサンドボックスに限ったことではありませんが、これだとサンドボックスは使わずに、自前でモックサーバを用意した方が本番に近い状態をエミュレートできそうです。

レシート検証のレスポンスイメージ

あれこれ書いてきましたが、具体的なレシート検証のレスポンスイメージを紹介しておきます。

ドキュメントに記載がなかった項目は以下の 5 つです。

・autoRenewing
・deferredDate
・deferredSku
・freeTrialEndDate
・gracePeriodEndDate

この記事を書いた数日後に 3 項目だけ反映されました。ただ、freeTrialEndDate ではなくて isFreeTrial なんですね。現在も isFreeTrial の項目は存在しなくて、freeTrialEndDate の項目がレスポンスで返ってくるのですが。

September 14, 2020
New data fields added for RVS: autoRenewing, gracePeriodEndDate, and isFreeTrial. For additional information, see Receipt Verification for IAP Apps.

Receipt Verification Service Enhancements

また、以下のページの推奨事項の段落に、レシートの有効期限に関係なく、定期的にキャンセルを確認することが望ましいと書かれています。

IAPのベストプラクティス:ユーザーの購入傾向の追跡

アクティブなレシートごとに72時間以内にRVSを呼び出すプロセスを作成して、キャンセルされたレシートの傾向をモニタリングします。

これにより、autoRenewing の項目が false になったタイミングで、次の有効期限でキャンセルとなるだろうという判断ができますが、管理しているアクティブなレシートが数百個ならまだしも、何万・何十万もある場合は、3 日に 1 回という頻度は現実的ではないですよね。

ちなみにレシートの有効期限を迎えた場合、どのタイミングで「継続更新」または「キャンセル」の状態がレシートに反映されるのか、開発者の立場だと気になるとことだと思います。

こちらは、まだサンプルがそれほど多くないのですが、有効期限を過ぎてから 1 時間以内に切り替わるというイメージで大丈夫そうです。

まとめ

Amazon のアプリ内課金について、気になることを洗い出してみました。

Google や Apple に比べると、利用者側としても開発者側としても関わる頻度は少ないと思います。

ただし、その分、情報やノウハウも不足ガチになるので、今回の記事が少しでも参考になれば幸いです。