mixiアプリ » 技術仕様(Graph API方式) » PC » はじめてのmixiアプリ » チュートリアル » 課金API
課金API
課金API は payment.php と payment-callback.php に実装しています。
payment.php は決済情報の作成と決済APIの呼び出しを行います。
payment-callback.php は mixiサーバからリクエスト送信されるポイントコードと決済情報を受け取ります。
まずは、画面の動作から見ていきましょう。
TOPページの「課金API」リンクをクリックすると payment.php へ遷移します。

payment.php と payment-callback.php が2つとも正常に動作している場合は、 すぐに「購入確認」ポップアップが表示されます。

「購入」ボタンをクリックすれば、続けて「購入完了」ポップアップが表示されます。

「OK」をクリックで、ポップアップは消え、 payment.php のページに戻ります。
決済情報の作成と決済API の呼び出し
では、プログラムを見ていきましょう。
payment.php
1 <?php
2 require_once('functions.php');
3 require_once('config.php');
4
5 $paymentHandlerUrl = 'http://'.APP_DOMAIN.'/payment-callback.php';
6
7 $inventoryCode = 123;
8 $itemId = 123;
9 $isTest = 'true';
10 $itemPrice = 250;
11
12 $params = array(
13 'callback_url' => $paymentHandlerUrl,
14 'inventory_code' => $inventoryCode,
15 'is_test' => $isTest,
16 'item_id' => $itemId,
17 'item_price' => $itemPrice,
18 );
19
20 $baseParams = array();
21 foreach($params as $key => $val){
22 $baseParams[] = $key.'='.urlencode($val);
23 }
24 sort($baseParams);
25 $baseStr = urlencode(implode('&', $baseParams));
26
27 $key = RESTFUL_CONSUMER_SECRET . '&';
28 $signature = hash_hmac('sha1', $baseStr, $key, true);
29 $signature = base64_encode($signature);
30
31 ?>
32 <!DOCTYPE html>
33 <html>
34 <head>
35 <meta charset="UTF-8" />
36 <title>はじめてのmixiアプリ</title>
37 <script type="text/javascript" charset="UTF-8" src="https://static.mixi.jp/js/application/connect.js"></script>
38 </head>
39 <body>
40 <div>
41 課金API
42 </div>
43 <div id="item"
44 data-price="<?=h( $itemPrice )?>"
45 data-name="itemName1"
46 data-signature="<?=h( $signature )?>"
47 data-id="<?=h( $itemId )?>"
48 data-is-test="<?=h( $isTest )?>"
49 data-inventory-code="<?=h( $inventoryCode )?>"
50 data-payment-handler-url="<?=h( $paymentHandlerUrl )?>" ></div>
51 <script>
52 var item = document.getElementById('item');
53
54 var params = {};
55 params[opensocial.Payment.Field.AMOUNT] = item.dataset.price;
56 params[mixi.Payment.Field.ITEM_NAME] = item.dataset.name;
57 params[mixi.Payment.Field.SIGNATURE] = item.dataset.signature;
58 params[mixi.Payment.Field.ITEM_ID] = item.dataset.id;
59 params[mixi.Payment.Field.IS_TEST] = item.dataset.isTest;
60 params[mixi.Payment.Field.INVENTORY_CODE] = item.dataset.inventoryCode;
61 params[opensocial.Payment.Field.PAYMENT_TYPE] = opensocial.Payment.PaymentType.PAYMENT;
62 var payment = opensocial.newPayment(params);
63
64 opensocial.requestPayment(
65 payment,
66 item.dataset.paymentHandlerUrl,
67 function(response){
68 var data;
69 var code;
70 var msg;
71
72 if (response.hadError()){
73 code = response.getErrorCode();
74 msg = response.getErrorMessage();
75 alert('code=' + code + ' msg=' + msg);
76 }else{
77 data = response.getData();
78 // alert('ok. itemNmae=' + data.fields_.itemName);
79 }
80 }
81 );
82 </script>
83 <br />
84 <br />
85 <div>
86 <a href="start.php">top</a>
87 </div>
88 </body>
89 </html>
このプログラムは大きく次の2つの部分からなります。
5-29行 決済情報の作成。サーバ側 php 処理にて、決済情報のsignature 生成を行っています。
43-82行 決済API の呼び出し。クライアント側 JavaScript 処理にて、 課金API requestPayment() のパラメータ設定および呼び出しを行っています。
※実際のアプリ・ゲームでは、決済情報の作成は別途APIとして作成し、JavaScriptから呼び出す方がスマートな実装となりますが、ここでは簡単のため、同一プログラムの中で処理を行っています。
それぞれの注意する点などは以下のようになります。
・決済情報のsignature生成部分
9行 開発中アプリでは is_test='true' にします。
12-18行 ベース文字列に含めるパラメータを設定。
22行 各パラメータの値は urlencode する。
24行 パラメータ文字順でソート。
27行 RESTful のCONSUMER_SECRET をhash生成のkeyとします。
28行 base64エンコードを行い決済情報のsignature生成は完了です。
・JavaScript 課金API requestPayment() の呼び出し部分
43-50行 アイテム情報をphpからJavaScriptへ渡すための要素を定義。
54-62行 パラメータ設定。signature 生成に用いた値と同じ値を設定します。57行では、生成したsgnatureも パラメータとして設定しています。
64-81行 requestPayment() の呼び出しを行います。
73-75行 callback 関数でエラーの場合など、alertで表示します。
77-78行 正常終了の場合の処理を適宜記述してください。
payment.php については以上となります。
バックエンドサーバでの署名検証
バックエンドサーバでの署名検証は payment-callback.php に実装しています。プログラムを見ていきます。
payment-callback.php
1 <?php
2 require_once('functions.php');
3 require_once('config.php');
4
5 /**
6 * 署名検証
7 */
8 function _verifySignature($consumerSecret){
9
10 $oauthParams = _getOAuthParams();
11
12 $oauthSignature = urldecode($oauthParams['oauth_signature']);
13
14 unset($oauthParams['oauth_signature']); // 必要ないので削除
15 unset($oauthParams['realm']); // 必要ないので削除
16
17 $oauthParams = array_merge($oauthParams, $_GET); // getパラメータを merge
18 ksort($oauthParams); // param name で sort
19
20 $baseParams = array(
21 $_SERVER['REQUEST_METHOD'], // method
22 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'], // request url
23 http_build_query($oauthParams),
24 );
25 $baseParams = array_map('urlencode', $baseParams); // それぞれ urlencode
26 $baseStr = implode('&', $baseParams);
27
28 $key = $consumerSecret.'&';
29 $signature = hash_hmac('sha1', $baseStr, $key, true);
30 $signature = base64_encode($signature);
31 $ret = ($signature == $oauthSignature);
32 // error_log($oauthSignature.' '.($ret?'':'!').'= '.$signature."\n"); // 必要ならログ出力
33
34 return $ret;
35 }
36
37 /**
38 * authorization params を取得
39 */
40 function _getOAuthParams(){
41
42 $httpAuthorization = $_SERVER['HTTP_AUTHORIZATION'];
43 $httpAuthorization = substr($httpAuthorization, strlen("OAuth ")); // 先頭の 'OAuth' を削除
44 $tmpAry = explode(', ', $httpAuthorization);
45
46 $oauthParams = array();
47 foreach($tmpAry as $param){
48 preg_match('/^(.+)="(.*)"$/', $param, $m);
49 $oauthParams[$m[1]] = $m[2];
50 }
51 return $oauthParams;
52 }
53
54 $verify = _verifySignature(RESTFUL_CONSUMER_SECRET);
55
56 header('HTTP/1.1 200 OK');
57 header('Content-type: text/plain');
58 echo ($verify ? 'OK' : 'NG');
59 exit;
8-35行 関数 _verifySignature() として、署名検証処理を行っています。54行で呼び出しています。
40-52行 関数 _getOAuthParams() として、付与された signature とパラメータ取得の処理を行います。ここでは $_SERVER["HTTP_AUTHORIZATION"] にセットされているものとして記述しています。phpの設定によっては、getallheaders() 関数でも取得できます。適宜読み替えを行ってください。
10, 12行 パラメータから signature を取得。
15行 realm は必要ないので削除します。
17行 GETパラメータをマージします。
18行 パラメータ名でソート。
20-26行 ベース文字列を生成。
28-30行 signature 生成。
58行 署名が一致すれば、 "OK" を返す。
実際のアプリ・ゲームでは署名検証だけでなく、購入したアイテムの内容をDB保存するなど必要な処理を行ってください。
課金API の説明は以上となります。
前ページ 自分と友人の情報を表示(2)
次ページ ライフサイクルイベントの署名検証