Server-Side Integration API Documentation
If your game has its own game server, and the player data is stored and managed by your server, then server-side integration is required:
Module | Description | Integration Recommendation |
---|---|---|
User System | You need to link the Jogos platform user system with your server users. This requires server-side integration of the user system | ☑️ Required Integration |
In-App Purchase | If your game includes in-app purchase items, you need to integrate with the Jogos in-app purchase system to ensure user payment and data security | ☑️ Required for IAP Games |
User System Integration
1. Obtain User Token from Client
- Please refer to
Client SDK User Integration
for details.
2. Overview
After obtaining the user token and public key from Jogos, send them to your game server for verification and to retrieve user information. Note: always retrieve the public key when verifying the token, as it may change at any time.
3. Verification Logic
- Game developers send the user token obtained from Jogos to their game server.
- The server fetches the public key (from https://www.jogos.com/publicKey.json).
- Convert the Base64-encoded public key string into an RSA public key.
- Decrypt the JWT token using the RSA public key. The decoded token can be tested at jwt.io.
- Retrieve the user information from the decoded token and bind it to your game server's user.
- If decryption fails, return empty user information.
4. Code Examples
::: tabs key:server
== JAVA Server
Import jwt in your project:
<!--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) {
/**
* Obtain publickey and user token from Jogos SDK and send them to the server, e.g., the publickey below:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhyUrr/W8bSuC+HK8Rk++BDOGDefGMEBa9jekVwVE3oeqi7QbVzZPAuqb1K3GPJjDBfi44IWzb3w8Xa0P1ZeO2Cnbg1LltanlzFv/EcKseCIkOd8Qo78ARPfmlf4WP6MznYGKwNVGFh/s5Y6ar8QgWX1ttkcwYzHu/gUroO+nPOZkU6bfxHjRrJxk3lSQBZWfTSFd2JFwntq3h45UHymjQZiMtW47G2C4VTtTTt1Iz0VQ9rdtWie/+REqQYoFUm04Yns9jyG3TZzio9vsRrxESLQbBIRxto77cQNtEe9j/2EXNwQabRkiS6zo6i2TIN4O6uthWBVud5WXsBWdiyIOHQIDAQAB
-----END PUBLIC KEY-----
and the user token:
eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIxOTY3NDIzNTM3NjE1NTgxMTg0Iiwic3ViIjoie1wicHJvZmlsZVBpY3R1cmVVcmxcIjpcImh0dHBzOi8vaW1hZ2Uuam9nb3NwcmUuY29tLzBlZTkyZjViZTRhMzQ4NzBhYjY0YWU1N2FjN2I1YmE0LmpwZ1wiLFwiZ2FtZUlkXCI6XCIxMjIwXCIsXCJ1c2VySWRcIjpcIjI1N1wiLFwidXNlcm5hbWVcIjpcIlBsYXllcjI1N1wifSIsImlzcyI6ImNvbTpqb2dvczpzZGsiLCJpYXQiOjE3NTc5MDUyOTgsImV4cCI6MTc2MTUwNTI5OH0.MKBab0XC1o5AYGosbq1l5m9xCLN1-4xfcr7_dHn-_C8Eh2moTuq9TbQutIajB3dViFW0e1KyIg7UhxNk00rdhT2b5UrvO23tyFsgg9FYyAyCZABURxHyI0lTW9V8YA9k4faycK_gCUMXH_IubseDMz1P7cYmPpo8WxJXZq3R-mL8OhhuKCn8DlpP5BVsd0_gYSTvDUD0gjdINLUNTVrZVkETcDVWW8OXQVzJxdTH0VVlDs4cGvIyko8TJ6g1Bvz4VWj4qy1XoQFfRBH8sgBl3oGJtUodhq3b4bOx4Cr_o-2tK54CetDdmmCPbtcbmmDcBqK5EQ51A2Kws-1cYtsFxg
Note: Always retrieve the publickey when verifying the token as it may change
*/
String publickey ="your publickey";
String token = "your user token";
System.out.println("publickey:["+publickey+"]");
System.out.println("token:["+token+"]");
Map<String, Object> userMap = verifyToken(token,publickey);
// If token parsing succeeds, userMap is not null
if (userMap != null) {
System.out.println("Verification succeeded, user information:");
System.out.println(JSONObject.toJSONString(userMap));
}else {
System.out.println("JWT verification failed");
}
}
/**
* Verify token
* @param token
* @return
*/
public static Map<String, Object> verifyToken(String token,String publickey){
// Try parsing the token; if parsing fails, return null
Map<String, Object> map = null;
try {
map = parseToken(token,publickey);
} catch (Exception e) {
}
return map;
}
/**
* Decrypt token
* @param token
* @return
*/
public static Map<String,Object> parseToken(String token,String publickey){
// Remove header and footer
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;
}
/**
* Get RSA public key from Base64-encoded string
* @param key Base64-encoded public key string
* @return Converted RSA public key
* <p>
* Note: This method decodes the input string into bytes using Base64, then uses KeyFactory and X509EncodedKeySpec
* to convert the byte array into a PublicKey object. RuntimeException is thrown if conversion fails.
*/
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;
}
}
== Node.js
import * as jwt from 'jsonwebtoken';
export interface JogosTokenPayload {
userId: string;
username: string;
gameId: string;
profilePictureUrl: string;
}
export const decodeUserToken = async (token: string): Promise<JogosTokenPayload> => {
try {
const resp = await axios.get("https://www.jogos.com/publicKey.json");
key = resp.data["data"];
}
catch (e) {
console.error("Failed to fetch JogosGames public key", e);
}
if (!key) {
throw new Error("Key is empty when decoding JogosGames token");
}
const payload = jwt.verify(token, key, { algorithms: ["RS256"] });
return payload as JogosTokenPayload;
};
:::
In-App Purchase System Integration
Before Starting Integration:
Ensure you are using either
www.jogospre.com
(test environment) orwww.jogos.com
(production environment); all POST request URLs below must be updated to the corresponding environment. (e.g., test webhook API:https://api.jogospre.com/api/gamepay/webhook/arrivedorder)Make sure your game app is created in the developer platform and a shared key has been generated under "Game Parameters".
Ensure the "Use In-App Purchase" option is checked in your game settings and the callback notification URL for your server is provided.
Communications use SHA-1 encryption as follows:
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); } }
Client-Side Integration:
- The client creates and initiates the order.
- Refer to
Client SDK Payment Integration
for details.
Server-Side Integration:
1. Payment Success Notification from Jogos Platform
The Jogos platform will send a payment success callback to your configured callback notification URL.
Request headers:
Field Type Required Description Authorization string Yes Verification header: sha1(body + shared key), where the key is your game's shared key set in game parameters Request body fields:
Field Type Required Description paytype String Yes Notification type: pay = payment success; refund = refund success gameId int Yes Game ID orderId String Yes Order ID arrivedStatus int Yes Delivery status: 0 = not delivered, 1 = delivered productId String Yes Product ID createTime long Yes Order creation time (Unix timestamp) payTime long Yes Order payment time (Unix timestamp) userId int Yes User ID refundStatus int No Refund status if applicable: 0 = refunding, 1 = refunded, 2 = refund failed, 3 = refund rejected refundTime long No Refund time (Unix timestamp), if applicable Example request body:
javascript{ "gameId": 9968, "orderId": "zXhKYRy3genKKh9TgndBpu1gp5tBpA", "arrivedStatus": 0, "productId": "1002", "createTime": 1755657098, "payTime": 1755657115, "userId": 278, "refundStatus": null, "refundTime": null }
- Response JSON fields (code:200 means success):
json{ "code": "200", "msg": "Success" }
Error codes:
305
Required parameter is missing40001
Game not found41007
Verification failed500
System error
2. Update Order Delivery Status
Request URL: [POST] https://api.jogos.com/api/gamepay/webhook/arrivedorder
Request headers:
Field Type Required Description Authorization string Yes Verification header: sha1(body + shared key), where the key is your game's shared key Request body:
Field Type Required Description gameId int Yes Game ID orderId int Yes Order ID Example request body:
javascript{ "gameId": 9943, "orderId":"gHpGwweTlucXwcM6yIeSMcgKkhFmoO" }
Response JSON fields (code:200 means success):
json{ "code": "200", "msg": "Success" }
Error codes:
305
Required parameter is missing40001
Game not found41007
Verification failed500
System error
3. Query Orders and Synchronize Delivery Status
Request URL: [POST] https://api.jogos.com/api/gamepay/getOrders
Request headers:
Field Type Required Description Authorization string Yes Verification header: sha1(body + shared key), where the key is your game's shared key Request body:
Field Type Required Description gameId int Yes Game ID pageNo int Yes Page number pageSize int Yes Page size Example request body:
javascript{ "gameId": 9943, "pageNo":1, "pageSize":20 }
Response JSON fields (code:200 means success):
Field Type Required Description code String Yes Status code, e.g., SUCCESS message String Yes Message, e.g., Logout successful total Integer Yes Total count pageSize Integer Yes Items per page currentPage Integer Yes Current page totalPage Integer Yes Total pages orderId String Yes Order ID arrivedStatus Integer Yes Delivery status: 0 = not delivered, 1 = delivered payTime long Yes Payment time (Unix timestamp) productId String Yes Product ID userId Integer Yes User ID refundStatus Integer No Refund status if applicable: 0 = refunding, 1 = refunded, 2 = refund failed, 3 = refund rejected refundTime long No Refund time (Unix timestamp), if applicable 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 } ] } }
- Error codes:
- `305` Required parameter is missing
- `40001` Game not found
- `41007` Verification failed
- `500` System error
### <span style="color:rgb(255, 196, 34);">4. Refund Notification</span>
- The Jogos platform will send refund success callbacks to your configured **callback notification URL** for refunded orders.
- Request body is the same as in section 1 “Payment Success Notification”.
- Developers are advised to deduct or restrict rewards previously granted to the player as appropriate based on the refund order.