Descrição da Conexão do Lado do Servidor
Se o seu jogo possui um servidor próprio e os dados dos jogadores são armazenados e gerenciados por ele, você precisará estabelecer a conexão do lado do servidor da seguinte forma:
Módulo | Descrição | Observações sobre Conexão |
---|---|---|
Sistema de Usuários | Você precisa vincular o sistema de usuários da plataforma Jogos aos usuários no seu servidor. É necessário conectar o sistema de usuários do lado do servidor | ☑️ Conexão obrigatória |
Sistema de Compras In-App | Se o seu jogo possui compras dentro do aplicativo, é necessário conectar o sistema de compras da Jogos para garantir a segurança dos pagamentos e dados do usuário | ☑️ Jogos com compras in-app devem conectar |
Conexão do Sistema de Usuários
1 Obter o token do usuário do lado do cliente
- Consulte o documento
Client SDK - Conexão de Usuário
antes
2 Visão Geral
Após receber o token e a publickey da Jogos, envie-os de volta ao servidor do jogo para validar e obter os dados do usuário. Observe que cada verificação de token deve obter a publickey novamente, pois ela pode mudar a qualquer momento.
3 Lógica de Verificação
- O desenvolvedor do jogo recebe o token da Jogos e envia para o seu servidor.
- O servidor obtém a publickey (dehttps://www.jogos.com/publicKey.json)
- Use a publickey em Base64 para criar a chave pública RSA.
- Use a chave pública RSA para decodificar o token JWT. Você pode verificar o resultado do token decodificado em jwt.io
- Após a decodificação, obtenha os dados do usuário e vincule ao usuário no servidor do jogo.
- Se a decodificação falhar, retorne os dados do usuário como nulos.
4 Exemplo de Código
Adicione JWT ao seu projeto:
<!--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) {
/**
* Obtenha a publickey e o token do usuário do SDK da Jogos e envie para o servidor.
Exemplo de publickey:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhyUrr/W8bSuC+HK8Rk++BDOGDefGMEBa9jekVwVE3oeqi7QbVzZPAuqb1K3GPJjDBfi44IWzb3w8Xa0P1ZeO2Cnbg1LltanlzFv/EcKseCIkOd8Qo78ARPfmlf4WP6MznYGKwNVGFh/s5Y6ar8QgWX1ttkcwYzHu/gUroO+nPOZkU6bfxHjRrJxk3lSQBZWfTSFd2JFwntq3h45UHymjQZiMtW47G2C4VTtTTt1Iz0VQ9rdtWie/+REqQYoFUm04Yns9jyG3TZzio9vsRrxESLQbBIRxto77cQNtEe9j/2EXNwQabRkiS6zo6i2TIN4O6uthWBVud5WXsBWdiyIOHQIDAQAB
-----END PUBLIC KEY-----
E token do usuário:
eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIxOTY3NDIzNTM3NjE1NTgxMTg0Iiwic3ViIjoie1wicHJvZmlsZVBpY3R1cmVVcmxcIjpcImh0dHBzOi8vaW1hZ2Uuam9nb3NwcmUuY29tLzBlZTkyZjViZTRhMzQ4NzBhYjY0YWU1N2FjN2I1YmE0LmpwZ1wiLFwiZ2FtZUlkXCI6XCIxMjIwXCIsXCJ1c2VySWRcIjpcIjI1N1wiLFwidXNlcm5hbWVcIjpcIlBsYXllcjI1N1wifSIsImlzcyI6ImNvbTpqb2dvczpzZGsiLCJpYXQiOjE3NTc5MDUyOTgsImV4cCI6MTc2MTUwNTI5OH0.MKBab0XC1o5AYGosbq1l5m9xCLN1-4xfcr7_dHn-_C8Eh2moTuq9TbQutIajB3dViFW0e1KyIg7UhxNk00rdhT2b5UrvO23tyFsgg9FYyAyCZABURxHyI0lTW9V8YA9k4faycK_gCUMXH_IubseDMz1P7cYmPpo8WxJXZq3R-mL8OhhuKCn8DlpP5BVsd0_gYSTvDUD0gjdINLUNTVrZVkETcDVWW8OXQVzJxdTH0VVlDs4cGvIyko8TJ6g1Bvz4VWj4qy1XoQFfRBH8sgBl3oGJtUodhq3b4bOx4Cr_o-2tK54CetDdmmCPbtcbmmDcBqK5EQ51A2Kws-1cYtsFxg
Observação: Cada verificação de token deve obter a publickey novamente, pois ela pode mudar.
*/
String publickey ="sua publickey";
String token = "token do usuário";
System.out.println("publickey:["+publickey+"]");
System.out.println("token:["+token+"]");
Map<String, Object> userMap = verifyToken(token,publickey);
// Se a verificação do token for bem-sucedida, userMap não será nulo
if (userMap != null) {
System.out.println("Verificação bem-sucedida, dados do usuário:");
System.out.println(JSONObject.toJSONString(userMap));
}else {
System.out.println("Falha na verificação JWT");
}
}
/**
* Verifica o token
* @param token
* @return
*/
public static Map<String, Object> verifyToken(String token,String publickey){
// Tenta decodificar o token, retorna null se falhar
Map<String, Object> map = null;
try {
map = parseToken(token,publickey);
} catch (Exception e) {
}
return map;
}
/**
* Decodifica o token
* @param token
* @return
*/
public static Map<String,Object> parseToken(String token,String publickey){
// Remove cabeçalho e rodapé
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;
}
/**
* Converte Base64 string em chave pública RSA
* @param key string Base64 da chave pública
* @return chave pública RSA
* <p>
* Observação: Este método decodifica a string em bytes e usa KeyFactory e X509EncodedKeySpec para gerar a PublicKey
*/
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;
}
}
Conexão do Sistema de Compras In-App
Antes de iniciar a conexão, confirme:
Você está usando
www.jogospre.com
(ambiente de teste) ouwww.jogos.com
(ambiente real); O URL do POST abaixo deve corresponder ao ambiente correto (Exemplo de API teste: https://api.jogospre.com/api/gamepay/webhook/arrivedorder)Verifique se você criou o jogo na Developer Platform e gerou a Shared Key do jogo em “Game Parameters”
Verifique se selecionou o modo “In-App Purchase” e definiu o Callback URL do seu servidor
A comunicação utiliza SHA-1 para verificação, exemplo de código:
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("Algoritmo SHA-1 não encontrado", e); } }
Conexão do lado cliente:
- O cliente cria a ordem e envia
- Consulte
Client SDK - Conexão In-App
Conexão do lado servidor:
1. Quando o usuário compra com sucesso, Jogos envia callback de pagamento
Jogos envia callback para o Callback URL configurado
Header do request:
Campo Tipo Obrigatório Descrição Authorization string Sim Header para verificar sha1(body+SecretKey), sendo Shared Key do jogo Corpo do Request:
Campo Tipo Obrigatório Descrição paytype String Sim Tipo de notificação: pay (pagamento concluído) / refund (reembolso concluído) gameId int Sim ID do jogo orderId String Sim Número da ordem arrivedStatus int Sim Status de entrega: 0 não entregue, 1 entregue productId String Sim ID do produto createTime long Sim Horário de criação da ordem (Unix timestamp) payTime long Sim Horário do pagamento concluído (Unix timestamp) userId int Sim ID do usuário refundStatus int Opcional Status do reembolso: 0 em processamento, 1 concluído, 2 falhou, 3 rejeitado refundTime long Opcional Horário do reembolso (Unix timestamp) Exemplo:
javascript{ "gameId": 9968, "orderId": "zXhKYRy3genKKh9TgndBpu1gp5tBpA", "arrivedStatus": 0, "productId": "1002", "createTime": 1755657098, "payTime": 1755657115, "userId": 278, "refundStatus": null, "refundTime": null }
Response JSON (code:200 = sucesso)
json{ "code": "200", "msg": "Success" }
Códigos de erro:
305
parâmetros obrigatórios ausentes40001
jogo não encontrado41007
verificação falhou500
erro do sistema
2. Após a entrega do produto pelo servidor do jogo, atualize o status de entrega
URL: [POST] https://api.jogos.com/api/gamepay/webhook/arrivedorder
Header:
Campo Tipo Obrigatório Descrição Authorization string Sim Header para verificar sha1(body+SecretKey), sendo Shared Key do jogo Corpo do Request:
Campo Tipo Obrigatório Descrição gameId int Sim ID do jogo orderId int Sim Número da ordem Response JSON (code:200 = sucesso)
json{ "code": "200", "msg": "Success" }
Códigos de erro:
305
parâmetros obrigatórios ausentes40001
jogo não encontrado41007
verificação falhou500
erro do sistema