mixi Developer Center (ミクシィ デベロッパーセンター)

mixiアプリ

mixiアプリ » 技術仕様(Graph API方式) » 課金API(mixiポイント決済)

課金API(mixiポイント決済)

android向け課金APIを利用することにより、mixiポイントを使ったアイテム課金をmixiアプリandroid版に組み込むことができます。ここでは、mixiアプリにてandroid向け課金APIをどのように利用して組み込むかを説明いたします。

制限事項

ここで説明するandroid向け課金APIの利用は、mixiより許可されたSAPが開発したmixiアプリのみで利用することができます。その際、SAPは開発するmixiアプリごとに許可を得なければなりません。

利用手順

android向け課金APIは、mixi Platform独自の決済確認フローを実装したAPIです。決済内容を保護するために、mixiアプリから規定のSDKインターフェイスを呼び出すだけ でなく、いくつかバックエンド側(SAP側の外部サーバ上)で行わなければならない処理があります。

事前準備

android向け課金APIでは、通信内容の妥当性検証を行うために、署名の生成や検証を行うことになります。使われる署名は、HMAC-SHA1にて 生成された文字列となります。この際に使用されるキーは、mixiアプリの設定画面(edit_appli.pl)にて表示されるConsumer Secretです。予めこのConsumer Secret文字列をその画面より入手しておきます。

基本的な処理フロー

mixiアプリ内でandroid向け課金APIを利用する際の代表的な処理フローを以下に示します。

android_payment_flow.gif

  1. mixiアプリからバックエンドサーバに決済情報の作成を依頼する
  2. バックエンドサーバにて決済情報を作成し、mixiアプリに返却する
  3. 決済情報を元に、決済のためのAPIを呼び出す
  4. mixiサーバからバックエンドサーバに、ポイントコードが送信される
  5. バックエンドサーバはポイントコードを保持し、mixiサーバに結果を返却する
  6. 決済確認ポップアップ画面が表示される
  7. ユーザが確認を行い、購入を確定する
  8. mixiサーバからバックエンドサーバに、決済処理ステータスが送信される
  9. バックエンドサーバは決済情報を確認後、mixiサーバに結果を返却する
  10. 決済完了ポップアップ画面が表示され、ユーザがそれを消去する
  11. 指定したコールバック関数が呼び出され、結果が渡される

1.アイテム情報のリクエスト

ユーザが何らかのアイテムの購入をmixiアプリ内で希望した際に、最初にmixiアプリからバックエンドサーバに対して、決済情報の作成を依頼します。この時点で、購入対象のアイテムIDが決定します。
以下に、サンプルコードを記載いたします。

HttpClient client= new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://sap_service/get_item.pl?item_id=123");
HttpResponse response = client.execute();
String responseBody = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
JSONObject itemData = new JSONObject(responseBody);
String itemName= itemData.getString("itemName");
String itemId= itemData.getString("itemId");
int itemPrice= itemData.getInt("itemPrice");
boolean isTest= itemData.getBoolean("isTest");
String inventory_code = itemData.getString("inventory_code");
String signature= itemData.getString("signature");

2.アイテム情報の作成

アイテム情報の作成要求を受け取ったバックエンドサーバでは、アイテムIDを元に必要な情報を準備し、それらを元に署名を作成します。これらを結果としてmixiアプリに返却します。
アイテム情報として必要な項目を以下に示します。

項目名 説明
callback_url mixiサーバから呼び出されるバックエンドサーバのURL
inventory_code バックエンドサーバー側でこの決済を特定するためのユニークな任意の文字列
is_test 決済処理のテストの場合は”true”, 実際の決済の場合は”false”
item_id アイテムID
item_price アイテムのポイント数

まず、これらの項目を「&」で連結して、1つの文字列を作成します。その際に、項目名はアルファベット順とします。また、全ての項目値はURIエスケープを行っておきます。

callback_url=http%3A%2F%2Fsap.server.host%2Fcreate_order&inventory_code=123&is_test=true&item_id=123&item_price=500

この文字列に対して、さらに以下の加工を行います。その結果は、上記のパラメータに対する署名となります。

  1. 上記文字列全体をURIエスケープする – (1)
  2. 予め入手したConsumer Secretの末尾に”&”を付与する – (2)
  3. (2)をキーとしてHMAC-SHA1アルゴリズムを使用し、(1)のダイジェスト値を得る – (3)
  4. (3)をBASE64エンコードする

上記のパラメータ値および生成した署名を、mixiアプリに結果として返却します。

※ URIエスケープは、こちら(http://oauth.net/core/1.0a#encoding_parameters)に則って行ってください。

3.決済APIの呼び出し

バックエンドサーバから得られたアイテム情報に基づいて、決済のためのAPIを呼び出します。このAPIとして、SDKのMixiContainer#requestPaymentメソッドを利用します。

PaymentParameter param = new PaymentParameter();
param.callbackUrl = "http://sap_service/callback";
param.inventoryCode = "order123";
param.itemId = "123";
param.itemName = "エクスカリバー";
param.itemPrice = 250;
param.isTest = true;
param.signature ="TmihyproUc02HOh17W0uz++WdYM=";
container.requestPayment(this, param, PAYMENT_REQUEST_CODE,new CallbackListener(){});

まず、決済オブジェクト(PaymentParameter)を生成します。その際に必要となる項目は、以下となります。

フィールド変数名 説明
itemPrice アイテムのポイント数
itemName アイテム名
signature 決済情報の署名文字列
itemId アイテムID
isTest 決済処理のテストの場合は”true”, 実際の決済の場合は”false”
inventoryCode バックエンドサーバー側でこの決済を特定するためのユニークな任意の文字列
callbackUrl mixiサーバから呼び出されるバックエンドサーバのURL

実際の決済処理は、MixiContainer#requestPaymentメソッドによって呼び出します。この関数は、以下の引数を受け付けます。

  1. 呼び出し元Activityのオブジェクト
  2. PaymentParameterオブジェクト
  3. コールバッククラスを呼び出すためのrequestCode
  4. コールバッククラス

MixiContainer#requestPaymentメソッドを呼び出すと、mixiサーバに決済開始要求がmixiアプリから送信されます。

残ポイントが足りなかった場合

決済情報に含まれるポイント数について、対象ユーザが必要なポイント数を持っていなかった場合は、ユーザに残高不足を表すポップアップ画面が表示されます。ユーザがポイントチャージを行い、さらにポップアップ画面から続行を選択することで、再度決済処理が行われます。

4.ポイントコードの送信

mixiアプリからMixiContainer#requestPaymentメソッドが呼び出された後、mixiサーバは PaymentParameter#callbackUrlにて指定されたバックエンドサーバのURLにポイントコードを送信します。その際に送られるパ ラメータは以下となります。

パラメータ 説明
opensocial_app_id mixiアプリのID
opensocial_owner_id mixiアプリの利用者のハッシュ化されたユーザID
inventory_code バックエンドサーバにて採番されたユニークな任意の文字列
point_code この決済を特定するためのポイントコード
item_id アイテムのID
item_price アイテムのポイント数
item_name アイテムの名前
signature バックエンドサーバにて生成された署名文字列
is_test 決済処理のテストの場合は”true”, 実際の決済の場合は”false”

このリクエストは、2-legged OAuthによる署名が施されています。署名は、Authenticationヘッダに記載されています。不正な購入を防ぐために、必ずこの署名の検証を 行ってください。検証方法は、mixiアプリモバイルでの仕様と同じです。ただし、検証時のベース文字列として、上記にあげたパラメータに関しても含める ようにしてください。

5.結果の返却

署名の検証後、ポイントコードなど決済内容をバックエンドサーバ側で保持します。その後、成功のレスポンスを返却します。

Status: 200
Content-Type: text/plain

OK

このレスポンスは、10秒以内に行う必要があります。10秒以内にレスポンスがなかった場合、決済処理は行われません。

6-7.ユーザによる決済確認

mixiサーバが結果を受信後、ユーザに決済確認のためのポップアップ画面が表示されます。そこでユーザは、決済するかどうかの判断を行います。ユーザが決済を要求することで、mixiサーバ内で決済処理が実行されます。

8.決済処理ステータスの送信

mixiサーバ内で決済処理が行われた後に、再度バックエンドサーバに決済確定のためのリクエストが送信されます。リクエストは、 requestPayment()関数の呼び出し時に渡されたpaymentHandlerUrlで指定したURLとなります。リクエストに含まれるパラ メータは、以下となります。

パラメータ名 説明
opensocial_app_id mixiアプリのID
opensocial_owner_id mixiアプリの利用者のユーザID
point_code この決済を特定するためのポイントコード
status ステータス 10=購入成功
updated 購入確定日時(UTC)
statusの値 説明
10 購入成功
20 購入失敗、その他エラー

このリクエストは、2-legged OAuthによる署名が施されています。署名は、Authenticationヘッダに記載されています。不正な購入を防ぐために、必ずこの署名の検証を行ってください。検証方法は、mixiアプリモバイルでの仕様と同じです。ただし、検証時のベース文字列として、上記にあげたパラメータに関しても含めるようにしてください。

9.結果の返却

署名の検証後、リクエストに含まれる各パラメータに基づいて、バックエンドサーバ側にて決済内容の確認とアイテム購入処理などを行います。その後、成功のレスポンスを返却します。

Status: 200
Content-Type: text/plain


OK

このレスポンスは、10秒以内に行う必要があります。10秒以内にレスポンスがなかった場合、決済確定の処理は行われません。

10.ユーザへの決済完了表示

バックエンドサーバから結果を受け取ったmixiサーバは、ユーザに決済完了を示すポップアップ画面を表示します。ユーザは、その画面を閉じます。

11.コールバック関数の呼び出し

Activity#onActivityResult内でMixiContainer#paymentCallbackを呼び出すようにしてください。 決済が成功している場合には、CallbackListener#onCompleteが実行されます。 決済がユーザーによってキャンセルされた場合はCallbackListener#onCancelが実行されます。 決済に何らかのエラーが発生した場合はCallbackListener#onErrorまたはCallbackListener#onFatalが実行されます。 onError,onFatalが実行された場合は、何らかの理由で決済が完了しなかったことを示しています。その場合は、 ErrorInfo#getErrorCode,ErrorInfo.getMessageによりエラーコードなどを取得し、適切なエラー処理を行ってください。

エラー内容の確認方法

CallbackListener内
public void onError(ErrorInfo e){
    int errCode = e.getErrorCode();
    if(errCode==401){
       String message = e.getMessage();
      // 権限エラーの処理
    }
    ・
    ・
    ・
}

上記はサンプルなのでエラーの内容に応じて正しく処理を実装してください。

このページの上部へ