pay_success 事件仅用于刷新 UI,不得作为发货依据。宿主 App → 游戏大厅(同源 H5)→ SDK → 宿主收银台 → 平台订单中心 → CP 游戏服务器发货。
玩家点击购买
→ SDK.pay / CP 服务端 /sdkopen/order/create 创建订单(CREATED)
→ 宿主收银台扣款,回调 POST /api/host/notify 订单(PAID)
→ 平台按标准协议 POST {DeliverURL} 订单(DELIVERED)
→ 失败自动进入 9 次递增重试队列 → 死信人工补偿
→ 租户财务发起退单 → 宿主退款 → 订单(REFUNDED / PARTIAL_REFUNDED)
→ 次月 10 号按订单费率快照生成结算单参与签名的字段按 key 升序 排列,用 k=v 以 & 拼接,末尾追加 &key=md5(appKey),再对整串取 MD5(小写 hex)。
raw = "amount=600&appId=guess&cpOrderId=CP001&playerId=P001&productId=diamond_1&key=" + md5(appKey) sign = md5(raw)
密钥轮换期间平台同时接受新旧两把 key 验签(双 key 并行),但签名生成始终只用新 key,厂商可平滑切换。
| 接口 | 用途 | 关键参数 |
|---|---|---|
POST /api/cp/pay/create | 创建支付单 | appId / playerId / cpOrderId / productId / amount(分) / sign,可选 tenant_code |
GET /api/cp/order | 订单查询 | orderId 或 cpOrderId + appId |
POST /api/cp/deliver/retry | 申请重发发货回调 | orderId |
POST /api/sdkopen/token/verify | 校验玩家 token | token / appId / sign |
POST /api/sdkopen/user/profile、/user/check | 玩家档案 / 存在性 | playerId / appId / sign |
POST /api/sdkopen/role/query | 角色查询 | playerId / appId / sign |
POST /api/sdkopen/order/create、/order/query、/order/confirm | 下单 / 查单 / 确认 | 同上 + 订单字段 |
POST /api/sdkopen/deliver/retry | 发货重试 | orderId / sign |
创建订单时若传 tenant_code,平台会校验它与 appId 所属租户一致,不一致直接拒绝。响应中也返回该字段。用于未来放开「跨租户同名 appId」时消除路由歧义;当前业务层仍保证 appId 全局唯一。
平台向租户后台登记的 DeliverURL 发起 application/x-www-form-urlencoded POST:
orderId=O...&playerId=P...&orderFee=600
厂商服务端必须返回纯文本 success(大小写不敏感)才算成功,其余任何响应或超时均视为失败。
重试序列:5s / 15s / 30s / 1m / 3m / 10m / 30m / 60m / 2h,共 9 次;每次尝试写 delivery_logs;死信可在租户后台改地址后重发或标记线下已处理。
引入同源 /sdk/sdk.js,全局对象 SaaSGameSdk:
SaaSGameSdk.init({ appId: 'guess' })
SaaSGameSdk.login() // 宿主免登优先,外部浏览器降级 OAuth
SaaSGameSdk.reportRole({ roleId, roleName, roleLevel, serverId, serverName })
SaaSGameSdk.pay({ productId, productName, amount, cpOrderId })
SaaSGameSdk.getOrder(orderId)
SaaSGameSdk.createTicket({ subject, content })
同源是硬性要求:SDK、大厅、游戏页共享 localStorage 中的玩家 token,因此静态资源由 Go 单进程托管,不单独部署前端域名。聊天上报走 POST /api/sdk/chat。
CREATED → PAYING → PAID → DELIVERED
└→ PARTIAL_REFUNDED → REFUNDED
支付回调幂等:重复回调因状态机被拒绝;发货由队列保证最终一致。订单记录 user_id、refunded_amount 与 fee_rate_snapshot(下单瞬间的三方分账费率 JSON)。
按应用配置平台技术服务费 / 租户分成 / CP 分成,单位万分比,合计必须 = 10000(默认 1000 / 1000 / 8000)。
| 码 | 含义 |
|---|---|
| 0 | 成功 |
| 1001 / 1002 / 1003 / 1004 / 1005 | 参数错误 / 未登录 / 无权限 / 资源不存在 / 服务内部错误 |
| 2001 ~ 2004 | 账号密码错误 / 宿主凭证无效 / 凭证过期 / 签名校验失败 |
| 3001 ~ 3003 | 应用不存在 / 已停用 / appKey 无效 |
| 4001 ~ 4005 | 订单不存在 / 状态不合法 / 金额不一致 / 重复订单 / 渠道未就绪 |
| 5001 ~ 5003 | 礼包码无效 / 已使用 / 已领完 |
| 6001 ~ 6003 | 任务不存在 / 未完成 / 奖励已领取 |
success。APP_ENV=production、ALLOW_TENANT_PARAM=0、关闭演示发货语义。X-Tenant-Id 一律无效。docs/00-总体方案.md(业务与决策)、docs/01-Go技术架构.md(工程)、docs/02-...规划.md(隔离与装修)、docs/03-...落地.md(上线加固)、docs/04-SDK接入文档(CP版).md(SDK 与 OpenAPI)、docs/05-...闭环.md(资金闭环与运营补齐)。