# SDK接入文档（服务端）

## 签名算法

我们采用两种签名算法，ServerKey用于充值回调及查询支付订单接口使用，AppKey用于验证登录usertoken是否有效接口使用。

1. ServerKey加签规则

将所有参数名按字母顺序进行排序，并将参数ServerKey(使用我方给定的ServerKey密钥)值以“&key=ServerKey”附加在排序后的参数串末尾，得到待签名字符串，再进行MD5签名，得到sign。

MD5签名采用标准MD5算法，得到32位大写的签名。

注意事项：ServerKey由我方提供，不以参数的形式传递，供MD5签名时使用，不可以泄漏到第三方，不可以保存在客户端，签名不能直接在客户端生成。

签名示例

假定serverKey=95974a4835f5121d3edeedd61ae27cea

> sign=md5(cpOrderId=123456789&gameId=10000&orderId=5770828&timestamp=1702364511034&key=95974a4835f5121d3edeedd61ae27cea)

得到sign=A32FB79A748BE888E877D9F5462ECFE5

2. AppKey加签规则

将所有参数以及appkey按照字母顺序进行排序后放到JSON中，得到待签名JSON字符串，再进行MD5签名，得到sign。

MD5签名采用标准MD5算法，得到32位大写的签名。

签名示例

假定appkey=95974a4835f5121d3edeedd61ae27cea

注意：usertoken为客户端登录返回的sign

> sign=md5({"appkey":"95974a4835f5121d3edeedd61ae27cea","gameid":"10000","timestamp":"20210421170511","usertoken":"af241d123bf36956d83eaaf31ba60a9c","useruid":"100012018092116430001992710"})

得到sign=2264F8A6B09B798BA7F3AFEA4BCD4646

## 接口列表

##### 一、充值回调（服务器）（必接）

充值通知游戏服务器 POST方式

给游戏服务器发送一个xml格式字符串参数示例：

    <xml>
      <orderId>100382</orderId>
      <userId>153</userId>
      <roleId>10086</roleId>
      <amount>1</amount>
      <return_code>SUCCESS</return_code>
      <out_order_id>12345</out_order_id>
      <game_server_id>23</game_server_id>
      <sign>4622824BC3749DCE900DCB3501AE4DDE</sign>
    </xml>

接受的xml字符串请自行屏蔽‘=’‘空格’等符号

参数说明

参数名 | 中文描述 | 类型 | 是否必填 | 参与签名
orderId | 我方提供给游戏方的订单id | Int | 必填 | 是
userId | 我方账号id | String | 必填 | 是
roleId | 游戏角色id | String | 必填 | 是
amount | 充值金额（单位分） | int | 必填 | 是
return_code | 充值成功返回SUCCESS | String | 必填 | 是
out_order_id | 游戏充值订单id | String | 必填 | 是
game_server_id | 游戏区服id | Int | 必填 | 是
sign | 签名 | String | 必填 | 否

Sign MD5加密字符串参数说明：

MD5签名规则

采用ServerKey加签规则，将所有参数名按字母顺序进行排序，并将参数ServerKey(使用我方给定的ServerKey)值以“&key=ServerKey”附加在排序后的参数串末尾，进行md5得到待签名字符串。

MD5签名采用标准MD5算法，得到32位大写的签名。

ServerKey由我方提供，不以参数的形式传递，供MD5签名时使用，不可以泄漏到第三方。

签名示例

sign=md5(amount=1&game_server_id=23&orderId=100382&out_order_id=12345&returnCode=SUCCESS&roleId=10086&userId=153&key=ServerKey)

注意事项：签名时应该使用returnCode，而不是xml的return_code

返回信息

游戏里面充值成功请返回 SUCCESS

其他情况返回FAIL

#####

##### 二、 查询游戏支付订单信息（可选）

请求地址：https://user-service.ldmnq.com/v3/cp/query-order

1) 请求方式

HTTP POST

Content-Type : application/json

2) 接口说明

当游戏合作商接收到"SDK服务器"支付回调后，为了防止因密钥泄露产生第三方恶意通知发货，游戏合作商可在收到支付回调请求后，调用此接口校验是否支付成功，验证成功后再进行发货。

3) 请求方

游戏服务器

4) 响应方

SDK服务器

5) 请求参数

参数 | 中文描述 | 类型 | 是否必填 | 参与签名
gameId | 我方提供给游戏方的游戏id | Integer | 必填 | 是
orderId | 我方提供给游戏方的订单id | String | 必填 | 是
cpOrderId | CP订单号 | String | 必填 | 是
timestamp | unix毫秒时间戳（1702364511034） | Long | 必填 | 是
sign | 签名 | String | 必填 | 否

参数示例：

    {
      "cpOrderId": "123456789",
      "gameId": 10000,
      "orderId": "5770828",
      "sign": "A32FB79A748BE888E877D9F5462ECFE5",
      "timestamp": 1702364511034
    }

6) sign加密规则

采用ServerKey加签规则，将所有参数名按字母顺序进行排序，并将参数ServerKey(使用我方给定的ServerKey)值以“&key=ServerKey”附加在排序后的参数串末尾，进行md5得到待签名字符串。

MD5签名采用标准MD5算法，得到32位大写的签名。

ServerKey由我方提供，不以参数的形式传递，供MD5签名时使用，不可以泄漏到第三方。

假定serverKey=95974a4835f5121d3edeedd61ae27cea

> sign=md5(cpOrderId=123456789&gameId=10000&orderId=5770828&timestamp=1702364511034&key=95974a4835f5121d3edeedd61ae27cea)

得到sign=A32FB79A748BE888E877D9F5462ECFE5

7) 响应内容(JSON格式)

参数 | 中文描述 | 类型
--- | --- | ---
code | 状态码 | Integer
msg | 响应说明信息，包括错误描述信息 | String
data | JSON格式数据 | Object

8) data对象说明

参数 | 中文描述 | 类型
--- | --- | ---
userId | 我方账号id | String
serverId | 用户下单区服标识 | String
roleId | 用户下单角色id | String
orderId | 我方提供给游戏方的订单id | String
cpOrderId | CP游戏订单号 | String
amount | 充值金额(单位：分) | Integer
payStatus | 支付状态(0:未支付 1:已支付 2:已退款) | Integer
notifyStatus | 通知状态(0:未通知 1:已通知) | Integer

9) code状态码说明

状态码 | 说明
0 | 成功
1 | 参数错误
404 | 参数签名检验失败

响应示例：

>     {
>       "code": 200,
>       "msg": "操作成功",
>       "data": {
>         "userId": "600012021111716300000000029",
>         "serverId": "23",
>         "roleId": "10086",
>         "orderId": "5770828",
>         "cpOrderId": "123456789",
>         "amount": 1,
>         "payStatus": 1,
>         "notifyStatus": 1
>       }
>     }

#####

##### 三、 验证登录usertoken 是否有效（可选）

验证URL：https://ldapi.ldmnq.com/ext/loginverify

1) 请求方式

HTTP post

Content-Type : application/json

2) 接口说明

验证usertoken是否为有效的登录用户会话，若有效则返回其账号登录标识。"游戏客户端"通过"SDK 客户端"获取到usertoken，传到"游戏服务器"，"游戏服务器"到"SDK 服务器"验证usertoken的有效性。

3) 请求方

游戏服务器

4) 响应方

SDK服务器

5) BODY请求参数

参数名 | 中文描述 | 类型 | 是否必填 | 参与签名
gameid | 我方提供给游戏方游戏id | String | 必填 | 是
useruid | 我方账号id | String | 必填 | 是
usertoken | 我方账号token | String | 必填 | 是
timestamp | 时间戳（20180921170511） | String | 必填 | 是
sign | 签名 | String | 必填 | 否

参数示例：

> {"gameid":"10000","usertoken":"af241d123bf36956d83eaaf31ba60a9c","useruid":"100012018092116430001992710","timestamp":"20210421170511","sign":"2264F8A6B09B798BA7F3AFEA4BCD4646"}

6) Sign加密规则

采用AppKey加签规则，将所有参数以及appkey按照字母顺序进行排序后放到JSON中，得到待签名JSON字符串，再进行MD5签名，得到sign。

MD5签名采用标准MD5算法，得到32位大写的签名。

假定appkey= 95974a4835f5121d3edeedd61ae27cea

sign 的签名规则：

Md5({"appkey":"xxx","gameid":"xxx","timestamp":"xxx","usertoken":"xxx","useruid":"xxx"});

假定appkey=95974a4835f5121d3edeedd61ae27cea

> sign=md5({"appkey":"95974a4835f5121d3edeedd61ae27cea","gameid":"10000","timestamp":"20210421170511","usertoken":"af241d123bf36956d83eaaf31ba60a9c","useruid":"100012018092116430001992710"})

得到sign=2264F8A6B09B798BA7F3AFEA4BCD4646

7) 响应内容(JSON)

>     {
>      "code":0,
>      "message":"用户已登陆"
>     }

code为状态码
message为状态码说明

状态码 | 说明
0 | 成功
1 | 参数错误
2 | Token验证失败
404 | 参数签名检验失败