Server 側での非同期確認処理
This page is not available in English.
Please select another language.
概要
Mobage JS SDKのアイテム購入のフローでは、コインによるアイテム決済 において先にモバコインが引き落とされ、アイテムの受注処理 はその後に行われます。このためモバコインが引き落とされた直後にブラウザがクラッシュしたり、Clientからのアイテム付与リクエストが失敗すると、「コインは引き落とされたのにアイテムがまだ付与されていない」という状態のままになってしまう場合があります。
これを防ぐ方法として、コインによるアイテム決済 後にPlatformから通知が送られてくる枠組みが、Server 側での非同期確認処理 です。
ここでは、このPlatfromからの通知から該当するトランザクションを確認し、「コインは引き落とされたのにアイテムがまだ付与されていない」という場合にアイテムを付与する機能を開発していきます。
作成するファイル一覧
このチュートリアルで作成するファイルは下記になります。
ファイル名 |
概要 |
---|---|
config.php |
各種設定値をまとめます |
confirmation.php |
Platformからの通知によりトランザクションの状態を確認し、場合によってアイテム付与をします |
![]() | なお本文中で定義するテーブル定義はこのチュートリアルの為のサンプルなので、参考程度に留めて下さい。 |
チュートリアルをはじめる前に
このチュートリアルは、以下のチュートリアルを終わらせている前提で進めます。
以下のチュートリアルでファイル作成していない場合は、先にそちらを完成させましょう。
サンプルコードのダウンロード
Github からサンプルコードを clone できます。
また、以下のライブラリを利用するので、ダウンロードしておきます。
Server 側での非同期確認処理を実現するために、大きく以下の2ステップで進めます。
Mobage Developers Japan で Subscriber Callback URI を登録する
Platformからのリクエストを受け取るために、Mobage Developers Japan(デベロッパーサイト) で Game Server 側のURIを設定します。
![]() | このチュートリアルを進めるためには、Platform からのリクエストを受け取れる Game Server の用意が必要となります。以下、Game Server の用意が完了しているものとしてチュートリアルを進めます。 |
1. ダッシュボードの左メニューより「アプリケーション」>「アプリケーション一覧」画面を開きます。
2. 「アプリケーション一覧」から開発しているアプリケーションを選択します。
3. 表示されたページの上部にある「SPWeb」タブを選択します。
4. SPWebのページ中央部、「Mobage Connect 情報」の右側にある「情報を変更」を押下します。
5. Mobage Connect情報の複数あるタブの中から、「アイテム購入非同期確認処理設定」を選択します。
6. 「Subscriber Callback URI」に、Platformからのリクエストを受け取るGame Server側のURIを設定します。
![]() | このチュートリアルでは「http://example.com/mobage-jssdk-sample-payment/server_async/confirmation.php」と設定します。 |
Mobage Developers Japan(デベロッパーサイト) で Subscriber Callback URI の登録が完了したら、次はリクエストを受け取るプログラムを開発します。
TOC
Platform からの通知を処理する
ユーザーがコインによるアイテム決済を行うと、Platformから先ほど登録したSubscriber Callback URIに通知が来ます。この通知はJSON Web Token(JWT)というフォーマットで送られます。
Platformからの通知を以下の4ステップで作成します。
- JWTの検証
- Order DB の確認 ※
- アイテムの付与と Order データの更新 ※
- Platformへのレスポンス送信
※このチュートリアルでは、アイテム付与管理を行うテーブルを Order DB 、Order DB 上のトランザクションを表すデータを Order データ として解説を進めます。
JWTの検証
Platform から通知されるリクエスト形式はJSON Web Token(JWT)というフォーマット(application/jwt)です。この JWT は署名アルゴリズムが RS256 となっています。ここでは JWT の検証として、以下のライブラリを利用します。
- https://github.com/firebase/php-jwt
JWTのデコード
Platform から送られたリクエストは Platform 側の秘密鍵で署名がつけられているため、X.509 形式の公開鍵を利用して署名の妥当性を検証します。(署名の検証で利用する公開鍵)
JWT の payload (JWT Claims Set)は以下のようなデータ構造をしています。
JWT Claims Set の検証
Platform から送られた通知が妥当であるかどうかを確認するため、JWT 中の本文である JWT Claims Set を検証する処理を実装します。Game Server で検証する項目は以下になります。
- iss(Issuer Claim, この JWT を発行したサーバの識別子)が妥当か
- aud(Audience Claim, この JWT の公開範囲として指定された Client ID)がアプリケーションの Client ID と一致しているか
- sub(Subject Claim)がログインユーザの所持する Mobage ユーザー ID と一致するか
- iat(Issued At)が現在時刻よりも過去の日時を表す UNIX タイムスタンプ値となっているか
なお、iss 値は sandbox/service で以下のように異なる値となっています。
環境 |
issの値 |
---|---|
sandbox |
https://sb-hub.mobage.jp |
service |
https://hub.mobage.jp |
![]() | sub 値の検証は、データベースからユーザー ID を取得する必要があるので、Order DB から Order データを取得する際に検証します。 |
Order DB の確認
JWT の妥当性を確認し終えたら、次は Order DB を参照しユーザーに既にアイテムが付与されているかどうかを確認します。
ここでは、下記のような Order DB を定義しています。
なお、このOrder DB の order_state は、下記のようにアイテム付与の状態を示しています。
order_state |
状態 |
決済処理の状態 |
---|---|---|
authorized |
アイテム未付与 |
処理途中 |
error |
エラーによりアイテム付与しない |
処理完了 |
canceled |
アイテム付与処理はキャンセル済み |
処理完了 |
closed |
アイテム付与済み |
処理完了 |
Order データを排他制御する
Order DBを確認する際には、処理途中に他のプロセスに邪魔されないように、Order データを排他制御する必要があります。
排他制御を取り入れることで、同じようなタイミングで複数プロセスから更新リクエストがあった際に、間違ったアイテムの重複付与を防ぐことができます。
また、直前に他プロセスに Order データを更新されていることも考慮して、排他制御で取得した Order データ自体の確認も行います。
すでにアイテムが付与されている場合は、order_state が closed になっています。この場合、Platformにアイテム付与成功のレスポンス(200 OK)を返します。
このチュートリアルではMySQLのストレージエンジンInnoDBを利用して、行レベルでの排他制御を行い、最新の Order データを確認します。
なお、このタイミングで Order DB から user_id も取得できているので、JWT Claim Setのsub(Subject Claim)とuser_idが一致しているか下記のように検証します。
アイテムの付与と Order データの更新
アイテムを付与する
排他制御により最新の Order データを取得して確認した結果、まだユーザーにアイテムが付与されていない場合にアイテムを付与します。
このチュートリアルでは、ユーザーのアイテムを管理するテーブルにレコードを追加/更新することでアイテムを付与します。
以下がこのチュートリアルで定義しているユーザーのアイテム管理テーブルです。
上記のテーブル定義に従って、下記のようなアイテム付与を行う処理を実装します。
Order データを更新し、排他制御を開放する
ユーザーへのアイテム付与が完了したら、Order データを更新し、Order データの排他制御を開放します。
このチュートリアルではMySQLのストレージエンジンInnoDBを利用して、行レベルでの排他制御を行っていましたが、排他制御していたトランザクションをcommitすることで排他制御を開放します。
Platformへのレスポンス送信
Platformからのリクエストに対して、以下の場合に 成功レスポンス を返します。
- 既にアイテムを付与していた場合
- ユーザーへのアイテム付与が成功した場合
また、以下の場合には 失敗レスポンス を返します。
- Platformからのリクエストに異常があった場合
- JWTの検証を通過することが出来なかった場合
- その他、ゲームサーバ側の内部処理で異常があった場合
Platformへ成功レスポンス送信する
ユーザへのアイテム付与が完了している場合、成功レスポンスを返します。
成功レスポンスのhttp status code は 200 OK とします。
Platformへ失敗レスポンスを送信する
ゲームサーバの処理で異常があった場合など、Platformへ失敗レスポンスを返します。
失敗レスポンスのhttp status code は 4xxもしくは5xxなどの適切なレスポンスを返します。
Platformからのリクエストは、最大10回まで再送処理が行われます。Platformに成功レスポンスを返すと、この再送処理は止まり、それ以上リクエストは送られません。なお、場合によってはこの再送回数上限まで成功レスポンスを返せない場合もあり得ますので、バッチを用いた確認処理 を併用するようにします。
動作確認
では、開発したプログラムを下記のように Game Server に配置します。
ファイル名 |
URL |
---|---|
config.php |
http://example.com/mobage-jssdk-sample-payment/config.php |
confirmation.php |
http://example.com/mobage-jssdk-sample-payment/server_async/confirmation.php |
![]() | このチュートリアルを進めるためには、Platformからのリクエストを受け取れる Game Server の用意が必要となります。このチュートリアルでは、example.comというドメインでPlatformからのリクエストを受け取れるGame Serverを用意した前提で説明を進めます。 |
また、アイテムを購入するプログラムは、下記のチュートリアルで先に開発しておきます。
Server 側での非同期確認処理の動作確認を行うため、アイテムを購入する処理が実装されたプログラムを一部編集します。
(上記チュートリアルで開発した purchase.js を編集します)
下記のように、「モバコインが引き落とされ、Game Server にアイテム付与リクエストを送る」処理をコメントアウトします。
また、アイテム購入を行う前の Game Server 側のテーブルを以下のように確認します。
これらのコマンド結果から、ユーザーが1つもアイテムを保持していないことと、Order DB にデータが1つも無いことを確認できます。
では、「Game Server へのアイテム付与リクエスト送信処理」のコメントアウトがされた状態で、アイテム購入を進めます。
「Purchase」のボタンを押下すると、以下の画面が表示されます。
この画面が表示された時点で、Game Server の Order DB には既にレコードが追加されているので確認します。
この時点ではまだアイテム付与されていないので、Order DB の order_state は authorized(アイテム未付与:決済処理途中)となっています。
次に、アイテム購入を行って下記の画面を表示させます。
アイテム購入を行うと、モバコインは引き落とされているのにアイテムが付与されていない状態になります。
Game Server を確認すると、下記の状態のままになっています。
Mobage Developers Japan(デベロッパーサイト) にSubscriber URIを登録していれば、すぐにPlatformから通知が来ますので、通知が来たら分かるようにログをはいておきます。
ログを監視していると、すぐに下記のような表示が出て、Platformからの通知が来たことが分かります。
Platformからの通知をきっかけに、アイテム付与が行われたか、Order DB が更新されたか確認します。
上記のように、アイテム付与も行われ、Order DB も正常に更新されたことを確認できました。
開発したコード
このチュートリアルで開発したコードは Github から clone できます。
利用したライブラリは下記になります。