跳到主要内容

后端接入文档

1 服务器域名地址

sdk服务器使用域名地址

api-sdk-gameplus.meetsocial.com

以下文档域名均以$MAIN_HOST代替,注:Content-Type: application/json

2 游戏服务器获取用户信息

​ 在sdk登陆回调成功后,使用返回数据UserInfo中的token字段向sdk服务器发送身份校验请求,游戏服务器直接使用身份校验返回的用户信息。

使用token获取用户信息curl示例

curl -X GET "https://$MAIN_HOST/auth/myProfile" -H "Authorization: token" -v

接口返回数据对象

字段描述类型
code状态码,200以外均为异常int
error错误类型stirng
message错误描述string
dataUserProfile对象object

UserProfile对象

字段描述类型
id平台应用下用户的唯一idlong
name唯一用户账户名string
isGuest是否游客(未绑定第三方账号为游客)boolean
agreementChecked是否同意协议boolean

3 支付成功回调验证

​ 使用sdk分配的secret密钥进行数据验签,按md5算法进行签名计算。签名相同即认为数据可信。

​ sdk服务器进行回调请求的超时时长为5秒,超时或其他情况导致回调失败都会进行重试。服务器将以1分钟为间隔重试10次,如果十次请求全部失败,则该订单视为掉单,需人工处理。

​ 游戏服务器收到回调后,只需向 SDK 服务器返回 HTTP 状态码 200 OK,并在响应 Body 中原样返回 JSON:{"result":"success"}(注意:该 JSON 外层不能有任何其他包裹内容,例如额外字段、嵌套结构或前后拼接文本),SDK 服务器即认为回调成功并终止重试(若响应中 result 值不是 “success”,则一律认为回调失败)

​ 另外,如重复收到同一笔支付回调(重复通知),也需要返回 HTTP 状态码 200 OK,并在响应 Body 中原样返回 JSON:{"result":"success"}(同样不能有任何外层包裹内容)。

​ 回调数据验签。

  1. 获取请求body中的json数据,进行反序列化处理。
  2. 读取json中signOrder字段,该字段中为签名字段名排列顺序。
  3. 将signOrder中字段值转化为字符串以&相隔连接,字段中不存在null值,类型一般为字符串和数字。
  4. 在最后拼接上&和secret,secret为应用申请时生成的secret密钥。
  5. 对连接的字符串进行md5散列摘要计算,并对结果进行base64编码。
  6. 比较base64编码结果与json中的sign字段值是否相同,相同说明内容未被篡改可以信任。
响应内容描述
{"result":"success"}或者{"result":"failure"}{"result":"success"}且HTTP状态码为200 OK表示处理订单成功,SDK服务端方收到响应success后不会再通知给cp方。failure失败(也可返回其他错误信息,收到{"result":"success"}以外的字符串后都会多次重复通知)。

java代码示例

@PostMapping("fakeServerResponse")//使用Post请求
@ApiOperation(value = "接收服务器订单支付回调", notes = "订单支付成功向游戏的回调数据")
public Map fakeServerResponse(HttpServletRequest request) throws Throwable {
// 服务器将对回调地址发送回调请求,被通知服务返回json: {"result":"success"} 且HTTP状态码为`200 OK`即认为回调成功
// 服务器五秒内会主动断开连接,超时即认为失败
// 失败后服务器会进行重试,间隔1分钟重试十次,之后将不进行通知

// 获取数据
byte[] bytes = new byte[request.getContentLength()];
request.getInputStream().read(bytes);
String data = new String(bytes, request.getCharacterEncoding());

Map map = objectMapper.readValue(data, Map.class);

// 使用md5和secret进行数据校验,secret为控制台应用中生成的密钥
// 获取数据签名的字段列
ArrayList<String> signOrder = (ArrayList<String>) map.get("signOrder");
Long appId = (Long) map.get("appId");
String sign = (String) map.get("sign");
String secret = "*****";

MessageDigest md5 = MessageDigest.getInstance("MD5");
StringBuilder stringBuilder = new StringBuilder();

// 拼接校验数据和secret
for (String s : signOrder) {
Object o = map.get(s);
stringBuilder.append(o.toString()).append("&");
}

stringBuilder.append(secret);

String signData = stringBuilder.toString();
String s = Base64.encodeBase64String(md5.digest(signData.getBytes()));

// 验证摘要值相同
assert s.equals(sign);
HashMap<String, Object> result = new HashMap<>();
// 向sdk服务器返回成功响应
result.put("result", "success");
return result;
}

回调数据示例

{
"event": "orderPayed",
"orderId": 100000000000000001,
"appId": 100000000000000002,
"createTime": "2026-01-01 12:00:00",
"productType": "GOOGLE",
"productCode": "item_01",
"originOrderId": "GPA.xxxx-xxxx-xxxx-xxxxx",
"originInfo": "{\"purchaseTimeMillis\":\"1700000000000\",\"purchaseState\":0,\"consumptionState\":0,\"developerPayload\":\"\",\"orderId\":\"GPA.xxxx-xxxx-xxxx-xxxxx\",\"purchaseType\":0,\"acknowledgementState\":1,\"kind\":\"androidpublisher#productPurchase\",\"obfuscatedExternalAccountId\":\"100000000000000001\",\"obfuscatedExternalProfileId\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"regionCode\":\"US\",\"productId\":\"item_01\"}",
"customInfo": "{\"amount\":1,\"developerPayload\":\"{\\\"characterId\\\":\\\"100000000000000003\\\",\\\"gameServer\\\":\\\"1\\\",\\\"orderId\\\":\\\"G20260101120000001\\\",\\\"extra\\\":\\\"any_custom_data\\\"}\",\"productId\":\"item_01\",\"productName\":\"示例商品\",\"roleInfo\":{\"roleId\":\"100000000001\",\"roleLevel\":\"1\",\"roleName\":\"PlayerName\",\"serverId\":\"1\",\"serverName\":\"server_name\",\"vipLevel\":\"0\"}}",
"signOrder": ["event", "orderId", "productType", "productCode", "originOrderId", "originInfo", "customInfo"],
"sign": "eHh4eHh4eHh4eHh4eHh4eA=="
}

回调数据字段

字段描述类型
signOrder签名字段顺序列表ArrayList<String>
productType商品类型,应用平台String
productCode各平台配置的应用内唯一编码String
originOrderId第三方平台生成的原始订单号String
originInfo第三方原始订单回调数据json string
orderId订单唯一编号Long
event固定值orderPayedString
customInfo用户上传的订单数据String
createTime创建时间String
appId应用唯一编号Long
sign签名String

customInfo参数说明:

字段描述类型
amount商品数量int
developerPayloadCP自定义透传字段,内容由客户端在发起支付时传入,SDK不做处理原样透传,可用于业务扩展校验String
productType商品类型String
productId商品IDString
productName商品名称String
roleInfo角色信息Object
提示

developerPayload 为CP自定义透传字段,需要客户端在调用SDK支付接口时主动传入。SDK不会对该字段做任何处理,支付成功后会原样回调给CP服务器。CP可利用该字段传递自定义业务数据(如内部订单号、角色信息等),以便在回调时进行业务关联和校验。

客户端传入方式请参考对应平台的接入文档:

roleInfo参数说明:

字段描述类型
roleId角色IDString
roleName角色名String
roleLevel角色等级String
serverName服务器名称String
vipLevelvip等级String