有人提交订单,不代表已经达到成团门槛。成团口径决定人数统计与失败退款。
本文使用团购业务的虚构订单与关系数据模型,伪代码不连接真实支付。团购把用户购买、平台收款、商家履约与结算连接起来。下单、支付、成团、消费和退款必须保留各自状态,不能用一个布尔字段表达整个生命周期。
1. 从现象推到机制
先明确门槛计算支付订单、购买份数还是独立用户。业务到期时应在一致口径下判定,不能让未支付占位无限影响结果。支付到账与成团决定属于两个状态过程,迟到支付也需要明确处理规则。
图中的四个节点分别表示参与订单、统计口径、活动判定、后续履约。顺着实线检查输入如何变成输出,再沿虚线核对反馈条件。图示表达的是本文讨论的关系,不是实测曲线或现场截图。
2. 最小实现与输入条件
建立团活动状态与参与订单状态。到期判定采用条件迁移,若多个调度器同时执行,只有一次把活动从开放改为成功或失败。
1
2
3
group: OPEN -> SUCCEEDED | FAILED
participant: CREATED -> PAID -> REFUNDING -> REFUNDED
counting_rule: paid_units_before_deadline
先列业务事件与允许的状态迁移,再用少量匿名订单演算。涉及金额的地方保存成交快照,涉及并发的地方使用数据库约束,外部支付行为按支付协议另行实现。
3. 用对照区分原因
下表列出需要主动改变的条件。预期行为来自机制分析,复现时还需记录运行环境和原始输出,不能将预期当作已经测得的结果。
| 改变的条件 | 需要验证的行为 |
|---|---|
| 大量未支付订单进入 | 不得按已付门槛直接成团 |
| 到期判定重复执行 | 结果不能来回变化 |
| 支付通知晚于截止时间 | 按预先约定处理而非临时猜测 |
对照 1:大量未支付订单进入
不得按已付门槛直接成团。观察时记录统计使用的状态与时间点。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 2:到期判定重复执行
结果不能来回变化。观察时记录活动状态的条件更新。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
对照 3:支付通知晚于截止时间
按预先约定处理而非临时猜测。观察时记录通道交易时刻与本地接收时刻。把这个条件与基准情形分开,有助于判断变化来自哪一层;若得到相反结果,应先核对前提,再修改实现。
4. 适用条件与取舍
到期边界、时区和退款规则应在销售前明确。技术实现只能执行既定规则,不能用数据库方便程度替代业务约定。
一次正常运行只覆盖了这组输入。继续扩展前,应把上面的异常对照保留下来,尤其关注“支付通知晚于截止时间”这一分支。后续方案若改变了图中任意一处依赖,原来的判断就要重新验证,不能仅凭界面相似或返回值相同沿用结论。