連載
» 2011年04月28日 00時00分 公開

Androidでアプリ内課金を始めるための基礎知識Android Marketアプリ内課金サービス徹底解説(1)(2/3 ページ)

[緒方聡,株式会社イーフロー]

アプリ内課金のアーキテクチャ

 アプリ内課金は、アプリとAndroid Marketサーバ間で課金リクエスト課金レスポンスによる通信で成り立ちます。ただし、アプリとAndroid Marketは直接通信をすることはなく、間にAndroid Marketアプリが仲介する形です。

 アプリに必要なのは、Android Marketアプリへのメソッド呼び出しによるプロセス間通信と、Android Marketから送られるブロードキャストインテントのハンドリングです。Androidのサポートするアーキテクチャを駆使することにより、専用APIを必要としないことが特徴です。

図3 アプリ、Android Marketアプリ、Android Marketの関係 図3 アプリ、Android Marketアプリ、Android Marketの関係

 アプリ内課金の典型的な実装は、以下の3つのコンポーネントから構成されます。

  1. ユーザーの購入メッセージを処理し、課金リクエストをAndroid Marketアプリに送信するサービス
  2. Android Marketアプリから非同期に送信されるブロードキャストインテントを受信するブロードキャストレシーバ
  3. 署名の検証や“なりすまし”防止などのセキュリティ関連タスクを処理するセキュリティコンポーネント

 また、必要に応じて、以下の2つのコンポーネントを導入するのもよいでしょう。

  1. アプリ固有の購入通知、エラー、その他のメッセージを処理するレスポンスハンドラ
  2. アプリへの購入情報や状態をコールバックすることでユーザーインターフェイス(以下、UI)を更新可能にするオブザーバ

 これらのコンポーネントに加え、アプリはある種のユーザーの購入情報を保存する方法と、購入する商品を選択させるUIを提供しなければなりません。チェックアウトのためのUIはAndroid Marketアプリによって提供されるため、アプリで用意する必要はありません。

 また、アプリによってはコンテンツ配信するためにリモートサーバを使用するかもしれませんが、アプリ内課金としてリモートサーバは必須ではありません。ただし、アプリ内で可能なセキュリティ関連のタスクをリモートサーバで行うことは、アプリをより堅牢にします。

 セキュリティ関連のタスクに関しては、最終回の「設計・実装における8つのセキュリティ対策ポイント」で後述します。

アプリ内課金のメッセージ処理

 アプリ内課金は、いくつかのリクエストとレスポンスから成り立つことは前述しました。ここでは、それらのメッセージの詳細を説明します。

アプリ内課金の5つのリクエスト

 すべてのアプリ内課金リクエストは、Android Marketアプリへのメソッド呼び出しによるプロセス間通信という形で送信されます。このAndroid Marketアプリへのメソッド呼び出しは、「Android Interface Definition LanguageAIDL)」ファイルによって定義されます。

 インターフェイスはキーと値を指定したバンドルを引数に取ります。以下は5つのキーと、その説明です。

  • 【1】Android Marketアプリがアプリ内課金をサポートするか検証「CHECK_BILLING_SUPPORTED

 このリクエストはAndroid Marketアプリがアプリ内課金をサポートするかどうかを検証します。大抵、このリクエストはアプリ開始時に送信されます。

 Android Marketアプリがアプリ内課金に対応していない場合で、もしアプリがアプリ内課金関連だけのユーザーインターフェイスと機能を無効にしたい場合、このリクエストは役に立ちます。

  • 【2】アプリ内アイテムの購入リクエストを送信「REQUEST_PURCHASE

 このリクエストはアプリ内課金で最も重要な、購入情報をAndroid Marketアプリに送信します。

 ユーザーがアプリ内で商品を購入した場合に、アプリはこのリクエストを送信します。Android Marketはその際、チェックアウトのユーザーインターフェイスを表示することで金融取り引きを処理します。

  • 【3】購入または払い戻しのトランザクション情報を受信「GET_PURCHASE_INFORMATION

 このリクエストは購入状態変更の詳細を受信します。購入リクエストが完了した場合、またはユーザーがチェックアウト時に購入をキャンセルした場合に、購入状態は変更されます。以前に購入された商品が払い戻しされることもあり得ます。

 Android Marketはアプリに購入状態の変更を通知し、アプリはそのトランザクション情報を受信するために、このリクエストを送信します。

  • 【4】購入または払い戻しのトランザクション情報を受信したことを通知「CONFIRM_NOTIFICATIONS

 このリクエストは、アプリが購入状態変更の詳細を受信したことを通知します。Android Marketはこのリクエストを受信するまで、アプリに対し購入状態変更通知を送り続けます。

  • 【5】管理された購入のユーザートランザクション履歴を受信「RESTORE_TRANSACTIONS

 このリクエストは「アカウント単位で管理」された購入のためのユーザーのトランザクション情報を受信します。アプリはユーザーのトランザクション状況を受信する必要があるときだけ、このリクエストを送るべきで、それは大抵アプリがインストールまたは再インストールされたときだけです。

アプリ内課金の3つのレスポンス

 Android Marketアプリはアプリ内課金リクエストに同期と非同期の両方でレスポンスを返します。同期レスポンスは以下の3つのキーを持つバンドルです。

  • 【1】リクエストに対するステータス情報とエラー情報「RESPONSE_CODE

 このキーはリクエストに対するステータス情報とエラー情報を提供します。

  • 【2】「PendingIntent」を提供する「PURCHASE_INTENT

 このキーはアプリがチェックアウトのアクティビティを起動するために使用する「PendingIntent」を提供します。

  • 【3】非同期レスポンスを特定可能にする「REQUEST_ID

 このキーは、アプリがリクエストに対する非同期レスポンスを特定可能にするリクエストIDを提供します。

 これらのキーは必ずしもすべてのリクエストに対して返されるものではありません。詳細については後述する「購入リクエストのメッセージシーケンス」を参照してください。また次回記事の「表3 アプリ内課金リクエストタイプで戻されるバンドルキーの詳細」も参照してください。

3つのブロードキャストインテント(非同期レスポンス)

 非同期レスポンスは以下を含むブロードキャストインテントの形式で送信されます。

  • 【1】課金リクエストが成功したかエラーになったか「com.android.vending.billing.RESPONSE_CODE

 このレスポンスはAndroid Marketサーバのレスポンスコードを含み、アプリがアプリ内課金リクエストを作成した後に送られます。サーバレスポンスコードは課金リクエストがAndroid Marketに送信成功したこと、または課金リクエスト中にいくつかのエラーが発生したことを表します。

 このレスポンスは(払い戻しや購入情報などの)購入状態変更通知には利用されません。このレスポンス時に送信されるレスポンスコードの詳細については、「Android Marketサーバレスポンスコード」を参照してください。

  • 【2】購入成功、キャンセル、払い戻し「com.android.vending.billing.IN_APP_NOTIFY

 このレスポンスは購入状態が変更されたこと(購入成功キャンセル払い戻し)を表します。このレスポンスは1つ以上の通知IDを含みます。それぞれの通知IDはサーバ側の特定のメッセージと一致し、それぞれのメッセージは1つ以上のトランザクション情報を含みます。

 アプリがIN_APP_NOTIFYブロードキャストインテントを受信した後、アプリは詳細情報を取得するために通知IDと一緒にGET_PURCHASE_INFORMATIONリクエストを送信します。

  • 【3】トランザクション情報の詳細「com.android.vending.billing.PURCHASE_STATE_CHANGED

 このレスポンスは1つ以上のトランザクション情報の詳細を含みます。トランザクション情報はJSON文字列に含まれます。JSON文字列は署名され、シグネチャは(暗号化されていない)JSON文字列と一緒にアプリに送信されます。アプリ内課金のセキュリティを堅牢にする補助として、アプリはJSON文字列のシグネチャを検証できます。

 PURCHASE_STATE_CHANGEインテントで返されるJSON文字列は1つ以上の課金トランザクションの詳細をアプリに提供します。以下はJSON文字列のサンプルです。

トランザクション情報を含む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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。