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)
次ページ ライフサイクルイベントの署名検証