运营方钱包接口指南
运营方钱包接口由 Star Game 平台调用、部署在你的后端。基础地址由你决定(例如 https://api.example.com/game-wallet/v1),作为「钱包 URL」在「商户控制台 → 接入」按环境分别填写。完整的机器可读契约见 OpenAPI 参考(英文)。
- 仅 HTTPS,JSON(UTF-8),字段
snake_case。忽略不认识的字段:新增字段不算破坏性变更。 - 每个请求都带签名(见签名)。
amount与balance是最小单位整数的十进制字符串("1500"),格式^-?[0-9]{1,19}$。币种和小数位以你在「商户控制台 → 接入」的配置为准。- 所有 ID 都是字符串;时间是 RFC 3339 UTC。
- 整体请求失败用 HTTP 状态码 +
application/problem+json(RFC 9457)。
| 方法 | 路径 | 用途 |
|---|---|---|
POST |
/players/authenticate |
用启动码换玩家与会话 |
POST |
/players/balance |
查询玩家当前余额 |
POST |
/transactions |
批量处理 1–500 笔扣款、加款、冲正 |
GET |
/transactions/{transaction_id} |
查询单笔交易(审计与客服) |
POST /players/authenticate
Section titled “POST /players/authenticate”每次启动游戏时调用一次,参数是你的 App 通过 getConfig 传入的启动码。
POST /game-wallet/v1/players/authenticate HTTP/1.1Host: api.example.comContent-Type: application/jsonwebhook-id: msg_3f9a0c1e5b7d4e2a9c8b6a4f2e1d0c9bwebhook-timestamp: 1791763200webhook-signature: v1,K5o0…=
{"launch_code":"lc_7Qm2…","game_id":"lantern","client_ip":"203.0.113.24"}{ "player_id": "84021734", "session_id": "gs_1c9e…", "display_name": "Layla", "avatar_url": "https://cdn.example.com/a/84021734.png", "currency": "GOLD", "balance": "250000", "language": "ar", "country": "SA"}player_id、session_id、currency、balance 为必填。启动码未知、已使用或已过期 → 401 problem,code: "invalid_launch_code"。
POST /players/balance
Section titled “POST /players/balance”{ "player_id": "84021734", "session_id": "gs_1c9e…" }{ "balance": "248500", "currency": "GOLD" }玩家不存在 → 404 player_not_found。请求带有有效 session_id 时请延长该会话。
POST /transactions
Section titled “POST /transactions”一批 1–500 笔交易(不超过你配置的单批最大笔数)。
{ "transactions": [ { "transaction_id": "lantern:59666:84021734:bet", "type": "debit", "player_id": "84021734", "session_id": "gs_1c9e…", "amount": "1500", "currency": "GOLD", "game_id": "lantern", "round_id": "lantern:59666", "room_id": "8880085", "created_at": "2026-10-12T13:00:18Z", "details": { "bets": [{ "option": "rose", "amount": "1000" }, { "option": "phoenix", "amount": "500" }] } }, { "transaction_id": "lantern:59665:84021734:win", "type": "credit", "player_id": "84021734", "amount": "4500", "currency": "GOLD", "game_id": "lantern", "round_id": "lantern:59665", "reference_transaction_id": "lantern:59665:84021734:bet" }, { "transaction_id": "lantern:59664:84021734:bet:rollback", "type": "rollback", "player_id": "84021734", "game_id": "lantern", "round_id": "lantern:59664", "reference_transaction_id": "lantern:59664:84021734:bet" } ]}返回 200,按请求顺序逐项给出结果:
{ "results": [ { "transaction_id": "lantern:59666:84021734:bet", "status": "ok", "balance": "248500", "processed_at": "2026-10-12T13:00:18Z" }, { "transaction_id": "lantern:59665:84021734:win", "status": "ok", "balance": "253000", "processed_at": "2026-10-12T13:00:18Z" }, { "transaction_id": "lantern:59664:84021734:bet:rollback", "status": "ok", "balance": "253000", "processed_at": "2026-10-12T13:00:18Z" } ]}| 字段 | 适用类型 | 说明 |
|---|---|---|
transaction_id |
全部 | 全局唯一,≤ 128 字符,是你的幂等键 |
type |
全部 | debit、credit 或 rollback |
player_id、game_id |
全部 | 必填 |
session_id |
debit | authenticate 返回的会话 |
amount、currency |
debit、credit | 字符串形式的最小单位金额 |
round_id |
全部 | 把同一局的所有交易归在一起 |
room_id |
可选 | 玩家所在房间(如有) |
reference_transaction_id |
rollback(必填)、credit(可选) | 要冲正的扣款 / 本次派彩对应的扣款 |
created_at |
可选 | 平台创建该交易的时间 |
details |
可选 | 给客服工具看的可读明细,按不透明数据处理 |
status |
含义 | 是否记账 | 平台动作 |
|---|---|---|---|
ok |
本次或此前已记账(无可冲正内容的冲正也返回 ok) |
是 / 已记 | 完成 |
insufficient_funds |
扣款被拒,请带上 balance |
否 | 投注作废 |
session_invalid |
仅扣款:会话已结束或无效 | 否 | 投注作废 |
player_blocked |
仅扣款:玩家不允许游戏 | 否 | 投注作废 |
limit_exceeded |
仅扣款:触发你的限额或风控 | 否 | 投注作废 |
duplicate_mismatch |
同一 transaction_id,内容不同 |
否 | 告警,人工跟进 |
reference_not_found |
加款引用的扣款从未记账或已冲正 | 否 | 不派彩,留记录 |
rolled_back |
扣款晚于其冲正到达(墓碑) | 否 | 投注作废 |
retry |
暂时失败(锁超时等) | 否 | 以同一交易号重发 |
GET /transactions/{transaction_id}
Section titled “GET /transactions/{transaction_id}”仅用于审计和客服,平台在资金主流程中不使用它。
{ "transaction_id": "lantern:59666:84021734:bet", "type": "debit", "status": "ok", "amount": "1500", "balance": "248500", "rolled_back": false, "processed_at": "2026-10-12T13:00:18Z"}从未收到 → 404 transaction_not_found。
错误(problem+json)
Section titled “错误(problem+json)”整体请求失败时返回非 2xx 状态码和 RFC 9457 响应体。平台读取 HTTP 状态码与 code;type 可以是你喜欢的任意 URI。
HTTP/1.1 429 Too Many RequestsContent-Type: application/problem+jsonRetry-After: 2
{"type":"https://api.example.com/problems/rate_limited","title":"Too many requests","status":429,"code":"rate_limited","detail":"slow down"}code |
HTTP | 何时返回 |
|---|---|---|
invalid_signature |
401 | 签名缺失、错误或过期 |
invalid_launch_code |
401 | 启动码未知、已使用或已过期 |
malformed_request |
400 | 请求体不符合契约 |
player_not_found |
404 | 查询不存在玩家的余额 |
transaction_not_found |
404 | GET /transactions/{id} 从未收到 |
not_found |
404 | 路径不存在 |
rate_limited |
429 | 请带 Retry-After |
unavailable |
503 | 整批结果未知;请带 Retry-After |
internal |
500 | 意外错误 |
平台对 408、429、5xx 和超时使用相同的交易号重试。详见错误码与限流。
在「商户控制台 → 接入」(「沙盒」或「生产」标签页)的「钱包」卡片中声明:
| 设置 | 范围 | 作用 |
|---|---|---|
| 最大批量 | 1–500 | 一次 POST /transactions 不会超过这个笔数 |
| 最大并发请求 | 1–16 | 平台对你的钱包同时在途的请求不会超过这个数 |
| 币种 | A–Z、0–9,2–8 位 |
作为扣款、加款的 currency 发送 |
| 小数位 | 0–8 | 最小单位与显示金额的换算 |
请按高峰来设定:热门对局下注期结束时,大量玩家会在一两秒内被扣款。你返回 429 或 503 时,平台按 Retry-After 退避。
每个请求都带三个头部(Standard Webhooks):
webhook-id: msg_<random> unique per HTTP attemptwebhook-timestamp: <unix seconds>webhook-signature: v1,<base64(HMAC-SHA256(key, id + "." + timestamp + "." + raw_body))>key 是 whsec_… 密钥去掉前缀后 base64 解码得到的字节。拒绝与本机时钟相差超过 300 秒的时间戳。密钥轮换期间,签名头会带多个以空格分隔的签名,任一匹配即通过。完整说明和五种语言的已测试代码见签名校验。