联盟订单退货、退款与收益撤销闭环
本文说明平台订单发生取消、申请退款、部分退款、退款成功或退款驳回后,BeeX 如何同步订单状态,
如何处理用户返现、邀请奖励、活动奖励、券额度和钱包,以及 App 最终向用户展示什么。
1. 结论与业务原则
退款不能只改订单状态
必须同步处理订单、全部受益人佣金、活动权益、钱包和提现风险。
资金闭环部分退款先冻结
金额减少或平台进入退款处理中时,不猜最终金额,订单进入人工复核。
FROZEN待结算可自动撤销
尚未释放的收益可以幂等失效,并从 pending 钱包扣回。
自动处理已到账不自动扣钱包
已可用或已提现的资金进入追偿审核并阻断提现,不制造负余额。
人工受审计资金红线:BeeX 当前不自动扣减用户已经可用或已经提现的历史资金,不建立自动债务,也不从未来返现静默抵扣。此类退款必须形成风控/追偿记录并阻断提现,由财务或运营核实后处理。
2. 统一订单状态
不同平台的原始状态先由各平台同步服务读取,再交给统一状态策略转成 BeeX 状态。后续资金逻辑只认统一状态,不在各平台分支里重复实现。
| BeeX 状态 | 含义 | 典型平台状态 | 资金是否可结算 |
|---|---|---|---|
UNPAID | 已创建但尚未支付。 | unpaid、created | 否 |
PENDING | 已支付,等待履约、平台确认或结算。 | pending、processing、shipped | 仅保留待结算 |
FROZEN | 退款处理中、金额减少或部分退款待复核。 | refund requested、partial refund、正金额快照下降 | 否,冻结待结算收益 |
COMPLETED | 订单完成且没有有效退款。 | completed、settled、refund rejected/withdrawn | 满足结算时间后可结算 |
CANCELLED | 订单取消或确认全额退款。 | cancelled、refunded、refund success/completed | 否,撤销全部关联收益 |
乱序规则:
CANCELLED 是终态,旧的 PENDING/COMPLETED 回放不能把它恢复;FROZEN 不会被普通旧 COMPLETED 覆盖,只有明确的退款驳回、撤回或审核解除才能恢复。3. 完整退款链路
flowchart TD
A["平台订单 API 返回新状态或新金额"] --> B["平台同步服务标准化单条订单"]
B --> C["统一状态策略"]
C --> D["订单事务:行锁 + upsert + 乱序保护"]
D --> E{"发生什么变化?"}
E -- "确认取消/全额退款" --> F["订单 CANCELLED"]
E -- "退款中/金额减少" --> G["订单 FROZEN"]
E -- "退款驳回/撤回" --> H["订单 COMPLETED"]
F --> I["全部关联佣金失效"]
I --> J{"佣金资金阶段"}
J -- "PENDING" --> K["扣回 pending 钱包"]
J -- "AVAILABLE/PAID" --> L["追偿风控记录 + 阻断提现"]
F --> M["释放活动券预占,顺延后续合格订单"]
G --> N["冻结仍为 PENDING 的佣金"]
G --> O["已释放收益进入人工复核"]
H --> P["恢复此前冻结的佣金并解除退款复核"]
sequenceDiagram
participant P as 平台 API
participant S as 平台同步服务
participant O as AffiliateOrderRepository
participant R as 退款与部分退款服务
participant W as WalletRepository
participant C as 券/活动权益
participant K as 风控与提现
participant A as App
S->>P: 按时间窗分页查询订单
P-->>S: 一页原始订单记录
loop 每条记录独立处理
S->>O: 标准化订单并 upsert
O-->>R: 发布取消、退款或金额减少事件
alt 确认退款,佣金仍 PENDING
R->>W: 幂等撤销 pending 钱包
R->>C: 释放活动预占/恢复券额度
else 确认退款,佣金 AVAILABLE/PAID
R->>K: 创建追偿事件并阻断提现
else 部分退款或退款处理中
R->>W: 冻结未释放佣金
R->>K: 标记复核
else 退款驳回或撤回
R->>W: 恢复此前冻结佣金
R->>K: 解除复核
end
end
A->>O: 查询订单列表/详情
O-->>A: reviewing / cancelled / pending / returned
4. 场景与处理结果
| 场景 | 订单结果 | 佣金与钱包 | 活动与券 | 用户体验 |
|---|---|---|---|---|
| 用户取消未完成订单 | CANCELLED | 全部受益人待结算佣金失效,pending 扣回。 | 释放预占额度。 | 显示“订单已取消”,不再展示预计返现。 |
| 申请退款,平台尚未判定 | FROZEN | 冻结 PENDING 佣金;已释放收益进入复核。 | 预占暂不核销,等待最终结果。 | 显示“退款审核中”,说明返现暂时冻结。 |
| 部分退款或订单金额减少 | FROZEN | 不按旧金额继续结算;等待明确的新佣金金额或人工复核。 | 等待最终可核销额度。 | 显示“退款审核中”,不展示旧返现金额。 |
| 全额退款成功 | CANCELLED | 买家、邀请人、活动等所有关联佣金一起失效;按资金阶段自动撤销或进入追偿。 | 释放/恢复本订单占用权益。 | 显示“已退款”,不再申诉普通追踪失败。 |
| 退款被平台驳回或用户撤回 | COMPLETED | 此前处于 FROZEN 的待结算佣金恢复为 PENDING。 | 继续由原订单占用并按完成流程核销。 | 恢复正常订单与返现流程。 |
| 退款信息晚到数周 | 由历史追扫纠正 | 执行相同的撤销/追偿逻辑,不因实时窗口已过而漏单。 | 执行相同释放逻辑。 | 下一次查询显示平台最新真实状态。 |
5. 各类收益如何撤销
退款不是只撤销“用户本人返现”。只要佣金记录关联同一个订单,确认退款后都必须采用同一撤销规则。
用户本人返现
订单确认退款后失效;PENDING 自动扣回,已释放进入追偿审核。
邀请人奖励
与该订单关联的邀请奖励同步失效,不能让邀请人继续保留已退款订单收益。
活动额外返现
活动生成的 commission record 同样失效,并按资金阶段处理钱包。
返佣基金券
释放本单预占额度;符合规则时由后续更晚的有效订单顺延使用。
普通优惠券
依照券的核销状态恢复或释放;不能重复恢复、重复领取或重复核销。
已提现收益
不自动从其它余额或未来订单扣除,生成追偿与风控记录并阻断提现。
为什么按订单统一失效:同一订单可能同时生成用户返现、邀请奖励、活动奖励和券加成。如果只撤销其中一条,资金总额就会与平台最终佣金不一致。
6. 部分退款与金额减少
部分退款最容易被忽略。平台可能只把订单佣金从 A 改成 B,也可能只给出退款状态,不一定给 BeeX 一条清晰的“部分退款成功”事件。
- Shopee 回放携带正金额快照,且 GMV 或平台佣金比数据库原值减少时,订单进入
FROZEN。 - 若 Shopee 稀疏回放只带状态、金额为 0,不覆盖原订单金额,也不把订单误判成部分退款。
FROZEN期间不继续释放佣金,避免按退款前金额多发钱。- 平台明确退款驳回/撤回后恢复;明确全额退款后转
CANCELLED并执行完整撤销。 - 平台只给出最终减少金额但不足以自动重算所有受益人时,保留复核记录,由运营/财务确认。
禁止做法:不能把“金额字段缺失或为零”直接当成退款,也不能在退款结果未确定时按比例猜测并立即改钱包。
7. 晚到退款追扫
常规订单同步通常查询最近订单;但用户可能在下单数周后退货。只依赖最近 15 分钟或最近几天的同步窗口,会永久漏掉晚到退款。
| 机制 | 当前实现 | 目的 |
|---|---|---|
| 常规同步 | 各平台按短周期轮询最新订单。 | 快速发现新单和近期状态变化。 |
| 历史退款追扫 | 每小时扫描 5 个互不重叠的 24 小时下单时间片。 | 重新查询历史订单当前状态。 |
| 覆盖范围 | 回看最近 120 天;24 次小时任务完成一轮,即最长约 24 小时复核一遍。 | 覆盖平台允许的退货周期,同时控制 API 调用量。 |
| 平台范围 | TikTok Creator、TikTok CAP、Shopee、Lazada、Traveloka。 | 所有已接入联盟订单使用同一退款安全网。 |
| 并发控制 | 分布式锁 + 稳定时间片 + 平台原分页。 | 多实例不重复扫同一轮,重启后不会错乱时间窗。 |
重要口径:历史追扫按“原下单/购买时间”查询,不是按退款发生时间查询。这样即使平台没有退款事件推送,也能重新拿到旧订单的最新状态。
8. App 展示口径
| 后端状态 | App 展示状态 | 金额展示 | 可用操作 |
|---|---|---|---|
PENDING | 待处理/追踪中 | 可展示当前预计返现,注明动态计算。 | 查看详情。 |
FROZEN | 退款审核中 | 不继续展示退款前的旧返现金额。 | 查看退款说明;不进入普通追踪失败申诉。 |
COMPLETED | 已返现/待结算 | 展示最终有效收益。 | 查看收益明细。 |
CANCELLED | 已取消/已退款 | 不展示可获得返现。 | 查看状态说明。 |
| 真实同步失败 | 追踪失败 | 不展示虚构收益。 | 允许用户申诉。 |
前端原则:订单列表和详情页必须以最新接口状态为准,不能让路由参数或本地缓存中的旧 PENDING 覆盖后端已返回的 FROZEN/CANCELLED。
9. 幂等与乱序保护
- 订单以
(platform, platform_order_id)唯一,重复平台回放只更新同一订单。 - 订单 upsert 在事务中锁定原记录,金额比较和状态迁移基于锁内快照。
- 每条 commission 使用确定性 ID;退款按订单失效全部关联记录,重复执行不会重复扣钱包。
- 钱包撤销以原 commission ledger 为依据,只有原待结算入账存在且未撤销时才处理。
- 追偿/复核事件使用稳定业务键,重复退款回放不会创建重复风险事件。
- 单页中的一条脏记录只失败这一条,后续退款记录仍继续处理;整页 API 失败则保留任务失败,让 Worker 重试。
CANCELLED终态和FROZEN黏性规则防止旧状态把退款结果冲回去。
10. 监控与验收
| 检查项 | 通过条件 |
|---|---|
| 重复退款回放 | 订单、佣金失效、钱包撤销、券释放和追偿事件都只发生一次。 |
| 乱序状态 | CANCELLED 不倒退;FROZEN 只有明确驳回/撤回才恢复。 |
| 稀疏 Shopee 回放 | 0 金额不覆盖历史金额、不触发错误冻结。 |
| 部分退款 | 佣金停止结算,App 显示审核中,提现按风险状态阻断。 |
| 全部受益人 | 用户、邀请人、活动和券加成的 commission records 全部处理。 |
| 晚到退款 | 120 天范围在 24 小时内被完整复核一轮。 |
| 单条脏数据 | 坏记录被记录,后续正常退款仍能完成。 |
| 退款驳回 | 冻结佣金恢复且复核/提现阻断被正确解除。 |
自动化覆盖:状态映射、平台记录隔离、订单仓储、钱包撤销、部分退款复核、全额退款、活动权益恢复、提现阻断和 120 天历史追扫均有定向测试。
11. 当前边界与后续演进
| 能力 | 当前状态 | 后续可选演进 |
|---|---|---|
| PENDING 退款自动撤销 | 已实现。 | 增加后台退款证据聚合视图。 |
| 部分退款自动重算 | 当前先冻结复核,避免猜错。 | 平台字段稳定后,按最终商品级金额重算全部收益。 |
| AVAILABLE/PAID 追偿 | 创建风险记录、阻断提现、人工处理。 | 若未来确需自动抵扣,必须另立 PRD、用户协议和审计机制,不能静默上线。 |
| 退款主动通知 | 订单状态可由 App 查询。 | 通过 Outbox 增加 Push/WhatsApp 通知,不影响资金事务。 |