怎么用这份清单
这份清单面向两类评审:方案评审与上线前评审。
- 方案评审关注「判断对不对」:所有权、状态机、失败路径、验证方式。
- 上线前评审关注「证据够不够」:测试覆盖、灰度策略、回滚方案、观测指标。
清单按十组问题组织,每组有若干提问、通过标准与常见缺陷。评审时不必逐条念,挑与本方案相关的组;但**「未验证」栏必须每次填**。
一个使用建议:把清单当成提问工具,而不是打分表。交易端的风险很少来自「少写了一个字段」,多来自「没人问过这个问题」。
第一组:所有权
要问的问题:
- 价格、库存、订单状态、支付结果分别由谁写?
- 端上有没有直接修改这些字段的路径?
- 预演值与服务端值冲突时,以谁为准?
- 服务端返回值是否覆盖端上乐观状态?
通过标准:
- 每个关键字段有唯一写入方,且写在文档里。
- 端上只读服务端字段,或只写明确属于自己的字段(如购物车勾选)。
- 预演值有明确标注,不进入提交。
常见缺陷:
- 「端上先改,服务端再纠正」,用户看到数字跳变。
- 库存由端上扣减,超卖后互相甩锅。
- 订单状态在端上与服务端各有一套枚举。
第二组:状态机
要问的问题:
- 订单、支付、退款各有几个状态?终态是哪几个?
- 非法迁移是拒绝还是忽略?
- 「结果未知」是独立状态还是被归入失败?
- 状态迁移是否有测试覆盖每一条边?
通过标准:
- 三套状态机分开定义,迁移表可枚举。
- 非法迁移返回明确错误,不静默成功。
unknown有独立出口,且出口不提供「重新支付」。- 每条允许的迁移至少一条测试,每条禁止的迁移至少一条测试。
常见缺陷:
- 用一个
status字段装三种状态。 - 状态机用黑名单校验,新状态被放行。
- 超时直接把订单置为取消,不检查是否已支付。
第三组:金额
要问的问题:
- 金额用什么类型?是否全程整数分?
- 有哪几个金额口径?字段名是否统一?
- 端上能算到哪一步?实付是否只由服务端给?
- 优惠、运费、退款的分摊规则是什么?舍入差由谁吸收?
通过标准:
- 全部金额整数分,币种与金额成对。
- 端上最多预演到应付金额,且标注「预估」。
- 部分退款的分摊由服务端计算,端上不二次分配。
- 有 0 元、1 分、超大金额、跨币种的展示用例。
常见缺陷:
- 用浮点数计算金额,出现
0.1 + 0.2类误差。 - 商品页价格直接用于提交。
- 端上把优惠按比例分摊,产生 1 分误差。
- 金额字段叫
total,不同页面含义不同。
第四组:幂等与重复
要问的问题:
- 提交订单的幂等键在哪生成?重试时是否复用?
- 同一幂等键重复提交,返回同一订单还是新建订单?
- 支付回调重复到达,处理是否幂等?
- 用户快速点击两次,端上有没有防抖之外的保护?
通过标准:
- 幂等键在用户动作开始时生成,覆盖整个重试周期。
- 服务端对同一键返回同一结果,不产生第二笔订单。
- 回调按事件 ID 或渠道交易号去重。
- 端上按钮置灰只是体验优化,幂等由服务端保证。
常见缺陷:
- 每次重试生成新幂等键。
- 把
orderId当幂等键,而创建订单前还没有orderId。 - 只做端上防抖,换设备或杀进程后重复提交。
第五组:失败路径
要问的问题:
- 网络超时后,端上认为成功还是失败?
- 结果未知时,用户能看到什么、能点什么?
- 支付拉起失败、回跳丢失、App 被杀,分别怎么恢复?
- 失败文案是否说满了?
通过标准:
- 超时归入「未知」,提供查询入口,不提供重复支付。
- 每个失败状态有对应文案与下一步动作。
- 恢复路径不依赖用户记住刚才发生了什么。
- 文案不承诺「一定退款」「立即到账」。
常见缺陷:
- 超时提示「支付失败,请重试」,用户付了两次。
- 回跳丢失后停在空白页。
- 失败文案把「处理中」写成「已退款」。
第六组:优惠与会员
要问的问题:
- 券的可用性由谁判定?端上判定与服务端是否同源?
- 叠加规则是「先券后折」还是「先折后券」?门槛按哪个金额算?
- 会员价与券能否叠加?积分何时发放?
- 价格变化后优惠失效,是否有明确提示?
通过标准:
- 最终可用性与金额由服务端返回,端上只做展示。
- 不可用原因具体到条件,不只置灰。
- 会员与券的叠加规则写在一处,端上不重复实现。
- 积分有流水,余额可重算。
常见缺陷:
- 端上算券,服务端再算一遍,两边规则漂移。
- 券不可用只显示「不满足使用条件」。
- 会员价展示与结算价不一致。
- 积分只有余额没有流水。
第七组:增长与实验
要问的问题:
- 分流键是什么?同一用户是否稳定命中同一组?
- 实验配置拉取失败时,端上用默认值还是阻塞?
- 曝光在什么时候打?路由缓存会不会重复曝光?
- 活动页降级后,用户还能不能完成主流程?
通过标准:
- 分流键稳定且与埋点标识一致。
- 配置有本地缓存与默认值,失败不阻塞交易主链路。
- 曝光去重规则明确,重复曝光可被识别。
- 活动降级不影响下单、支付等核心动作。
常见缺陷:
- 用随机数分流,用户刷新后换组。
- 配置接口失败导致首页白屏。
- 曝光打在渲染函数里,每次重渲染都上报。
- 活动页挂了,入口仍然指向它。
第八组:埋点与观测
要问的问题:
- 关键事件有哪些?事件契约是否版本化?
- 上报失败是否重试?重试是否去重?
- 支付链路的漏斗能否用
orderId串起来? - 线上出问题时,看哪几个指标能定位?
通过标准:
- 关键事件有 schema,字段变更走版本。
- 上报队列有上限、有丢弃策略、有去重。
- 端上事件与服务端事件共享
orderId或traceId。 - 至少有三个核心指标:下单成功率、支付成功率、退款完成率。
常见缺陷:
- 事件字段随手加,下游解析失败。
- 上报失败无限重试,耗电又重复。
- 漏斗各步骤用不同标识,无法串联。
- 只有「支付成功」一个点,失败原因全靠猜。
第九组:安全与隐私
要问的问题:
- 端上是否持有支付密钥、渠道私钥?
- 订单、地址、手机号在日志里是否脱敏?
- 分享链接、邀请参数是否可被篡改?
- 退款、改价等敏感操作是否有二次校验?
通过标准:
- 密钥只在服务端,端上不落盘。
- 日志脱敏,埋点不含明文手机号与地址。
- 分享参数有签名或服务端校验。
- 敏感操作有身份校验与操作留痕。
常见缺陷:
- 把渠道密钥写进客户端配置。
- 埋点带上完整收货地址。
- 邀请码可枚举,被刷奖励。
- 客服后台可直接改价,无审计。
第十组:发布与回滚
要问的问题:
- 这次改动能否独立回滚?回滚后数据是否兼容?
- 新旧版本客户端同时存在时,接口是否兼容?
- 灰度比例与观察指标是什么?
- 出现资金问题时,止损动作是什么?
通过标准:
- 前后端改动可分别回滚,或明确绑定发布。
- 接口向后兼容,旧客户端不崩。
- 灰度有明确指标与停止条件。
- 有资金止损预案:关闭入口、降级支付渠道、人工退款流程。
常见缺陷:
- 数据库字段直接改名,旧版本读写失败。
- 只测新客户端,旧版本白屏。
- 灰度只看 crash,不看支付成功率。
- 出事后没有关闭入口的开关。
「未验证」栏
每次评审结束前,把下面这张表填完:
| 结论 | 证据 | 验证方式 | 负责人 | 截止时间 |
|---|---|---|---|---|
| 例:重复提交不会产生两笔订单 | 缺 | 待补 L2 用例 | 张三 | 上线前 |
| 例:回调重复到达幂等 | 有 | L3 用例 | 李四 | 已完成 |
规则:
- 「结论」写成可证伪的句子,不写「已处理」「没问题」。
- 「证据」指测试用例、压测报告、对账结果,不指代码位置。
- 没有证据的结论一律标「缺」,不因为「大家都知道」而放行。
- 截止时间必须早于上线时间;上线前无法验证的,写进风险台账并给出降级方案。
这一栏是整份清单最重要的部分。交易端的事故,几乎都能在评审时找到一条「当时没人验证」的结论。
评审记录模板
评审对象:
评审类型:方案 / 上线前
参与人:
结论:通过 / 有条件通过 / 不通过
必改项:
1.
2.
建议项:
1.
未验证项:
| 结论 | 证据 | 验证方式 | 负责人 | 截止时间 |
风险与降级:
「有条件通过」必须写清条件与验证人;「不通过」要给出重新评审的时间,而不是无限期挂起。
快速版清单
时间有限时,至少问这十个问题:
- 价格、库存、订单状态、支付结果分别谁写?
- 三套状态机的终态是哪几个?
- 结果未知时,用户能点什么?
- 金额是否全程整数分?实付由谁给?
- 幂等键在哪生成,重试是否复用?
- 回调重复到达会怎样?
- 券不可用时,用户看得到原因吗?
- 配置拉取失败会阻塞下单吗?
- 漏斗能否用
orderId串起来? - 出资金问题时,止损开关在哪?
十个问题里有一个答不上来,就不该直接上线。
小结
评审的价值不在清单本身,而在它逼着团队把「默认成立」的假设说出来。
三句话总结:
- 所有权不清,后面全是争论。
- 状态与金额不分开,故障无法表达。
- 没有证据的结论,等于没有结论。
把这份清单带进评审会,重点看「未验证」栏,而不是看打了多少个勾。
常见错误与边界
- 把清单当打分表,勾完就通过,不看证据。
- 只评审新功能,不评审对旧版本客户端的兼容。
- 未验证项写「已知」,但没有负责人与截止时间。
- 评审结论写「通过」,风险台账却是空的。
- 只问「有没有测」,不问「测的是不是这条结论」。
- 把端上防抖当成幂等保证。
- 忽略资金止损开关,出事后只能发版。
- 评审记录不落库,下次评审从零开始。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。