2013年5月29日水曜日

Amazon App Store In-App Purchasing API (アプリ内課金) の実装 #2

Amazon App Store In-App Purchasing API (アプリ内課金) の実装 #1 のつづき。
#1にて BasePurchasingObserver を継承したサブクラスまで記載したので、今度は PurchasingManager を使って実際に課金を行う処理について。

Purchasing Manager

  • In-App Purchasing API と情報をやりとりする重要なクラスです。Amazon Clientおよび Amazon Platform との間のアクセスを容易にします。
  • Purchasing Managerを使用するには、 #1で示したBasePurchasingObserverクラスを継承したサブクラスをPurchasing Managerへ登録する必要があります。アプリのActivityの onStart()メソッドで登録を行うのがベターです。

PurchasingManagerには以下の5つのメソッドがあります。
  1. registerObserver(PurchasingObserver purchasingObserver)
    • BasePurchasingObserver クラスを継承したサブクラスを PurchasingManager へ登録します。
    • 通常、Activity の onStart() メソッドにて呼出します。
  2. initiateGetUserIdRequest()
    • Amazon Client に現在ログインしているユーザーのアプリ特有IDの取得リクエストを送信します。
    • 通常、Activity の onStart() メソッドにて呼出しますが、いつでも取得できます。
  3. initiatePurchaseUpdatesRequest(Offset offset)
    • オフセットレシート情報のページ区分)指定されたレシート情報を取得するリクエストを送信します。
    • ここで返されるレシート情報は、Entitled Content(買い切り型コンテンツ)及び Subscription Content(期間購入型コンテンツ)のみで、Consumable Content(消費型コンテンツ)情報は取得できません。
    • デバイス間でユーザー購入情報を同期する処理に使用できます。
  4. initiateItemDataRequest(Set skus)
    • 指定されたSKU一連のアイテムデータを取得するリクエストを送信します。
    • コンテンツタイプ全てのアイテム情報を取得できます。
  5. initiatePurchaseRequest(String sku)
    • 指定されたSKUの購入リクエストを送信します。
      ※購入リクエストを行った後 Amazon Clientによって表示される購入ダイアログで購入ボタンをタップしない限り購入されません。
    • コンテンツタイプ全てのアイテムを購入できます。

PurchasingManagerを使う準備

 各所で記述していますが、PurchasingManagerを使用してアプリ内課金関連処理を行う前に最初にPurchasingManagerに対してコールバックさせる為のObserverを登録する必要があります。
@Override
protected void onStart() {
.
.
.
    // BasePurchasingObserverを継承して作成したサブクラスのインスタンスを取得
    IapObserver iapObserver = new IapObserver (this);

    // PurchasingManagerへObserverを登録する。
    com.amazon.inapp.purchasing.PurchasingManager.registerObserver(iapObserver);
.
.
.
}

アプリ特有IDの取得

 IAP-APIの課金では、Amazon ClientにログインしているユーザーIDに対して、そのアプリで使用する課金用のユーザーIDを使って管理を行います。

処理の手順は...
  1. PurchasingManager.initiateGetUserIdRequest()でユーザーID取得リクエストを行う。
  2. ObserverのonGetUserIdResponse(GetUserIdResponse getUserIdResponse)メソッドへコールバックする。
  3. 非同期処理でレスポンスオブジェクトからリクエストのステータス、ユーザーIDを取得してアプリで永続化する。

以下に、PurchasingManagerのユーザー取得リクエストメソッドと該当するObserverのメソッドを記述します。
Observerのより具体的な処理サンプルは #1のObserverサンプルコードを参照してください。
@Override
protected void onStart() {
.
.
.
// ユーザーID取得リクエストを行う
com.amazon.inapp.purchasing.PurchasingManager.initiateGetUserIdRequest();
.
.
.
}

@Override
public void onGetUserIdResponse(GetUserIdResponse getUserIdResponse) {
    // 非同期処理でレスポンスオブジェクトを検証
    new GetUserIdAsyncTask().execute(getUserIdResponse);
}

private class GetUserIdAsyncTask extends AsyncTask
{
    // onGetUserIdResponseで取得したGetUserIdResponseを格納
    GetUserIdResponse getUserIdResponse = params[0];
    
    if (getUserIdResponse.getUserIdRequestStatus() == GetUserIdRequestStatus.SUCCESSFUL) {
        // リクエスト成功。レスポンスからユーザーID取得
        Log.d(TAG, "UserID:" + getUserIdResponse.getUserId());
        // 永続化処理
        .
        .
        .
    } else {
        // リクエスト失敗
        .
        .
        .
    }
}

アイテムの購入処理

 やっと本題のアプリ内課金の購入処理についてです。実際の購入よる課金等の処理は全てIAP-APIが行ってくれるので、アプリ側で実装する内容は、購入情報(レシート)を検証して、その課金アイテムやコンテンツ・機能を使えるようにしてあげるというというものです。
 ストアに登録する商用アプリの場合は上記の他にも、購入権利をローカルに保持して不正が無い様定期的に権限を確認させる機能やマルチユーザー対応、消費型アイテム・コンテンツの管理、デバイス間同期処理を呼ぶ...などなど様々な前後処理が必要になります。しかし、ここではシンプルに購入 → 購入成功ダイアログ表示 までの処理を説明していきます。

※尚、Amazon Developer Portalでの課金アイテムの作り方や、SDKTesterの使い方・登録するJsonファイルなどについては触れません。この辺は別の記事に書いていこうと思います。

処理の手順は...
  1. PurchasingManager.initiatePurchaseRequest("購入アイテムのSKU")でアイテム購入リクエストを行う。
  2. Amazon Clientにて購入ダイアログが表示され、ユーザーが購入ボタンをタップするとIAP-APIで課金処理が行われる。
  3. ObserverのonPurchaseResponse(PurchaseResponse purchaseResponse)メソッドへコールバックする。
  4. 非同期処理でレスポンスオブジェクトからリクエストのステータス、コンテンツタイプなどのレシート情報を検証して課金コンテンツ・機能を利用可能にする。

以下に、PurchasingManagerの購入リクエストメソッドと該当するObserverのメソッドを記述します。
Observerのより具体的な処理サンプルは #1のObserverサンプルコードを参照してください。
// アイテムの購入リクエストを送信する。このリクエスト時にはリクエストIDが返り、
// コールバック後のレスポンスオブジェクトに含まれるリクエストIDと突き合わすことにより
// どのリクエストのレスポンスなのか判断する事ができる。
String requestId = com.amazon.inapp.purchasing.PurchasingManager.initiatePurchaseRequest("購入アイテムのSKU");

@Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
    new PurchaseAsyncTask().execute(purchaseResponse);
}

private class PurchaseAsyncTask extends AsyncTask {
    @Override
    protected Boolean doInBackground(PurchaseResponse... params) {
        // レシート検証処理
        .
        .
        .
    }
}

 非同期処理とUIスレッドの同期については、アプリによって色々な方法があると思いますので細かく触れませんが、私はCountDownLatchで同期させたりしてました。

上記に示した通り、IAP-APIを使うのはかなり簡単です。
PlayStoreの課金処理 (IAB-API v2とか特に)を実装した人ならIAP-APIの方が楽だと思います。

0 件のコメント:

コメントを投稿