こんにちは、コンテンツ・メディア第1事業部の前田です。
業務で自動更新購読型のAppStore課金を取り入れたのですが、AppStoreから返却される自動更新購読レシートの中身がよく分からず行き詰まることがありました。今回は自動更新購読レシートを調べた中で分かった仕様や消耗型・非消耗型レシートとの違い、ユーザの課金状態によってレシートの内容はどう変化するかについて書いていきます。
AppStore自動更新購読のざっくりとした流れ
上図が購入から完了までの流れになります。今回はレシートの内容についてなので詳細には触れません。
この図中にあるAppStoreAPIから返却された検証結果レシートの内容について詳しく見ていきます。
レシート仕様
AppStoreから返却されるレシート例を以下に示します。
レシートパラメータの各値は伏せ字にしておきます。見難いかと思いますがご了承下さい。
※レシートデータの内容はiOSのバージョン毎に異なりますので注意して下さい。
{ "status": ■■■■■■, "environment": "■■■■■■", "receipt": { "receipt_type": "■■■■■■", "adam_id": ■■■■■■, "app_item_id": ■■■■■■, "bundle_id": "■■■■■■", "application_version": "■■■■■■", "download_id": ■■■■■■, "version_external_identifier": ■■■■■■, "receipt_creation_date": "■■■■■■", "receipt_creation_date_ms": "■■■■■■", "receipt_creation_date_pst": "■■■■■■", "request_date": "■■■■■■", "request_date_ms": "■■■■■■", "request_date_pst": "■■■■■■", "original_purchase_date": "■■■■■■", "original_purchase_date_ms": "■■■■■■", "original_purchase_date_pst": "■■■■■■", "original_application_version": "■■■■■■", "in_app": [ { "quantity": "■■■■■■", "product_id": "■■■■■■", "transaction_id": "■■■■■■", "original_transaction_id": "■■■■■■", "purchase_date": "■■■■■■", "purchase_date_ms": "■■■■■■", "purchase_date_pst": "■■■■■■", "original_purchase_date": "■■■■■■", "original_purchase_date_ms": "■■■■■■", "original_purchase_date_pst": "■■■■■■", "expires_date": "■■■■■■", "expires_date_ms": "■■■■■■", "expires_date_pst": "■■■■■■", "web_order_line_item_id": "■■■■■■", "is_trial_period": "■■■■■■" } ] }, "latest_receipt_info": [ { "quantity": "■■■■■■", "product_id": "■■■■■■", "transaction_id": "■■■■■■", "original_transaction_id": "■■■■■■", "purchase_date": "■■■■■■", "purchase_date_ms": "■■■■■■", "purchase_date_pst": "■■■■■■", "original_purchase_date": "■■■■■■", "original_purchase_date_ms": "■■■■■■", "original_purchase_date_pst": "■■■■■■", "expires_date": "■■■■■■", "expires_date_ms": "■■■■■■", "expires_date_pst": "■■■■■■", "web_order_line_item_id": "■■■■■■", "is_trial_period": "■■■■■■" }, ・・・ ], "latest_receipt": "■■■■■■■■■■■■■■■■■■・・・" }
各パラメータ内容
重要なパラメータのみ説明します。
プロパティ | 子プロパティ | 内容 |
status | レシートが正しければ0、異常であれば対応したエラーコードとなる。なお購読の有効期限が切れても0が返る。 | |
receipt | in_app | latest_receiptの詳細となる。下記「in_app~消耗型・非消耗型プロダクトとの違い~」で詳しく説明。 |
latest_receipt_info | 今まで購入した自動更新のレシートがすべて入る。下記「latest_receiptについて」で詳しく説明。 | |
product_id | なんの商品(たとえば1ヶ月購読と半年購読があったりした場合)を判別できるもの。 | |
transaction_id | 購入または更新に対するID。latest_receipt_infoの配列毎に値は異なる。 | |
original_transaction_id | product_idを購読購入したということに対するID。購読購入→一度やめる→また1年後に購入とした場合でも値は同じとなる。下記「original_transaction_idの検証で詳しく説明」 | |
purchase_date | transaction_idに対応した購読開始日時。 | |
original_purchase_date | transaction_idに対応した購読購入した日、または更新した日時。更新というのはApple側が更新をかけた日時であって、購読更新日(この日からまた購読)という日時ではない。 | |
expires_date | transaction_idに対応した購読期限。 | |
cancellation_date | Appleを通してキャンセルされた場合に入る。設定から自動更新オフした場合とかではない。ここに値が入っている場合は有効期限内であっても購入はキャンセルされているので注意。 | |
latest_receipt | 自動更新購読型にのみ存在する。アプリから渡され、レシートデータとしてAppStoreAPIへ渡す。ある購読情報をBase64エンコードしたもの。 |
in_appについて~消耗型・非消耗型プロダクトとの違い~
自動更新購読のレシート構造は消耗型・非消耗型プロダクト(ゲームなどによくあるアイテム課金等)のレシート構造といくつか違いがあります。非消耗型プロダクトのレシートは、in_app
の中に課金したアイテムの情報が入ってきます。ですのでそのとき購入した情報はin_app
を見れば分かるのですが、自動更新購読レシートはそうとは限りません。自動更新購読のin_app
にはlatest_receipt
に紐付く購入情報が入ってきます。latest_receipt
が一番最新の購入情報であればin_app
には最新の購入情報が入りますが、古いlatest_receipt
であればin_app
には古い購入情報が入ってきます。
具体的には下図のようになります。下図では自動更新購読の内容を「一ヶ月の定期購読課金」としています。
latest_receipt_infoについて
latest_receipt_info
は一見すると最新のレシートのみが入ってくるようにみえるのですが、ここにはアプリ内で購入した自動更新のレシート情報が全て入ってきます。一度更新をやめてしばらく経ってから再度購読を開始した場合でも、以前の購読レシートは一緒になって返ってきます。また、アプリ内にプロダクトが複数あり(300円コース、1000円コース等)、かつ両方で課金したことがある場合には両方の情報が入ってきます(下図参照)。
original_transaction_idの検証
以下図にある3つの状態でレシートを取得した際、original_transaction_id
の内容について検証した結果をまとめます。
ここでは、自動更新購読の内容を「一ヶ月の定期購読課金」としています。
①1月1日に購読を開始し、2月、3月も購読を更新している場合
latest_receipt_info
には3ヶ月分の購読情報が入ってくる。また、この3つのoriginal_transaction_id
は全て同じものである。
②1月1日に購読を開始。1月5日に自動更新を解除したが、1月10日に更新解除をやめ、2月、3月と購読した場合
latest_receipt_info
には3ヶ月分の購読情報が入ってくる。また、この3つのoriginal_transaction_id
は全て同じものである。
③1月1日に購読を開始し、1月5日に自動更新を解除。3月1日に購読を開始した場合。
latest_receipt_info
には1月、3月の購読情報が入ってくる。また、この2つのoriginal_transaction_id
は全て同じものである。
つまり、あるアプリ内で自動購読を開始すると、途中で更新解除→再度課金してもoriginal_transaction_id
は全て同じとなります。じゃあどこで月々の購読情報を見分けるの?と言うと、transaction_id
で見分けることができます。パラメータ内容にも書きましたが、transaction_id
には購読が更新される毎に違う値が入ってくるからです。
感想
初めはレシートの中身がややこしすぎて全く分からない…と焦っていたのですが、実際に取得したSandboxのレシートを見てみることによって仕組みを理解することができました。今後自動更新購読を実装する際に参考になればと思います。
参考
自動購読課金について【iOS編】- サイバーエージェント 公式エンジニアブログ
商標について
AppStore、In-App Purchaseは、Apple Inc.の商標です。