1. 业务防乱(专属通道锁定):提货页面一旦生成二维码后,直接禁用'重新生成二维码'按钮并锁定游戏UID输入框,杜绝Token浪费与绑定混乱; 2. 频控治理(前端3秒冷却):手动点击'检查扫码状态'增加3秒倒计时防抖冷却,且对'过于频繁/110001'错误进行平滑提示,不再触发大红报错; 3. 频控治理(后端瞬时防抖与软降级):RockService增加800ms内存并发安全防抖缓存,当上游返回110001时自动优雅降级返回等待扫码状态,不抛出HTTP 400错误。
33 KiB
Rock发货平台 (0666.pro) 代理接入与库存风控实施方案
编制日期:2026-10-05
指导原则:
- 后台全反代,买家/打手对上游完全无感(底层对接全部在后端完成,对外输出完全符合既有系统规范)。
- Token 一次性绑定不可换绑,设立 UID 强一致防御门禁(前置填 UID,阻断混淆旧数据,UID 不符绝对禁止领取)。
- 本地库存池机制,支持批量采购、安全水位预警与自动补货。
- 先规划设计,严格门禁验证,暂不急于修改既有 Provider。
一、 核心需求解构与风险防御矩阵
| 序号 | 需求要点 | 业务痛点 / 致命风险 | 应对防御方案 | 确信度 |
|---|---|---|---|---|
| REQ-1 | 后台做代理,用户无感上游 | 若直接下发 0666 链接,买家会发现源头平台;且数据结构不一致破坏现有前端逻辑。 | • 后端封装中转代理,对外暴露统一的订单提货 API; • 二维码仅输出腾讯官方活动链接( gp.qq.com),买家端完全无第三方痕迹;• 数据字段对齐既有 DeliveryOrderInfo 与 DeliveryBindResult。 |
100% |
| REQ-2 | Token 无法换绑,绑定即作废 | 买家若扫错游戏账号,或乱扫码,该 Token 直接报废(21 积分/个损失),且无法解绑。 | • 前置输入门禁:生成二维码前,强制买家输入/确认游戏角色 UID; • UID 强一致校验:扫码后捕获角色 UID,不等于预期 UID 严禁发货; • 阻断错误发货,保留 Token 供售后人工处理。 |
100% |
| REQ-3 | 上游旧绑定信息防混淆 | 0666 平台下发 Token 或刚 refresh 时可能残留历史账号信息(previous_bound_account / 历史记录),容易被误判为“已绑定”。 |
• 基线快照比对(Baseline Snapshotting):分配 Token 时抓取初始绑定快照; • 仅当检测到买家扫码产生新的绑定事件且角色 UID 完全吻合时,才跃迁为 bound 状态。 |
100% |
| REQ-4 | 后台批量采购与统一通用库存池 | 提取 Token 默认统一下单为“黑色通用 Token”(对应界面 1 = 黑色),该链接本身不预先区分黑蓝,是一个通用兑换凭证。 |
• 建立本地统一的 rock_tokens 通用库存池,无需双池割裂;• 后台一键采购 50 个通用 Token 存入库存; • 发货时直接从通用池中锁定分配,零网络延迟。 |
100% |
| REQ-5 | 安全水位告警与自动采购 | 库存用尽导致订单积压失败。 | • 设置通用 Token 低库存预警阈值(如低于 10 个); • 接入系统既有通知渠道(飞书、钉钉、企微机器人等); • 支持配置开关:低于阈值自动调用上游采购补充 50 个。 |
100% |
| REQ-6 | 黑蓝区分时机:绑定后发货前动态选择 | 买家购买不同商品(黑色ROCK或蓝色运动服),上游链接本身无区别,何时决定发放黑色还是蓝色? | • 延后到发货阶段决策(Late-Binding Selection): • 买家扫码通过 UID 强一致门禁后,系统根据订单商品的 SKU 属性,在最终调用兑换接口时自动填充对应 skin:- 黑色商品传 "skin": "黑色ROCK长袖T恤"- 蓝色商品传 "skin": "蓝色运动服上衣" |
100% |
| REQ-7 | 绑定错误独立统计与追溯 | 买家扫错账号或扫了他人账号,虽然被系统阻断未发货,但该 Token 已无法在 0666 换绑,需明确统计损耗与售后责任。 | • 独立状态与指标面板:Token 标记为 mismatch(绑定错误),后台大屏卡片高亮统计“绑错数量”;• 全要素审计快照:完整记录买家填写的 expected_uid 与扫码实际捕获的 actual_role_id、角色名、大区、发生时间,支持一键导出与人工处理。 |
100% |
| REQ-8 | Rock 自动发货全局总开关 | 遇到上游接口波动、积分不足、Token 缺货或价格调整时,需一键熔断。 | • 配置全局熔断开关 rock_auto_delivery_enabled;• 一旦关闭:黑色ROCK与蓝色运动服两个商品彻底停走自动发货通道,直接降级为人工打手抢单或客服处理,避免错单穿透。 |
100% |
二、 系统架构与发货时序图
2.1 整体流程时序图(全反代 + UID 强校验)
sequenceDiagram
autonumber
actor Buyer as 买家 / 发货员
participant Dash as Affiliate-Dash 后台
participant Pool as 本地 Token 库存池
participant Rock as 0666.pro 平台
participant Tencent as 和平精英官方 (gp.qq.com)
Note over Buyer, Dash: 第零阶段:全局自动发货总开关检查 (Kill Switch)
Buyer->>Dash: 打开提货页 /delivery/:orderNo
alt rock_auto_delivery_enabled == false (总开关已关闭)
Dash-->>Buyer: ⚠️ 该商品自动发货维护中,已转交人工客服/打手为您处理
else rock_auto_delivery_enabled == true (允许自动发货)
Note over Buyer, Dash: 第一阶段:前置输入 UID 锁定
Dash-->>Buyer: 展示商品信息,要求确认/输入游戏角色 UID
Buyer->>Dash: 提交预期游戏 UID (例如: 4331027062)
Note over Dash, Pool: 第二阶段:本地通用池分配 Token
Dash->>Pool: 锁定 1 个可用的通用 Token (默认黑色通用凭证)
Pool-->>Dash: 返回 Token 记录 (包含 redeem_code, bindUrl)
Dash->>Dash: 记录 Token 初始状态快照 (排除上游历史旧信息)
Dash-->>Buyer: 展示腾讯官方绑定二维码 (绝无 0666 标识)
Note over Buyer, Tencent: 第三阶段:买家微信/QQ 扫码授权
Buyer->>Tencent: 手机扫码授权登录并绑定角色
Note over Dash, Rock: 第四阶段:轮询与 UID 强一致门禁
loop 每 2~3 秒轮询
Dash->>Rock: POST /api/user/tokens/{id}/refresh
Rock-->>Dash: 返回 binding 信息 (role, roleId, region)
end
alt 实际 roleId != 预期 UID (扫错账号)
Dash->>Dash: 触发硬阻断!标记 deliveryStageBindMismatch
Dash->>Pool: 将该 Token 状态标记为 mismatch (绑定错误),记录扫码角色与时间进入统计池
Dash-->>Buyer: ⚠️ 绑定角色与订单 UID 不符,已阻断发货,请联系客服处理
else 实际 roleId == 预期 UID (校验通过)
Dash->>Dash: 状态变更为 bound,核验通过
Dash-->>Buyer: 角色匹配成功 (唉终章 / 4331027062)
Note over Dash, Rock: 第五阶段:根据订单商品动态选择皮肤并兑换发货
alt 订单购买的是黑色 ROCK
Dash->>Rock: POST /api/redeem/{id} {"skin": "黑色ROCK长袖T恤", "currency": "幸运币", "account": "..."}
else 订单购买的是蓝色运动服
Dash->>Rock: POST /api/redeem/{id} {"skin": "蓝色运动服上衣", "currency": "幸运币", "account": "..."}
end
Rock-->>Dash: {"status": "success", "message": "领取成功"}
Dash->>Pool: 标记 Token 状态为 redeemed,记录实际发放的 skin
Dash-->>Buyer: 发货成功!生成发货凭证图
end
end
三、 本地库存模型与数据表设计
为了实现后台批量采购、库存水位控制与防错追踪,设计本地专属库存表:
3.1 Token 库存表 (rock_tokens)
所有 Token 在提取时统一默认采购为**“黑色通用 Token”**(上游类型传 1 = 黑色,即 color = 'black'),不预设皮肤,入库为通用库存。
CREATE TABLE IF NOT EXISTS `rock_tokens` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`upstream_id` BIGINT UNSIGNED NOT NULL COMMENT '0666平台的Token ID,如 151153',
`token_jwt` TEXT NOT NULL COMMENT 'Token完整JWT串',
`redeem_code` VARCHAR(64) NOT NULL UNIQUE COMMENT '专属兑换码哈希',
`color` VARCHAR(16) NOT NULL DEFAULT 'black' COMMENT '采购规格: 统一为 black 通用 Token',
`status` VARCHAR(24) NOT NULL DEFAULT 'available' COMMENT '状态: available(可用)/locked(锁定)/bound(已绑)/redeemed(已发)/mismatch(绑错待查)/abnormal(异常)/expired(过期)',
`assigned_order_no` VARCHAR(64) DEFAULT NULL COMMENT '当前绑定的内部订单号',
`expected_uid` VARCHAR(64) DEFAULT NULL COMMENT '买家输入的预期游戏UID',
`actual_role_name` VARCHAR(128) DEFAULT NULL COMMENT '扫码绑定的游戏角色名',
`actual_role_id` VARCHAR(64) DEFAULT NULL COMMENT '扫码绑定的游戏角色UID',
`actual_region` VARCHAR(64) DEFAULT NULL COMMENT '扫码绑定的大区',
`bind_url` TEXT DEFAULT NULL COMMENT '腾讯官方绑定链接',
`initial_snapshot` TEXT DEFAULT NULL COMMENT '分配时的初始旧绑定快照JSON(用于防混淆)',
`cost_points` DECIMAL(10,2) DEFAULT '21.00' COMMENT '采购消耗积分',
`redeemed_skin` VARCHAR(64) DEFAULT NULL COMMENT '实际兑换发放的皮肤名称(如: 黑色ROCK长袖T恤 / 蓝色运动服上衣)',
`redeemed_currency` VARCHAR(64) DEFAULT NULL COMMENT '附赠的货币类型(默认: 幸运币)',
`redeemed_amount` INT DEFAULT 0 COMMENT '附赠的货币数量(黑=10, 蓝=14)',
`mismatch_at` DATETIME DEFAULT NULL COMMENT '判定为绑错UID的时间戳(用于统计大屏)',
`mismatch_reason` VARCHAR(255) DEFAULT NULL COMMENT '绑错详情说明(如: 预期UID 4331027062 与扫码 3911959065 不符)',
`expires_at` DATETIME DEFAULT NULL COMMENT 'Token官方过期时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_status_color` (`status`, `color`),
INDEX `idx_assigned_order` (`assigned_order_no`),
INDEX `idx_mismatch` (`status`, `mismatch_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Rock平台Token本地通用库存池';
3.2 Rock 平台配置表 / 系统配置扩展 (rock_config)
在系统配置项中持久化以下参数:
rock_auto_delivery_enabled: Rock 自动发货全局总开关(true开启 /false一键关闭,关闭后两款商品停走自动发货通道)rock_base_url:https://0666.prorock_bearer_token: 上游当前有效的 Bearer Token(如抓包中的05c55d8b8c...)rock_username: 上游系统采购用户名(调GET /api/me自动获取,如王大锤)rock_account_points: 上游最新同步的积分余额(实时快照,如8271.2)rock_min_points_warning: 上游最低积分告警阈值(默认1050.0,即至少满足一次 50 个 Token 自动补货)rock_token_warning_stock: 通用 Token 告警安全水位(默认 10)rock_auto_purchase_enabled: 自动补货开关(true/false)rock_auto_purchase_count: 触发自动补货时单次采购量(默认 50,对应上游count=50黑色通用 Token)rock_purchase_cooldown_minutes: 自动采购防抖冷却时间(默认 10 分钟,防并发击穿积分)
3.3 0666.pro 系统采购用户账号生命周期管理方案 (Upstream Account Lifecycle)
根据业务核验,0666.pro 平台登录方式为 Bearer Token 登录 与 用户名+验证码登录(无密码登录)。依照当前实施策略,现阶段纯采用 Bearer Token 模式直接配置接入,后续再按需扩展验证码交互:
1. 凭据录入与自动校验 (Token-Only Direct Configuration)
- 商户鉴权机制结论: 上游 0666.pro 平台无独立固定密码,仅支持“Bearer Token 登录”与“用户名+手机短信验证码登录”。根据实施规划,先期直接采用 Token 配置方式,后续再视需要支持用户名+验证码交互。
- 后台极简配置:
在系统设置面板中,管理员直接粘贴从 0666.pro 网页或抓包中获取的当前有效
Bearer Token(64位十六进制串):💡 Token 提取极简指引: 登录 0666.pro 网页后,按
F12打开控制台,在Application (应用程序) -> Local Storage -> https://0666.pro中找到yd_token字段复制;或在控制台 Console 执行localStorage.getItem('yd_token')即可一键复制。 - 即时连通性校验与自动同步:
点击【保存并测试连通】,后端立即发送
GET https://0666.pro/api/me:- 成功时:自动提取并展示上游用户名(
王大锤)、账号状态(active)、当前可用积分(8271.2),折算展示“约可采购 393 个通用 Token”; - 失败时:界面提示错误详情(如凭证无效),阻止错误保存。
- 成功时:自动提取并展示上游用户名(
2. 账号健康心跳与积分余额监控 (Heartbeat & Balance Tracker)
- 定时心跳巡检:后台定时任务(如每 10 分钟)调用
GET /api/me; - 大屏实时看板:
- 采购账号:
王大锤(状态:active 正常) - 上游剩余积分:
8271.2点(看板自动折算可用 Token 配额) - 最后心跳时间:实时更新
- 采购账号:
- 低积分提前预警:
当
points < 1050.0(不足一次 50 个采购)时,通过飞书/企微/钉钉机器人推送:⚠️ 【资金告警】0666.pro 平台采购账号积分不足!
账号:王大锤 | 剩余积分:840.0 点(不足一次 50 个自动补货)
请及时前往 0666.pro 进行充值,避免断货。
3. 凭据失效(401 Unauthorized)自动处置与熔断
- 当采购接口返回 401(Token 到期失效或被注销)时:
- 系统自动软熔断:自动将
rock_auto_delivery_enabled置为报警待查状态,黑色 ROCK 与蓝色运动服两款商品立即降级为人工打手接单/客服处理,避免错单穿透; - 高危警报推送:立即向管理群推送高危紧急告警:“【紧急】0666 平台采购账号 Token 已失效,自动发货通道已自动熔断转人工,请管理员复制最新 Token 登录后台更新!”;
- 一键恢复:管理员登录 0666.pro 获取新 Token 粘贴保存后,连通性测试通过即可一键恢复自动发货。
- 系统自动软熔断:自动将
- 后续扩展计划(Phase 2):未来若需支持脱离网页获取 Token,再在后台增加“输入手机号 -> 调
/api/auth/send-code-> 接收短信验证码 -> 调/api/auth/phone-login”的在线登录换 Token 流程。
四、 核心防护算法与业务门禁细节
4.1 旧绑定信息清洗与基线比对(Anti-Ghost-Binding)
真实抓包实锤证据 (蓝色一个发货.har):
在买家尚未扫码前(Entry 1~6),上游 refresh 接口一直返回该手机号绑过的旧账号:
bound_account: "总荒凉"bound_account_id: "3751279035"bind_changed_at: null直到买家在手机微信真正完成扫码授权后(Entry 10),上游数据才发生跃迁:bound_account: "打破虚妄的浪漫"bound_account_id: "3688825401"previous_bound_account: "总荒凉"(旧账号自动归入 previous)bind_changed_at: "2026-10-05 14:08:02"bind_change_type: "rebind"
若没有基线快照比对,系统在买家扫码前就会把旧账号“总荒凉”当作买家发货,导致灾难性货损!
算法逻辑:
type BindingSnapshot struct {
Bound bool `json:"bound"`
RoleName string `json:"role_name"`
RoleID string `json:"role_id"`
BindChangedAt string `json:"bind_changed_at"`
}
// 检查是否发生新的真实有效扫码
func IsNewBindingValid(initialSnap BindingSnapshot, currentRefresh UpstreamRefreshResp, expectedUID string) (bool, string) {
if !currentRefresh.Binding.Bound || currentRefresh.Binding.RoleID == "" {
return false, "等待扫码绑定"
}
// 若当前刷新的绑定状态与初始分配时的历史快照完全一致,说明买家尚未真正扫码,仍是历史残留
if initialSnap.Bound && initialSnap.RoleID == currentRefresh.Binding.RoleID && initialSnap.BindChangedAt == currentRefresh.Token.BindChangedAt {
return false, "等待买家扫码(忽略历史残留)"
}
// 核心门禁:UID 必须 100% 强一致
trimmedExpected := strings.TrimSpace(expectedUID)
trimmedActual := strings.TrimSpace(currentRefresh.Binding.RoleID)
if trimmedExpected != "" && trimmedActual != trimmedExpected {
return false, fmt.Sprintf("绑定账号UID(%s)与订单预期UID(%s)不一致,严禁发货!", trimmedActual, trimmedExpected)
}
return true, "ok"
}
4.2 绑定错误独立统计与追溯大屏 (Mismatch Audit & Metrics)
当买家扫错账号或拿他人微信扫码导致 UID 不一致时,系统触发以下处理:
- Token 状态跃迁至
mismatch:- 记录
mismatch_at = NOW(); - 记录
mismatch_reason = fmt.Sprintf("预期UID(%s) 与 扫码UID(%s/%s) 不一致", expectedUID, actualRoleName, actualRoleID); - 阻断底层兑换调用,保留该 Token 在数据库中。
- 记录
- 后台管理大屏独立统计卡片:
- 统计指标:
COUNT(status = 'mismatch'),直观展示“绑定错误待排查 Token 数量”; - 列表展示维度:
- 关联订单号 (
assigned_order_no) - 买家填写的预期 UID (
expected_uid) - 扫码实际角色与 UID (
actual_role_name/actual_role_id) - 发生时间与大区
- 关联订单号 (
- 支持客服人工处理:
- 人工释放/重置:若确认买家输入失误,允许客服人工纠偏重置为
available或重新下发; - 上报作废:调用上游
POST /api/user/tokens/{id}/report标记为abnormal归档。
- 人工释放/重置:若确认买家输入失误,允许客服人工纠偏重置为
- 统计指标:
4.3 全局自动发货总开关与降级熔断机制 (Kill Switch)
针对黑色 ROCK 与蓝色运动服两款商品,设立全局软熔断总开关 rock_auto_delivery_enabled:
- 开关位置:商户后台 / 平台设置中的一键 Switch 开关。
- 熔断效果:
- 当开启 (
true) 时:正常走全自动反代发货链路(分配 Token -> 出示二维码 -> 扫码强校验 -> 自动兑换发货)。 - 当关闭 (
false) 时:- 黑色 ROCK 和蓝色运动服两款商品彻底脱离自动发货流程;
- 订单状态保留在
paid,自动发货接口直接返回:{ "can_ship": false, "cannot_ship_reason": "当前该商品自动发货通道维护中,已转交人工客服/打手为您处理" } - 绝不调用 0666.pro 消耗 Token 或积分,由人工打手在接单平台抢单核验发货,或由客服人工处理;
- 用于应对上游故障、Token 缺货、价格调整或恶意攻击时的秒级止血。
- 当开启 (
五、 库存管理、安全水位预警与自动采购逻辑
5.1 批量采购与入库流程
- 管理员在后台点击【采购 50 个黑色 Token】;
- 服务端带上
rock_bearer_token,向https://0666.pro/api/user/tokens/claim发送:{"color": "black", "count": "50"} - 上游返回 50 个 Token 数组,事务批量写入
rock_tokens表,status = 'available'; - 记录本次采购消耗的积分与操作日志。
5.2 水位巡检与告警通知
- 触发时机:
- 订单每次消耗锁定 Token 时;
- 后台定时巡检 Cron(如每 5 分钟)。
- 判断逻辑:
\text{可用库存} = \operatorname{COUNT}\left(\text{status} = 'available' \land \text{color} = \text{target\_color}\right)- 若 $\text{可用库存} \le \text{告警阈值}$:
- 发送机器人告警通知(复用系统现有的飞书/钉钉/企业微信 webhook):
【库存告警】Rock平台黑色Token库存告急!
当前可用库存:4 个(预警阈值:10 个)
请及时确认上游积分或检查自动补货状态。 - 若开启了
rock_auto_purchase_enabled:- 检查是否在冷却期内(距上次自动采购时间
\ge 10分钟); - 触发自动采购任务,调用 claim 补充 50 个;
- 采购成功后发送补货成功通知。
- 检查是否在冷却期内(距上次自动采购时间
- 发送机器人告警通知(复用系统现有的飞书/钉钉/企业微信 webhook):
- 若 $\text{可用库存} \le \text{告警阈值}$:
六、 实施规划路线图(分步推进)
[Phase 1: 数据模型与库存池] -> [Phase 2: 采购与水位监控] -> [Phase 3: 反向代理与UID门禁] -> [Phase 4: Provider集成]
- 创建 rock_tokens 数据表 - 实现手动采购API - 提货页输入UID前置流程 - 实现 RockProvider 接口
- 系统配置项拓展 - 接入飞书/企微低库存预警 - 上游旧数据过滤与比对 - 接入系统统一发货工作台
- 自动补货定时任务与冷却控制 - 强一致校验与硬阻断
- 第一阶段(数据底座):创建
rock_tokens数据结构与配置项存储,打通 0666.pro 的 Claim 接口。(已完成) - 第二阶段(库存与安全):在后台管理界面增加 Rock 库存面板,支持采购 50 个、库存查看、低水位告警与自动补货。(已完成)
- 第三阶段(反代与安全门禁):实现代理转发与 UID 校验拦截器,杜绝因扫错号报废 Token。(已完成)
- 第四阶段(业务无缝收口):完成标准 Provider 适配,系统无缝接管。(已完成)
七、 工程落地进度与实测验证记录 (Implementation Audit)
7.1 落地成果交付清单
| 模块层级 | 文件路径 | 核心功能与职责 | 状态 |
|---|---|---|---|
| SQL 迁移 | backend/internal/database/migrations/012_rock_fulfillment.sql |
创建 rock_configs 配置表、rock_tokens 通用库存表,初始化黑色ROCK与蓝色运动服目录数据 |
✅ 已就绪 |
| 数据模型 | backend/internal/model/rock.go |
定义 RockConfig 与 RockToken 结构体及常量映射 |
✅ 已就绪 |
| 通信客户端 | backend/internal/service/rock_client.go |
封装 0666.pro 平台全部 REST 接口 (GetMe, Claim, Refresh, Redeem, etc.) | ✅ 已就绪 |
| 库存与风控 | backend/internal/service/rock_service.go |
实现库存行锁分配、Anti-Ghost 基线比对、UID强一致阻断、自动补货巡检与 mismatch 解冻 | ✅ 已就绪 |
| 履约渠道 | backend/internal/service/provider_rock.go |
实现统一 FulfillmentProvider 接口,支持动态判定皮肤与腾讯官方流水提取 |
✅ 已就绪 |
| 后台 API | backend/internal/handler/rock.go |
提供配置查询/更新、测试连通、一键采购 50 个、库存分页与重置接口 | ✅ 已就绪 |
| 前端 API | frontend/src/api/index.ts |
增加 rockApi 与相关 TypeScript 类型声明 |
✅ 已就绪 |
| 管理大屏 | frontend/src/pages/PlatformRock.tsx |
实现自动发货总开关、指标看板、Token 配置与连通测试、库存与错单审计列表 | ✅ 已就绪 |
| 菜单与路由 | frontend/src/App.tsx, MainLayout.tsx |
注册 /platform-rock 路由与侧边栏商品管理子菜单 |
✅ 已就绪 |
| 单元测试 | backend/internal/service/provider_rock_test.go |
覆盖软熔断、Anti-Ghost、UID不匹配阻断、黑蓝动态兑换、采购与连通测试 | ✅ 100% 通过 |
7.2 自动化测试结果记录
- 后端单元测试:
go test -v ./internal/service -run TestRockTestRockProvider_KillSwitch: PASS (0.41s)TestRockProvider_AntiGhostAndUIDMismatch: PASS (0.28s)(已包含角色名正确读取验证)TestRockProvider_SubmitBlueAndBlack: PASS (0.25s)(已包含兑换发货 Bearer 鉴权头校验)TestRockService_StatsAndPurchase: PASS (0.23s)(已包含真实上游字符串 points 反序列化验证)
- 后端全量测试:
go test ./...-> 全部通过 (exit code 0) - 前端静态构建:
npm run build->tsc -b && vite build成功通过 (exit code 0)
7.3 实测抓包逆向排障与修复记录(基于平台实际测试-1.har 铁证)
证据分类审计表
| 维度 | 内容详情 | 确信度 |
|---|---|---|
| 已知 (Known) | 1. 用户实际发货报错:400: 调用上游兑换失败: 上游兑换发货接口返回错误码 401: {"error":"请先登录"};2. 用户发货页显示角色名称为 -,仅显示 UID。 |
100% (有 HAR 报文) |
| 未知 (Unknown) | 1. 为何兑换接口返回 401?是否缺少 Header 还是 Cookie? 2. 为什么 UID 识别出来了,角色名却没有获取到? |
已探明 |
| 目标 (Goal) | 1. 查清发货兑换请求与刷新接口的准确协议报文; 2. 修复角色名称映射; 3. 修复兑换鉴权,实现发货成功交付。 |
100% 达成 |
关键技术发现与修复对齐:
- 角色名称缺失根因:
- 抓包分析发现:0666.pro 的
/api/user/tokens/:id/refresh与/api/redeem/:code响应中根本没有binding对象,所有的扫码角色信息直接位于token根对象下:token.bound_account:买家真实游戏角色名(例如"感性的洁少");token.bound_account_id:买家游戏角色 UID;token.region:登录渠道(例如"安卓-微信");token.status:绑定状态("bound")。
- 修复:重构
RockTokenData并增加GetRoleName()、GetRoleID(),将角色名正确回填至ProviderBindResult.RoleName与数据库,彻底解决“角色名显示为-”的问题。
- 抓包分析发现:0666.pro 的
- 兑换发货 401 根因:
- 抓包分析发现:
POST https://0666.pro/api/redeem/:id接口受到商户认证中间件保护,必须携带请求头Authorization: Bearer <yd_token>,且请求体account字段必须传入买家真实角色名。原代码漏设了该请求头导致被拒。 - 修复:在
RedeemSkin中接收并注入Authorization: Bearer <bearerToken>请求头,且account优先取token.ActualRoleName。
- 抓包分析发现:
- 单测防护覆盖:
- 更新
TestRockProvider_AntiGhostAndUIDMismatch,断言扫码成功后RoleName必须准确提取为玩家角色名; - 更新
TestRockProvider_SubmitBlueAndBlack,若未携带 Bearer 鉴权头则模拟 401 拒绝,断言发货请求必须 100% 鉴权通过。
- 更新
7.4 平台实际发货 HAR(黑色平台发货的, 自己的不行.har)报文深度比对与最终闭环
证据分类审计表
| 维度 | 内容详情 | 确信度 |
|---|---|---|
| 已知 (Known) | 1. 用户使用 0666.pro 原生管理台发货黑色 ROCK 成功,状态码 200; 2. 发货报文完整捕获于 /Users/yml/Desktop/抓包/rock相关/黑色平台发货的, 自己的不行.har;3. 发货成功响应体为 {"token":{...},"status":"success","message":"领取成功"},无 delivery 包装字段。 |
100% (有 HAR 报文证实) |
| 未知 (Unknown) | 1. 0666.pro 兑换成功后返回的 JSON 结构是否与之前预期一致? 2. 除 Bearer Token 外,是否校验 Origin / Referer / Accept 请求头? |
已探明 |
| 目标 (Goal) | 1. 100% 字节级对齐 0666.pro 发货请求头与响应反序列化结构; 2. 修复原代码中误假设的 redeemResp.Delivery 字段,杜绝反序列化截断或空指针;3. 验证通过并提交 Git。 |
100% 达成 |
报文镜像比对表 (Side-by-Side Wire Protocol Diff)
POST /api/redeem/151237 HTTP/1.1
Host: 0666.pro
Authorization: Bearer 05c55d8b8c38cac0c388db2615a0e3eed5a53c1eaecdee5cf8924b2a814b1958
Content-Type: application/json
Origin: https://0666.pro
Referer: https://0666.pro/
Accept: */*
{"skin":"黑色ROCK长袖T恤","currency":"幸运币","account":"谢总腰死你"}
HTTP/1.1 200 OK
Content-Type: application/json
{
"token": {
"id": 151237,
"redeem_code": "9d93ac2dd9e42ef5a22bf3d8cd9c3ed5",
"status": "redeemed",
"bound_account": "谢总腰死你",
"bound_account_id": "3892548310",
"redeem_skin": "黑色ROCK长袖T恤",
"redeem_currency": "幸运币",
"redeemed_at": "2026-10-05 16:23:33"
},
"status": "success",
"message": "领取成功"
}
关键修复落地点:
- 请求头指纹对齐:在
RedeemSkin中补齐Origin: https://0666.pro、Referer: https://0666.pro/以及Authorization: Bearer <token>; - 响应结构体重构:将
RockRedeemResponse从臆想的delivery对象重构为真实结构(包含Token RockTokenData、Status string、Message string),并提供IsSuccess()方法判定; - FulfillID 兜底流:官方单号提取优先从
token.upstream_fulfill_id读取,若兑换后无单独 ID 则平滑兼容; - 编译与单测:全量单元测试与编译均已 100% 通过。
7.5 “提货页补货中与发货报错”死锁漏洞排查记录(基于自身的补货中, 但是后台正常.har 铁证)
证据分类审计表
| 维度 | 内容详情 | 确信度 |
|---|---|---|
| 已知 (Known) | 1. 用户反馈:自己的发货页面一直提示“补货中”,后台发货一直报错拦截,但上游 0666.pro 平台却可以正常发货; 2. 抓包证实 Token 152317 绑定正常且在上游已成功发货(账号: 屛堃,UID:3640883661);3. 数据库中订单 33 已完成发货,可用 Token 数量正好归零 ( AvailableStock = 0)。 |
100% (有 HAR 报文与 DB 记录双重佐证) |
| 未知 (Unknown) | 为何订单明明已分配 Token 且绑定成功,提货页与发货接口仍强制判定为不可发货并提示“补货中”? | 已探明 |
| 目标 (Goal) | 修复 PrepareDelivery 状态机判定,订单一旦成功预占分配 Token,无论池子空闲库存是否为 0,均允许正常进入扫码与发货履约流程。 |
100% 达成 |
致命逻辑盲区根因解构:
- 死锁链条:
- 当一笔订单分配了池中最后一个 Token 后,数据库中
status = 'available'的空闲 Token 数量变为0; - 买家扫码授权后,提货页轮询或点击发货,外层均调用
PrepareDelivery进行发货前瞻校验; - 原代码无条件执行:
if stats.AvailableStock <= 0 { return &DeliveryOrderState{CanShip: false, CannotShipReason: "当前商品库存补充中..."} } - 原逻辑完全忽略了当前订单其实早就成功预占了专属 Token!
- 导致提货页直接弹窗横幅提示“当前商品库存补充中”,并在买家点击发货时被
if !info.CanShip硬性拦截报 400 错误! - 此时由于上游 0666.pro 已经完成微信扫码绑定,用户前往 0666.pro 官方后台点击发货自然能够成功,造成了“自己系统报补货中,但官方后台发货正常”的假象。
- 当一笔订单分配了池中最后一个 Token 后,数据库中
- 修复落地:
- 在
PrepareDelivery中增加专属已占库存识别:如果当前订单号已存在using或bound状态的 Token,判定为库存已锁定,豁免空闲库存校验; - 针对未分配 Token 的新订单,在空闲库存不足时若开启了自动采购,即刻触发异步补货巡检;
- 在
ClaimTokens与RefreshToken中补齐Origin与Referer头。
- 在
- 回归测试门禁:
- 新增单元测试
TestRockProvider_PrepareDelivery_ZeroStockWithAssignedToken:- 断言 1:空闲库存为 0 时,新订单被正确拦截并提示“库存补充中”;
- 断言 2:空闲库存为 0 时,已分配 Token 的订单必须 100% 允许正常发货(
CanShip = true)。
- 包含新增用例在内的 5 项 Rock 专项测试与全量 service 测试全部 100% PASS。
- 新增单元测试
7.6 提货页面二次绑定禁用与上游 110001 频控防抖治理
证据分类审计表
| 维度 | 内容详情 | 确信度 |
|---|---|---|
| 已知 (Known) | 1. Rock 平台生成的二维码与 Token 属于 1:1 强绑定关系,多次调用会导致 Token 浪费或绑定覆盖; 2. 用户手动点击“检查扫码状态”时频繁触发 400 报错: 未知错误码: (110001) 抱歉,请求过于频繁,请稍后再试!谢谢!,而自动轮询正常。 |
100% (有实测报错报文) |
| 未知 (Unknown) | 为什么自动轮询正常而手动点击报错? | 已探明:自动轮询每 2.5 秒触发一次,手动点击与定时器极易并发,使 0666.pro 瞬间接收多笔相同 Token 的 refresh 请求触发 WAF 限流。 |
| 目标 (Goal) | 1. 禁用提货页面“重新生成二维码”按钮,锁定专属通道; 2. 后端建立 800ms 瞬时防抖缓存与 110001 软降级; 3. 前端增加 3 秒倒计时冷却与友好提示。 |
100% 达成 |
落地措施:
- 提货页防抖与单次专属锁定(
frontend/src/pages/Delivery.tsx):bindResult生成后,按钮变为“专属二维码已生成”并直接处于disabled状态;- 游戏 UID 输入框置灰禁用,防止中途修改;
- 手动点击“检查扫码状态”增加 3 秒冷却倒计时(
检查扫码状态 (3s)),错误处理中对“过于频繁/110001”进行平滑文案提示,不再弹出大红错误框。
- 后端瞬时缓存与错误降级(
backend/internal/service/rock_service.go):- 在
RockService中维护并发安全防抖缓存refreshCache sync.Map(800ms 窗口); - 当遇到上游 110001 频控响应时,执行平滑兜底,返回正在等待扫码,不抛出 HTTP 400 异常。
- 在
- 验证结果:
- 前后端静态编译构建与 5 项 Rock 单元测试全部通过。