サーバー側接続インターフェース説明
もしあなたのゲームに独自のゲームサーバーがあり、ゲームプレイヤーデータをサーバー側で保存・管理している場合、サーバー側での接続が必要です:
モジュール | 説明 | 接続推奨 |
---|---|---|
ユーザーシステム | Jogosプラットフォームのユーザーシステムをあなたのサーバーのユーザーと関連付ける必要があります。サーバー側でユーザーシステムに接続する必要があります | ☑️必須接続 |
課金システム | あなたのゲームに課金項目がある場合、Jogos課金システムに接続する必要があります。これにより、ユーザーの支払いとデータの安全性が保証されます | ☑️課金ゲームは必須接続 |
ユーザーシステム接続
1 クライアントからユーザートークンを取得
- 詳細は
クライアント接続ユーザーSDK
ドキュメントを参照してください。
2 概要
Jogosからユーザートークンおよびpublickeyを取得後、ゲームサーバーに返送して検証を行い、ユーザー情報を取得します。注意:トークンを検証するたびにpublickeyを取得してください。publickeyは随時変更される可能性があります。
3 検証ロジック
- ゲーム開発者はJogosから取得したユーザートークンを自分のサーバーに送信します。
- サーバー側でpublickeyを取得します(https://www.jogos.com/publicKey.json から取得)。
- Base64エンコードされたpublickey文字列からRSA公開鍵を生成。
- RSA公開鍵を使用してJWTトークンを復号化します。復号化結果は jwt.io でテスト可能です。
- 復号化後に取得したユーザー情報をあなたのゲームサーバーのユーザーと紐付けます。
- 復号化が失敗した場合、空のユーザー情報を返します。
4 コード例
プロジェクトにjwtをインポート:
<!--JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
</dependency>
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import com.alibaba.fastjson.JSONObject;
public class JwtUtils {
public static void main(String[] args) {
/**
* Jogos SDKからpublickeyとユーザートークンを取得し、サーバーに送信
* 以下は例のpublickey:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhyUrr/W8bSuC+HK8Rk++BDOGDefGMEBa9jekVwVE3oeqi7QbVzZPAuqb1K3GPJjDBfi44IWzb3w8Xa0P1ZeO2Cnbg1LltanlzFv/EcKseCIkOd8Qo78ARPfmlf4WP6MznYGKwNVGFh/s5Y6ar8QgWX1ttkcwYzHu/gUroO+nPOZkU6bfxHjRrJxk3lSQBZWfTSFd2JFwntq3h45UHymjQZiMtW47G2C4VTtTTt1Iz0VQ9rdtWie/+REqQYoFUm04Yns9jyG3TZzio9vsRrxESLQbBIRxto77cQNtEe9j/2EXNwQabRkiS6zo6i2TIN4O6uthWBVud5WXsBWdiyIOHQIDAQAB
-----END PUBLIC KEY-----
ユーザートークン:
eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIxOTY3NDIzNTM3NjE1NTgxMTg0Iiwic3ViIjoie1wicHJvZmlsZVBpY3R1cmVVcmxcIjpcImh0dHBzOi8vaW1hZ2Uuam9nb3NwcmUuY29tLzBlZTkyZjViZTRhMzQ4NzBhYjY0YWU1N2FjN2I1YmE0LmpwZ1wiLFwiZ2FtZUlkXCI6XCIxMjIwXCIsXCJ1c2VySWRcIjpcIjI1N1wiLFwidXNlcm5hbWVcIjpcIlBsYXllcjI1N1wifSIsImlzcyI6ImNvbTpqb2dvczpzZGsiLCJpYXQiOjE3NTc5MDUyOTgsImV4cCI6MTc2MTUwNTI5OH0.MKBab0XC1o5AYGosbq1l5m9xCLN1-4xfcr7_dHn-_C8Eh2moTuq9TbQutIajB3dViFW0e1KyIg7UhxNk00rdhT2b5UrvO23tyFsgg9FYyAyCZABURxHyI0lTW9V8YA9k4faycK_gCUMXH_IubseDMz1P7cYmPpo8WxJXZq3R-mL8OhhuKCn8DlpP5BVsd0_gYSTvDUD0gjdINLUNTVrZVkETcDVWW8OXQVzJxdTH0VVlDs4cGvIyko8TJ6g1Bvz4VWj4qy1XoQFfRBH8sgBl3oGJtUodhq3b4bOx4Cr_o-2tK54CetDdmmCPbtcbmmDcBqK5EQ51A2Kws-1cYtsFxg
注:トークン検証時は毎回publickeyを取得してください。変更される可能性があります。
*/
String publickey ="あなたのpublickey";
String token = "あなたのユーザートークン";
System.out.println("publickey:["+publickey+"]");
System.out.println("token:["+token+"]");
Map<String, Object> userMap = verifyToken(token,publickey);
// Token解析成功の場合、userMapはnullではない
if (userMap != null) {
System.out.println("検証成功、ユーザー情報:");
System.out.println(JSONObject.toJSONString(userMap));
}else {
System.out.println("jwt検証失敗");
}
}
/**
* トークン検証
* @param token
* @return
*/
public static Map<String, Object> verifyToken(String token,String publickey){
// トークン解析を試み、失敗した場合はnullを返す
Map<String, Object> map = null;
try {
map = parseToken(token,publickey);
} catch (Exception e) {
}
return map;
}
/**
* トークン復号
* @param token
* @return
*/
public static Map<String,Object> parseToken(String token,String publickey){
// 先頭と末尾を削除
if(publickey.startsWith("-----BEGIN PUBLIC KEY-----")) {
publickey = publickey.substring(27,publickey.length()-25);
}
Claims claims = (Claims) Jwts.parser()
.setSigningKey(getPublicKey(publickey))
.parse(token)
.getBody();
String parseToken = claims.getSubject();
if (parseToken != null) {
Map<String, Object> map = JSONObject.parseObject(parseToken, Map.class);
return map;
}
return null;
}
/**
* Base64エンコード文字列からRSA公開鍵を取得
* @param key Base64エンコードされた公開鍵文字列
* @return 変換後のRSA公開鍵
* <p>
* 注意:入力文字列をBase64デコーダーでバイト配列に変換後、KeyFactoryとX509EncodedKeySpecを使用してPublicKeyオブジェクトに変換します。
* 変換中に例外が発生した場合はRuntimeExceptionをスローします。
*/
private static PublicKey getPublicKey(String key) {
byte[] decode = Base64.getDecoder().decode(key);
PublicKey publicKey;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decode);
publicKey = keyFactory.generatePublic(keySpec);
} catch (Exception e) {
throw new RuntimeException(e);
}
return publicKey;
}
}
課金システム接続
接続開始前の確認事項
現在使用している環境が
www.jogospre.com
(テスト環境)またはwww.jogos.com
(本番環境)であることを確認してください。以下に記載されるPOSTリクエストURLは、対応する環境のURLに変更する必要があります。 (例:テスト環境の到着API:https://api.jogospre.com/api/gamepay/webhook/arrivedorder)開発者プラットフォームでゲームアプリを作成し、「ゲームパラメータ」でゲームの 共有キー を生成済みであること。
ゲーム設定で「アプリ内課金」を有効にし、サーバーが受信する コールバック通知URL を入力済みであること。
通信はSHA-1暗号化方式を使用。使用例は以下の通り:
javascriptprivate String sha1(String input) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] hashInBytes = md.digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : hashInBytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("SHA-1 algorithm is not available", e); } }
クライアント側の事前接続:
- クライアント側で注文作成および注文送信を行います。
- 詳細は
クライアント接続課金SDK
ドキュメントを参照してください。
サーバー側接続開始:
1. ユーザーがゲーム内で商品購入成功後、Jogosプラットフォームが支払い成功通知を送信
Jogosプラットフォームは支払い成功コールバック情報を、あなたが設定した コールバック通知URL に送信
リクエストヘッダ:
フィールド名 タイプ 空許可 説明 Authorization string 否 検証ヘッダ。sha1(body+キー)、キーはゲームの共有キー(ゲームパラメータで設定) リクエストボディには以下のフィールドが含まれます:
フィールド名 タイプ 空許可 説明 paytype String 否 通知タイプ pay:支払い成功通知;refund:返金成功通知 gameId int 否 ゲームID orderId String 否 注文番号 arrivedStatus int 否 到着ステータス:0 未到着,1 到着済み productId String 否 商品ID createTime long 否 注文作成時間(Unixタイムスタンプ) payTime long 否 支払い成功時間(Unixタイムスタンプ) userId int 否 ユーザーID refundStatus int はい 返金ステータス。返金時に値がある:0:返金中、1:返金成功、2:返金失敗、3:返金拒否 refundTime long はい 返金時間(Unixタイムスタンプ)。返金時に値がある リクエスト例:
javascript{ "gameId": 9968, "orderId": "zXhKYRy3genKKh9TgndBpu1gp5tBpA", "arrivedStatus": 0, "productId": "1002", "createTime": 1755657098, "payTime": 1755657115, "userId": 278, "refundStatus": null, "refundTime": null }
- 返却されるJSONオブジェクトには以下のフィールドが含まれます(code:200は成功):
json{ "code": "200", "msg": "Success" }
エラーコード:
305
必須パラメータが空40001
対応するゲームが見つからない41007
検証失敗500
システムエラー
2. ゲームサーバーでの発送完了後、「到着ステータス更新」APIを呼び出し、注文を発送済みに設定
リクエストURL:[POST] https://api.jogos.com/api/gamepay/webhook/arrivedorder
リクエストヘッダ:
フィールド名 タイプ 空許可 説明 Authorization string 否 検証ヘッダ。sha1(body+キー)、キーはゲームの共有キー(ゲームパラメータで設定) リクエストボディ: | フィールド名 | タイプ | 空許可 | 説
明 | | ------------ | ---- | ---- | ---- | | gameId | int | 否 | ゲームID | | orderId | int | 否 | 注文番号 |
リクエスト例:
{
"gameId": 9943,
"orderId":"gHpGwweTlucXwcM6yIeSMcgKkhFmoO"
}
返却JSONオブジェクト(code:200は成功):
json{ "code": "200", "msg": "Success" }
エラーコード:
305
必須パラメータが空40001
対応するゲームが見つからない41007
検証失敗500
システムエラー
3. ゲームサーバーで注文リストを取得し、注文および到着ステータスを同期
リクエストURL:[POST] https://api.jogos.com/api/gamepay/getOrders
リクエストヘッダ:
フィールド名 タイプ 空許可 説明 Authorization string 否 検証ヘッダ。sha1(body+キー)、キーはゲームの共有キー(ゲームパラメータで設定) リクエストボディ:
フィールド名 タイプ 空許可 説明 gameId int 否 ゲームID pageNo int 否 ページ番号 pageSize int 否 ページサイズ リクエスト例:
javascript{ "gameId": 9943, "pageNo":1, "pageSize":20 }
返却JSONオブジェクト(code:200は成功):
フィールド名 タイプ 空許可 説明 code String 否 ステータスコード (例: SUCCESS) message String 否 メッセージ (例: ログアウト成功) total Integer 否 総件数 pageSize Integer 否 1ページあたり件数 currentPage Integer 否 現在ページ totalPage Integer 否 総ページ数 orderId String 否 注文番号 arrivedStatus Integer 否 到着ステータス;0 未到着,1 到着済み payTime long 否 支払時間(Unixタイムスタンプ) productId String 否 商品ID userId Integer 否 ユーザーID refundStatus Integer はい 返金ステータス(返金時のみ値がある):0:返金中、1:返金成功、2:返金失敗、3:返金拒否 refundTime long はい 返金時間(Unixタイムスタンプ)、返金時のみ値がある json{ "code": "200", "msg": "Success", "page": { "total": 31, "totalPage": 7, "currentPage": 1, "pageSize": 5, "content": [ { "orderId": "gHpGwweTlucXwcM6yIeSMcgKkhFmoO", "arrivedStatus": 1, "payTime": 1112211221, "productId": "game_pro1", "userId": 278, "refundStatus": null, "refundTime": null } ] } }
エラーコード:
305
必須パラメータが空40001
対応するゲームが見つからない41007
検証失敗500
システムエラー
4. ユーザーが返金した場合、ゲームサーバーに返金成功通知を送信
- Jogosプラットフォームは、ユーザーが返金申請を行い成功した注文のコールバック情報を、設定した コールバック通知URL に送信
- リクエストボディは第1項「支払い成功通知」と同じ
- 開発者は返金注文情報をもとに、プレイヤーが以前に得た報酬アイテムを適宜減算または制限することを推奨