典型的な購入リクエストのメッセージシーケンスを図4で示します。それぞれのリクエストタイプは太字で、ブロードキャストインテントは斜体で表示されています。簡単なため、以下すべての図でブロードキャストインテントのRESPONSE_CODEの表示は省略しています。
トランザクションリクエストのやり直しのためのメッセージシーケンスを図5で示します。このシーケンス内のIN_APP_NOTIFYレスポンスのハンドリングに関しては、重要なので後述の「IN_APP_NOTIFYメッセージのハンドリング」で詳しく説明します。
リクエストは3つのレスポンスを引き起こします。最初はRESPONCE_CODEキーとREQUEST_IDキーを持つバンドルです。次は、リクエストについての状態情報またはエラー情報を提供するAndroid MarketアプリのRESPONSE_CODEブロードキャストインテントです。常にRESPONSE_CODEメッセージは特定のリクエストIDを参照するため、アプリはどちらのリクエストにRESPONSE_CODEメッセージが属するかを判断可能です。
RESTORE_TRANSACTIONSリクエストタイプはまた、購入リクエスト送信時と同じトランザクション情報タイプを含むPURCHASE_STATE_CHANGEDブロードキャストインテントを引き起こしますが、CONFIRM_NOTIFICATIONSメッセージのインテントに応答する必要はありません。
アプリ内課金がサポートされるかどうかをチェックするメッセージシーケンスを図6で示します。
RESULT_OKレスポンスコードはアプリ内課金がサポートされていることを示します。RESULT_BILLING_UNAVAILABLEレスポンスコードはアプリ内課金がアプリの指定したAPIバージョンが不正であるか、ユーザーがアプリ内購入を使用できないことを示します。SERVER_ERRORもまた、起こり得ます。これはAndroid Marketサーバの問題であることを示します。
大抵、アプリはREQUEST_PURCHASEメッセージのレスポンス内でAndroid MarketからIN_APP_NOTIFYブロードキャストインテントを受け取ります(図4)。
IN_APP_NOTIFYブロードキャストインテントはアプリにリクエストされた購入情報が変更されたことを通知します。その購入の詳細を取得するために、アプリはGET_PURCHASE_INFORMATIONリクエストを送信します。
Android Marketは購入状態変更の詳細を含むPURCHASE_STATE_CHANGEDブロードキャストインテントをレスポンスします。アプリは購入状態変更情報を受信したことをAndroid Marketに知らせるために、CONFIRM_NOTIFICATIONSメッセージを送信します。
Android MarketはCONFIRM_NOTIFICATIONSメッセージを受け取ったら、大抵IN_APP_NOTIFYインテント送信を停止します。
しかし、アプリがCONFIRM_NOTIFICATIONSメッセージを送ったにもかかわらずAndroid MarketがIN_APP_NOTIFYインテント送信を繰り返し続ける場合があります。アプリがCONFIRM_NOTIFICATIONSメッセージを送信中にデバイスがネットワーク接続を失った場合です。
この場合、Android MarketはアプリのCONFIRM_NOTIFICATIONSメッセージを受け取ってはおらず、アプリが再びIN_APP_NOTIFYメッセージの応答としてCONFIRM_NOTIFICATIONSを返すまで送り続けます。
そのため、アプリはIN_APP_NOTIFYメッセージが過去のトランザクションのものである場合でも認証できるようになっていなければなりません。すべてのトランザクションはユニークなorderIdを持っているので、アプリはJSON文字列に含まれるorderIdを調べることで、これに対応可能です。
アプリがREQUEST_PURCHASEメッセージを送信していないとしても、IN_APP_NOTIFYブロードキャストインテントを受け取るケースが2つあります。図7は、それらのケースを示すメッセージシーケンスです。
最初のケースとして、ユーザーが2つ以上のデバイスにアプリをインストールし、いずれかのデバイスでアプリ内購入を行った場合に、IN_APP_NOTIFYブロードキャストインテントを受け取ります。
このケースでは、Android MarketはIN_APP_NOTIFYメッセージを第2のデバイスにも送信し、アプリに購入状態変更を通知します。アプリはREQUEST_PURCHASEメッセージを開始したアプリからのレスポンスを処理する方法と同様の方法で、このメッセージを処理でき、最終的にはアプリは購入したアイテムの情報を含むPURCHASE_STATE_CHANGEDブロードキャストインテントを受信します。
これは「アカウント単位で管理」購入タイプで購入した商品にのみ適応されます。
アプリが送信したトランザクション情報の完全性を保証する補助として、Android MarketはPURCHASE_STATE_CHANGEDブロードキャストインテントに含まれるJSON文字列に署名をします。
Android Marketは、このシグネチャを作るために開発者アカウントにひも付けられた秘密鍵を使用します。開発者サイトは、それぞれの開発者のためにRSAキーペアを生成します。開発者は自分のアカウントのプロファイルページで、このキーペアの公開鍵を見ることができます。これは、Android Marketライセンスで使用する公開鍵と同じです。
Android Marketは(暗号化されない)JSON文字列とシグネチャに署名し、課金レスポンスを行います。アプリが署名されたレスポンスを受け取ったとき、開発者のRSAキーペアの公開鍵を使用してシグネチャの検証ができます。シグネチャを検証することによって、レスポンスが改ざんされているかどうかを検出する補助になります。
アプリで署名検証ステップを行うこともできますが、もしアプリがセキュアなリモートサーバに接続可能であれば、サーバ内での署名検証を推奨します。
またアプリ内課金は、Android Marketから受け取った購入情報の完全性を検証する補助として「ナンス」(一度だけ使用されるランダムな数値)を使用します。アプリはナンスを作成し、GET_PURCHASE_INFORMATIONリクエストとRESTORE_TRANSACTIONSリクエストでナンスを送信しなければいけません。
Android Marketはリクエストを受け取る際に、ナンスをトランザクション情報に含まれるJSON文字列に追加します。JSON文字列は署名されアプリに戻されます。アプリがJSON文字列を受信したら、JSON文字列のシグネチャと同様にナンスを検証する必要があります。
セキュリティに関しては、最終回の「設計・実装における8つのセキュリティ対策ポイント」も参照してください。
新しく始まったアプリ内課金は、以下のような可能性を秘めています。
これまでは写真集などがそれぞれ単独のアプリになっていましたが、アプリ内課金を使うことで、1つのビューアでいくつものコンテンツを閲覧できるようになります。
ゲーム内のレアアイテムなどを販売できるようになります。アプリ内課金はこのためにある、といっても過言ではないぐらい、アイテム課金との相性が抜群です。
これまでは「xxx Lite」「xxx Free」などの名前で機能制限版や無料版をリリースし、それが気に入ってもらえたら有料版を購入してもらう、という流れでしたが、アプリ内課金を使用することで、同一アプリで有料版の機能をアンロックすることが可能になります。
逆に、使用後1カ月経ったら機能を制限し、課金してもらえた場合には制限を取り除く、というシェアウェアのような販売方法も考えられます。
次回は、アプリ内課金の実装方法とリファレンスについて、詳しく見ていきます。
Copyright © ITmedia, Inc. All Rights Reserved.