https://{base-url}文档目录
AG 游戏开放平台 API
V5.0.0通过游戏目录、游戏会话、单一钱包回调或转账钱包接口,将游戏平台能力接入现有系统。所有平台接口均使用 JSON 请求体;公共请求头与签名规则适用于每次请求。
application/json本页公开 endpoint 目录、签名方法、代表性字段和脱敏示例,用于技术评估。真实 Base URL、凭据、完整字段约束、最终 callback 清单和生产配置须通过受控接入流程确认;示例值均不是可用凭据,请勿通过公开联系渠道发送真实玩家或交易数据。
测试与正式环境配置应隔离。不要把签名密钥放入浏览器代码、客户端安装包、日志、工单或聊天记录;公开示例中的占位值不能直接用于生产。
最小请求示例
以下示例创建游戏会话。发送前,请使用最终 JSON 字符串计算签名。
curl --request POST 'https://{base-url}/game/v5/game/url' \
--header 'Content-Type: application/json' \
--header 'X-MERCHANT-CODE: {merchant-code}' \
--header 'X-TIMESTAMP: {timestamp}' \
--header 'X-NONCE: {nonce}' \
--header 'X-SIGN: {hmac-sha256-signature}' \
--header 'X-CONTENT-PROCESSING-TYPE: {processing-type}' \
--data-raw '{
"reqTraceId": "trace-demo-001",
"gameCode": "{game-code}",
"playerId": "player-demo-001",
"currencyCode": "{currency-code}",
"language": "zh-CN",
"terminalType": "PC",
"returnUrl": "https://{merchant-host}/lobby",
"ipAddress": "192.0.2.10"
}'鉴权与签名
签名类型固定为 HmacSHA256,公共头必须随请求一并发送。
公共请求头
| Header | 类型 | 必填 | 说明 |
|---|---|---|---|
X-MERCHANT-CODE | string | 是 | 平台分配的商户编码 |
X-TIMESTAMP | string | 是 | 发起请求时的时间戳 |
X-NONCE | string | 是 | 每次请求使用的随机字符串 |
X-SIGN | string | 是 | 使用 HmacSHA256 生成的请求签名 |
X-CONTENT-PROCESSING-TYPE | string | 是 | 内容处理类型,按接入配置传入 |
签名字符串
- 1
将请求体序列化为最终发送的 JSON 字符串
body。 - 2
严格按下列顺序拼接字段,不插入分隔符。
- 3
使用签名密钥执行 HMAC-SHA256,并将结果传入
X-SIGN。
参与签名的 body 必须与实际发送的请求体完全一致。重新格式化 JSON、改变字段顺序或空白后再发送,都可能产生 C10004。
import { createHmac } from "node:crypto";
const signType = "HmacSHA256";
const body = JSON.stringify(requestBody);
const signingText = merchantCode + timestamp + nonce + signType + body;
const signature = createHmac("sha256", secretKey)
.update(signingText, "utf8")
.digest("hex");公共响应
业务结果通过响应体中的 code 返回;不要只依据 HTTP 状态判断交易结果。
| 字段 | 类型 | 说明 |
|---|---|---|
code | string | 业务结果码 |
msg | string | 结果说明 |
success | boolean | 响应示例中的成功标记 |
data | object | 接口返回数据 |
{
"code": "C10000",
"msg": "Request succeeded",
"success": true,
"data": {}
}目录与典型接口
选择与商户钱包架构对应的接口组。所有平台接口均使用 POST。
游戏目录与会话
/game/v5/providers查询游戏供应商列表
/game/v5/categories查询游戏分类
/game/v5/games分页查询游戏列表
/game/v5/game/url创建玩家游戏会话并取得启动地址
/game/v5/player/force/logout强制结束玩家游戏会话
单一钱包回调
{MERCHANT-URL}/wallet/balance查询玩家钱包余额
{MERCHANT-URL}/player/info查询玩家资料
{MERCHANT-URL}/wallet/bet接收下注通知
{MERCHANT-URL}/wallet/win接收结算或下注结算通知
{MERCHANT-URL}/wallet/cancel接收订单取消通知
转账钱包
/game/v5/cash/deposit向玩家游戏钱包转入余额
/game/v5/cash/withdraw从玩家游戏钱包转出余额
/game/v5/cash/balance查询玩家游戏钱包余额
/game/v5/cash/transaction分页查询钱包交易记录
/game/v5/cash/force/withdraw/all强制转出玩家全部游戏钱包余额
记录与商户
/game/v5/game/record分页查询游戏记录
/game/v5/merchant/info查询当前商户配置与钱包信息
没有匹配的接口。
/wallet/bet 与 /wallet/cancel是否需要由商户实现,取决于实际接入配置与最终技术协议;联调前请确认回调清单。
POST/game/v5/game/url创建游戏会话
/game/v5/game/url创建游戏会话为指定玩家创建游戏会话,返回可用于启动游戏的地址。
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reqTraceId | string | 是 | 请求唯一标识;每次请求不可重复 |
gameCode | string | 是 | 游戏编码 |
playerId | string | 是 | 商户侧玩家唯一标识 |
currencyCode | string | 是 | 钱包币种编码 |
language | string | 是 | 游戏界面语言 |
terminalType | string | 否 | 终端类型:PHONE 或 PC;默认 PHONE |
returnUrl | string | 否 | 玩家退出游戏后的返回地址 |
ipAddress | string | 是 | 玩家 IPv4 或 IPv6 地址 |
subMerchantCode | string | 否 | 子商户编码;不可包含下划线 |
nickName | string | 否 | 玩家昵称 |
avatarUrl | string | 否 | 玩家头像地址 |
{
"reqTraceId": "trace-demo-001",
"gameCode": "{game-code}",
"playerId": "player-demo-001",
"currencyCode": "{currency-code}",
"language": "zh-CN",
"terminalType": "PC",
"returnUrl": "https://{merchant-host}/lobby",
"ipAddress": "192.0.2.10"
}{
"code": "C10000",
"msg": "Request succeeded",
"success": true,
"data": {
"gameCode": "{game-code}",
"playerId": "player-demo-001",
"gameUrl": "https://{game-launch-host}/session/{token}",
"expireTime": "2026-08-08T10:30:00Z"
}
}响应数据
| 字段 | 类型 | 必返 | 说明 |
|---|---|---|---|
data.gameCode | string | 是 | 游戏编码 |
data.playerId | string | 是 | 玩家标识 |
data.gameUrl | string | 是 | 游戏启动地址 |
data.expireTime | string | 否 | 会话过期时间 |
POST{MERCHANT-URL}/wallet/win钱包结算回调
{MERCHANT-URL}/wallet/win钱包结算回调单一钱包模式下,平台向商户钱包发送派彩或下注结算通知。商户应以交易标识实现幂等处理,并在响应中返回处理后的余额。
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reqTraceId | string | 是 | 请求唯一标识 |
playerId | string | 是 | 商户侧玩家唯一标识 |
currencyCode | string | 是 | 钱包币种编码 |
gameCode | string | 是 | 游戏编码 |
transactionId | string | 是 | 平台交易唯一标识 |
roundId | string | 是 | 游戏局唯一标识 |
betId | string | 是 | 关联下注标识 |
betAmount | string | 是 | 本次下注金额 |
winAmount | string | 是 | 本次派彩金额 |
isFree | boolean | 是 | 是否为免费游戏产生的记录 |
isEnd | boolean | 是 | 当前游戏局是否结束 |
betTime | string | 是 | 下注时间 |
settledTime | string | 是 | 结算时间 |
type | string | 是 | 通知类型:win 或 bet_win |
{
"reqTraceId": "trace-demo-002",
"playerId": "player-demo-001",
"currencyCode": "{currency-code}",
"gameCode": "{game-code}",
"transactionId": "txn-demo-002",
"roundId": "round-demo-001",
"betId": "bet-demo-001",
"betAmount": "10.00",
"winAmount": "18.50",
"isFree": false,
"isEnd": true,
"betTime": "2026-08-08T10:00:00Z",
"settledTime": "2026-08-08T10:00:08Z",
"type": "bet_win"
}{
"code": "C10000",
"msg": "Request succeeded",
"success": true,
"data": {
"merchantBetId": "merchant-bet-demo-001",
"balance": "108.50"
}
}POST/game/v5/cash/deposit转入游戏钱包
/game/v5/cash/deposit转入游戏钱包转账钱包模式下,将指定金额从商户侧转入玩家游戏钱包。
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reqTraceId | string | 是 | 请求唯一标识;用于请求追踪 |
playerId | string | 是 | 商户侧玩家唯一标识 |
currencyCode | string | 是 | 钱包币种编码 |
amount | string | 是 | 转入金额 |
merchantTransactionId | string | 是 | 商户侧交易唯一标识;用于交易核对 |
{
"reqTraceId": "trace-demo-003",
"playerId": "player-demo-001",
"currencyCode": "{currency-code}",
"amount": "100.00",
"merchantTransactionId": "merchant-txn-demo-001"
}{
"code": "C10000",
"msg": "Request succeeded",
"success": true,
"data": {
"balance": "100.00"
}
}为每次转账生成唯一的 merchantTransactionId,并保留请求与业务结果,便于通过交易查询接口核对最终状态。
POST/game/v5/game/record查询游戏记录
/game/v5/game/record查询游戏记录按时间范围分页查询玩家的下注与派彩记录。
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reqTraceId | string | 是 | 请求唯一标识 |
pageNum | integer | 是 | 页码 |
pageSize | integer | 是 | 每页记录数 |
reqData.startTime | string | 是 | 查询开始时间 |
reqData.endTime | string | 是 | 查询结束时间 |
sort | string | 否 | 排序方式 |
{
"reqTraceId": "trace-demo-004",
"pageNum": 1,
"pageSize": 50,
"reqData": {
"startTime": "2026-08-08T00:00:00Z",
"endTime": "2026-08-08T23:59:59Z"
},
"sort": "DESC"
}{
"code": "C10000",
"msg": "Request succeeded",
"success": true,
"data": {
"gameRecordList": [{
"orderNo": "order-demo-001",
"playerId": "player-demo-001",
"betAmount": "10.00",
"winAmount": "18.50",
"betTime": "2026-08-08T10:00:00Z",
"winTime": "2026-08-08T10:00:08Z",
"gameCode": "{game-code}",
"currencyCode": "{currency-code}",
"roundId": "round-demo-001"
}]
}
}技术常见问题
汇总签名、钱包、幂等、超时与会话查询中最常见的联调问题。
AG API 如何生成请求签名?
先将最终发送的请求体序列化为 body,再按 merchantCode + timestamp + nonce + signType + body的顺序拼接,不加入分隔符。signType 固定为 HmacSHA256;使用签名密钥计算 HMAC-SHA256 后,将结果放入 X-SIGN。参与签名的 body 必须与实际发送内容完全一致。
为什么会返回 C10004?
C10004 表示签名校验失败。优先检查商户编码、时间戳、nonce、签名密钥和固定的HmacSHA256类型,再确认参与签名的 JSON 字符串没有被中间件重新序列化、调整字段顺序或改变空白。排查时应保留reqTraceId 和请求时间,但不要记录签名密钥。
单一钱包和转账钱包有什么区别?
单一钱包模式由商户维护玩家余额,平台通过余额、下注和结算等回调与商户钱包协作。转账钱包模式则由商户调用/game/v5/cash/deposit、/game/v5/cash/withdraw等接口,在商户系统与玩家游戏钱包之间转入或转出资金。实际使用哪一种模式由商户接入配置决定,不应在同一交易流程中自行混用。
钱包回调重复发送时应该如何处理?
商户应以 transactionId作为回调交易的幂等判断依据。同一交易再次到达时,应返回先前已经确认的处理结果和余额,不要再次扣款或加款;同时保留请求、业务结果和最终余额,便于对账。/wallet/bet 与 /wallet/cancel 是否需要接入,仍以商户最终回调清单为准。
转账请求超时后是否可以直接重试?
不建议在结果未知时直接生成新交易并重复转账。应先使用原 merchantTransactionId 调用 /game/v5/cash/transaction查询交易结果,再依据最终技术协议决定是否重发。这样可以避免首次请求已经成功、但响应在网络中丢失时产生重复记账。
reqTraceId 和 merchantTransactionId 分别有什么作用?
reqTraceId是每次请求的唯一追踪标识,用于关联调用日志和定位一次请求;即使重试,也应按请求维度生成和记录。merchantTransactionId 是商户侧交易唯一标识,用于转账对账、结果查询和防止同一业务交易被重复处理。两者作用不同,不能相互替代。
如何创建玩家游戏会话?
先从游戏目录取得可用的 gameCode,准备玩家标识、币种、语言和 IP 地址,然后携带公共请求头调用/game/v5/game/url。成功响应会返回 gameUrl,以及可选的 expireTime;客户端应在会话有效期内打开该地址。
如何查询玩家的游戏记录?
调用 /game/v5/game/record,传入 pageNum、pageSize 和 reqData.startTime、reqData.endTime 时间范围;需要时可传 sort。从响应的 gameRecordList 读取订单、玩家、下注额、派彩、游戏编码和局号等记录,并按分页持续查询。
错误码
记录 reqTraceId、业务错误码和请求时间,以便快速定位问题。
| Code | Message | 处理建议 |
|---|---|---|
C10000 | Request succeeded | 请求成功 |
C10001 | Base service exception | 基础服务异常 |
C10002 | Request parameter error | 检查请求字段与数据类型 |
C10003 | Invalid request header | 检查五个公共请求头 |
C10004 | Signature error | 检查签名顺序、密钥与原始请求体 |
C20001 | Merchant code absent | 检查商户编码 |
G10001 | Game service exception | 游戏服务异常 |
G20001 | Player ID empty | 补充 playerId |
G20002 | Game ID absent | 检查游戏编码 |
G20003 | Game offline | 游戏已下线或不可用 |
G30001 | Game user session expired | 重新创建游戏会话 |
G30002 | Merchant balance insufficient | 商户余额不足 |
G30003 | Player balance insufficient | 玩家余额不足 |
G40001 | Third-party service exception | 第三方服务异常 |
联调检查
以下控制须在最终项目协议中确认,并在切换正式环境前完成测试;本页不表示服务端已经启用这些控制。
- ✓
请求可追踪且日志最小化:每次调用生成唯一
reqTraceId;日志仅保留排障所需的时间、结果码与脱敏标识,不记录密钥、完整签名、token、玩家资料或完整交易载荷。 - ✓
签名可复现:签名输入与发送的 JSON 字符串完全一致,测试用例覆盖
C10004。 - ✓
防重放规则明确:确认时间戳允许偏差、
nonce唯一性与重复请求拒绝策略,并覆盖过期、复用和并发场景。 - ✓
授权与资源限制明确:按商户校验 endpoint、钱包与数据访问权限,并确认频率、并发、分页和交易额度限制及告警策略。
- ✓
交易可幂等:钱包通知与转账按交易标识去重,重复请求不会重复记账。
- ✓
结果可核对:超时或网络异常时,先查询交易结果,再决定是否重试。
- ✓
金额使用定点数:不要使用二进制浮点数处理余额、下注额和派彩金额。
