アプリ内課金は、アプリとAndroid Marketサーバ間で課金リクエストと課金レスポンスによる通信で成り立ちます。ただし、アプリとAndroid Marketは直接通信をすることはなく、間にAndroid Marketアプリが仲介する形です。
アプリに必要なのは、Android Marketアプリへのメソッド呼び出しによるプロセス間通信と、Android Marketから送られるブロードキャストインテントのハンドリングです。Androidのサポートするアーキテクチャを駆使することにより、専用APIを必要としないことが特徴です。
アプリ内課金の典型的な実装は、以下の3つのコンポーネントから構成されます。
また、必要に応じて、以下の2つのコンポーネントを導入するのもよいでしょう。
これらのコンポーネントに加え、アプリはある種のユーザーの購入情報を保存する方法と、購入する商品を選択させるUIを提供しなければなりません。チェックアウトのためのUIはAndroid Marketアプリによって提供されるため、アプリで用意する必要はありません。
また、アプリによってはコンテンツ配信するためにリモートサーバを使用するかもしれませんが、アプリ内課金としてリモートサーバは必須ではありません。ただし、アプリ内で可能なセキュリティ関連のタスクをリモートサーバで行うことは、アプリをより堅牢にします。
セキュリティ関連のタスクに関しては、最終回の「設計・実装における8つのセキュリティ対策ポイント」で後述します。
アプリ内課金は、いくつかのリクエストとレスポンスから成り立つことは前述しました。ここでは、それらのメッセージの詳細を説明します。
すべてのアプリ内課金リクエストは、Android Marketアプリへのメソッド呼び出しによるプロセス間通信という形で送信されます。このAndroid Marketアプリへのメソッド呼び出しは、「Android Interface Definition Language(AIDL)」ファイルによって定義されます。
インターフェイスはキーと値を指定したバンドルを引数に取ります。以下は5つのキーと、その説明です。
このリクエストはAndroid Marketアプリがアプリ内課金をサポートするかどうかを検証します。大抵、このリクエストはアプリ開始時に送信されます。
Android Marketアプリがアプリ内課金に対応していない場合で、もしアプリがアプリ内課金関連だけのユーザーインターフェイスと機能を無効にしたい場合、このリクエストは役に立ちます。
このリクエストはアプリ内課金で最も重要な、購入情報をAndroid Marketアプリに送信します。
ユーザーがアプリ内で商品を購入した場合に、アプリはこのリクエストを送信します。Android Marketはその際、チェックアウトのユーザーインターフェイスを表示することで金融取り引きを処理します。
このリクエストは購入状態変更の詳細を受信します。購入リクエストが完了した場合、またはユーザーがチェックアウト時に購入をキャンセルした場合に、購入状態は変更されます。以前に購入された商品が払い戻しされることもあり得ます。
Android Marketはアプリに購入状態の変更を通知し、アプリはそのトランザクション情報を受信するために、このリクエストを送信します。
このリクエストは、アプリが購入状態変更の詳細を受信したことを通知します。Android Marketはこのリクエストを受信するまで、アプリに対し購入状態変更通知を送り続けます。
このリクエストは「アカウント単位で管理」された購入のためのユーザーのトランザクション情報を受信します。アプリはユーザーのトランザクション状況を受信する必要があるときだけ、このリクエストを送るべきで、それは大抵アプリがインストールまたは再インストールされたときだけです。
Android Marketアプリはアプリ内課金リクエストに同期と非同期の両方でレスポンスを返します。同期レスポンスは以下の3つのキーを持つバンドルです。
このキーはリクエストに対するステータス情報とエラー情報を提供します。
このキーはアプリがチェックアウトのアクティビティを起動するために使用する「PendingIntent」を提供します。
このキーは、アプリがリクエストに対する非同期レスポンスを特定可能にするリクエストIDを提供します。
これらのキーは必ずしもすべてのリクエストに対して返されるものではありません。詳細については後述する「購入リクエストのメッセージシーケンス」を参照してください。また次回記事の「表3 アプリ内課金リクエストタイプで戻されるバンドルキーの詳細」も参照してください。
非同期レスポンスは以下を含むブロードキャストインテントの形式で送信されます。
このレスポンスはAndroid Marketサーバのレスポンスコードを含み、アプリがアプリ内課金リクエストを作成した後に送られます。サーバレスポンスコードは課金リクエストがAndroid Marketに送信成功したこと、または課金リクエスト中にいくつかのエラーが発生したことを表します。
このレスポンスは(払い戻しや購入情報などの)購入状態変更通知には利用されません。このレスポンス時に送信されるレスポンスコードの詳細については、「Android Marketサーバレスポンスコード」を参照してください。
このレスポンスは購入状態が変更されたこと(購入成功、キャンセル、払い戻し)を表します。このレスポンスは1つ以上の通知IDを含みます。それぞれの通知IDはサーバ側の特定のメッセージと一致し、それぞれのメッセージは1つ以上のトランザクション情報を含みます。
アプリがIN_APP_NOTIFYブロードキャストインテントを受信した後、アプリは詳細情報を取得するために通知IDと一緒にGET_PURCHASE_INFORMATIONリクエストを送信します。
このレスポンスは1つ以上のトランザクション情報の詳細を含みます。トランザクション情報はJSON文字列に含まれます。JSON文字列は署名され、シグネチャは(暗号化されていない)JSON文字列と一緒にアプリに送信されます。アプリ内課金のセキュリティを堅牢にする補助として、アプリはJSON文字列のシグネチャを検証できます。
PURCHASE_STATE_CHANGEインテントで返されるJSON文字列は1つ以上の課金トランザクションの詳細をアプリに提供します。以下はJSON文字列のサンプルです。
{ "nonce" : 1836535032137741465, "orders" : { "notificationId" : "android.test.purchased", "orderId" : "transactionId.android.test.purchased", "packageName" : "com.example.dungeons", "productId" : "android.test.purchased", "developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", "purchaseTime" : 1290114783411, "purchaseState" : 0 } }
JSON文字列のフィールドの詳細情報は、次回の「アプリ内課金ブロードキャストインテント」を参照してください。
次ページでは、より詳細にメッセージの流れを解説し、セキュリティ管理についても説明します。
Copyright © ITmedia, Inc. All Rights Reserved.