生码方 = 扣分方 | 兑码方 = 加分方
req → 我扣我这边,返回 200 + 应增记的分数反方向完全对称:你把码给我 → 我调你的 req → 我加。两边各自记账,凭据不互传。
| 项目 | 值 |
|---|---|
| 地址 | POST https://api.hi0357.com/points/bridge |
| 鉴权 | 请求头 X-Bridge-Key: <密钥>(由 Roast 线下给) |
| 内容类型 | application/json |
| 比例 | 1 : 1 |
| 单笔上限 | 10000(不接受 0 与负数) |
| 码有效期 | 接口生成:24 小时(可传 ttl 覆盖,ttl=0 表示无期限)★ 网页上手动生成的不设期限(长期有效) |
| 时钟宽限 | ±10 分钟(只对"设了期限"的码生效;网页手生的码不受影响) |
| 码格式 | CG- + 16 位 36 进制大写,例:CG-P4A99GS8NGO0F1O8 |
{
"action": "gen",
"user_id": 1008, // 发起人(扣的就是他)
"amount": 123, // 金额,1 ~ 10000
"ttl": 86400, // 可选:有效期秒数;不传=默认 24 小时,传 0 = 无期限
"note": "送你的" // 可选,备注
}
{
"ok": true,
"code": "CG-P4A99GS8NGO0F1O8",
"amount": 123,
"expires_at": 1791118977,
"ttl": 86400,
"remaining_points": 500, // ★ 你当前余额(生码不扣,给前端显示/更新用)
"note": "把这一串给对方,对方凭它来兑(一次有效,长期内)"
}
注意生码不预扣、不锁额 —— 只在生成时校一次余额(不够不发码)。真正的扣分发生在兑付那一刻。
{
"action": "req",
"api": "CG-P4A99GS8NGO0F1O8" // 要兑的码
}
{
"ok": true,
"code": "CG-P4A99GS8NGO0F1O8",
"amount": 123,
"gain": 123, // ★ 你需要给对方加多少分(= amount)
"issuer_id": 1008,
"remaining_points": 4877, // ★ 剩余积分(发起人扣完后的余额,前端更新用)
"balance_after": 4877,
"used_at": 1791032577
}
一次性兑成功后码立即作废(同一码再兑一律 409)。
{ "action": "info", "api": "CG-P4A99GS8NGO0F1O8" }
{ "ok": true, "code": "...", "amount": 123, "issuer_id": 1008,
"created_at": 1791032577, "expires_at": 1791118977,
"used": 0, "result_code": 0 }
| 码 | 含义 | 是否动账 |
|---|---|---|
| 200 | 成功:发起端已扣 | 已扣 ✔ |
| 403 | 余额不足(结算时发起端不够) 响应里带 remaining_points(当前余额)与 need(还差多少) | 不动账,码作废 |
| 404 | 不存在此码 | 不动 |
| 402 | 该码已过期(仅对"接口生成的、设了期限的"码可能返回) | 不动 |
| 400 | 参数缺失 / 格式错(含非正数、超 10000) | 不动 |
| 409 | 该码已被使用 | 不动 |
判定优先级:409 > 402 > 404 > 403 > 400
即:先看码本身能不能用 → 再看钱够不够 → 最后才看参数。
两道阑:生码时先拦一道(不够不发码)| 结算时再兜一道(不够就 403)。
UPDATE ... WHERE used=0 兜底,禁止“先查后写”。gen 一个 1 分的码 → 用 info 看看它正常 → 再 req 兑掉。