这本手册怎么用
交易问题有两个特点:用户描述往往不准确,而排查窗口很短。用户说「我付了钱但没订单」,实际可能是支付成功但页面没刷新,也可能是支付根本没成功,还可能是下到了另一个账号。
这本手册按症状组织,不按模块组织。每类症状给出:
- 先问什么、先看什么(定性顺序)。
- 必须拿到的字段(最小信息集)。
- 常见原因排序,从最可能到最不可能。
- 什么情况下停止自查、升级人工。
它假设你能拿到客户端日志、服务端查询接口与支付渠道后台。三者缺一时,结论要降级为「疑似」而不是「确认」。
排查的通用顺序
不管什么症状,先做三步定性,能排除掉一半误报:
第一步:确认事实,而不是描述。 用户说「扣款了」,要看渠道账单或银行流水;用户说「没到账」,要看退款单状态而不是订单状态。
第二步:对齐时间线。 把用户操作、端上请求、服务端响应、渠道回调按同一时钟排列。时区不一致是最常见的假线索。
第三步:确认对象。 同一用户可能有多个账号、多笔相似订单、多个支付尝试。先锁定 orderId 与 paymentId,再讨论状态。
三步做完再进入具体症状。跳过这三步直接看代码,通常会在错误的方向上花掉最多的时间。
最小信息集
无论哪类问题,先收集这些字段:
| 字段 | 从哪里拿 | 为什么需要 |
|---|---|---|
userId | 登录态 | 排除多账号 |
orderId | 订单页或服务端 | 锁定对象 |
paymentId | 支付记录 | 区分多次支付尝试 |
idempotencyKey | 端上日志 | 判断是否重复提交 |
traceId | 响应头或日志 | 串起一次请求链路 |
clientVersion | 客户端 | 排除旧版本缺陷 |
platform | 客户端 | 区分 iOS/Android/Web/小程序 |
| 操作时间 | 用户描述 + 日志 | 对齐时间线 |
| 金额与币种 | 订单与账单 | 判断口径 |
| 网络状态 | 端上日志 | 判断是否为「未知」 |
缺少 paymentId 时,很多结论只能到「疑似」。缺少 traceId 时,服务端排查会退化成按时间盲搜。
症状一:支付成功,订单仍显示待支付
这是最高频的问题,原因分布大致如下:
- 端上没有刷新,页面停留在支付前的快照。
- 支付回调尚未到达,订单状态还没推进。
- 回调到达但处理失败,进入重试队列。
- 用户实际支付的是另一笔订单(重复下单)。
- 支付成功但订单已被取消,需要退款。
定性顺序:
- 查支付单状态:
succeeded还是unknown。 - 查订单状态与版本号:是否已经推进,只是端上没刷新。
- 查回调记录:有没有收到、处理结果是什么。
- 查是否存在同一商品的另一笔订单。
端上要做的不是「等」,而是主动查询支付结果。查询接口应返回支付单状态与订单状态两部分,避免端上从订单状态反推支付结果。
如果确认支付成功而订单已取消,正确动作是发起退款,不是把订单改回待支付。
症状二:重复扣款
用户看到两笔扣款,先区分三种情况:
| 情况 | 特征 | 处理 |
|---|---|---|
| 同一支付单重复通知 | 渠道侧只有一笔交易 | 端上展示去重,无需退款 |
| 两次支付尝试都成功 | 两个 paymentId 都是 succeeded | 退一笔 |
| 用户误操作下了两单 | 两个 orderId,商品相同 | 按取消规则处理 |
排查要点:
- 按
orderId列出所有paymentId,不要只看最新一条。 - 按渠道交易号去重,渠道交易号相同就是同一笔。
- 检查端上是否在「结果未知」时提供了重新支付入口。
- 检查服务端是否对同一幂等键返回了不同订单。
重复扣款的第一道防线在端上:unknown 状态只能查询,不能重新支付。第二道在对账:每日把渠道流水与支付单比对,发现「渠道有、系统无」或「系统有、渠道无」。
症状三:金额与预期不一致
金额问题先分清是「显示不一致」还是「实际扣款不一致」。
显示不一致:
- 预演金额与服务端返回不一致。
- 优惠金额没有及时刷新。
- 运费在最后一步才出现。
- 币种或小数位展示错误。
实际扣款不一致:
- 端上把预演金额用于提交。
- 服务端计算与展示用了不同的优惠规则。
- 支付渠道按自己的汇率或手续费扣款。
排查顺序:拿订单快照里的 payableAmount、paidAmount、discountAmount 三个字段,与渠道账单逐项对照。三者对不上时,以渠道账单为事实,以订单快照为解释。
一个常见误区是拿「商品页显示价 × 数量」去对账。商品页价格可能已过期,订单快照才是下单时刻的价格。
症状四:券不可用或优惠消失
券的问题通常不是「券坏了」,而是「判定条件没对齐」。
按顺序检查:
- 券是否在有效期内(用服务端时间,不用设备时间)。
- 是否满足门槛(门槛按券后价还是原价计算)。
- 是否与其它优惠互斥。
- 商品是否在适用范围内。
- 券是否已被占用(下单未支付时可能锁定)。
端上展示「不可用」时必须给出具体原因,不能只把券置灰。用户看不到原因,就会反复尝试,最后变成客服工单。
如果下单时券可用、支付时优惠消失,检查库存或价格变化是否触发了重新计算。价格变化后优惠失效是合理行为,但必须在支付前明确提示,而不是静默改价。
症状五:显示有货,下单失败
库存是交易端最容易「看起来对、实际错」的数据。
常见原因:
- 商品页库存是缓存值,下单时已售罄。
- 库存分仓,展示的是总库存,下单仓无货。
- 限购规则在提交时才校验。
- 并发下单导致超卖保护触发。
排查时不要只看商品页。要看下单接口返回的错误码与库存扣减记录。如果错误码是「库存不足」,端上应刷新商品与购物车,并提示具体是哪个 SKU 不足。
端上不应该在下单失败后自动重试。库存不足是业务拒绝,重试只会放大请求。
症状六:退款不到账
退款涉及三个状态:退款单状态、渠道退款状态、银行到账状态。三者可能不同步。
排查顺序:
- 退款单是否创建成功。
- 审核是否通过。
- 渠道是否受理。
- 渠道是否完成。
- 银行是否入账(通常 1–3 个工作日)。
端上能展示的是前四步;第五步只能给预计时间,不能承诺「立即到账」。
如果退款单显示成功但用户没收到,先确认退款去向:原路退回还是退到余额。原路退回的卡已注销、过期,会导致渠道退款失败,需要人工处理。
退款失败不是终态。端上应展示「退款处理中,请联系客服」,而不是让用户重新申请,造成重复退款。
症状七:会员权益不生效
权益问题先区分「没生效」与「生效了但没展示」。
- 会员价没显示:检查商品是否参与会员价、会员是否在有效期内。
- 折扣没叠加:检查会员折扣与券的叠加规则。
- 积分没到账:检查积分是支付后发放还是完成后发放。
- 权益到期时间不对:检查时区与自然月/自然年的定义。
排查时拿会员快照,而不是当前会员状态。用户下单时的会员等级可能与现在不同,用当前状态解释历史订单会得出错误结论。
积分账本要有流水,不能只有一个余额。余额对不上时,用流水重算;没有流水就无法排查。
症状八:漏斗数据对不上
埋点问题通常不是「少打了一个点」,而是口径不一致。
先确认三件事:
- 分子分母是不是同一批人、同一时间窗。
- 事件是否去重,重试是否产生重复上报。
- 曝光、点击、下单是否用了同一个
sessionId或traceId。
常见差异来源:
- 端上上报失败后重试,服务端没去重。
- 页面曝光在组件挂载时打,路由缓存导致重复曝光。
- 支付成功事件在回跳页打,用户杀掉 App 就丢失。
- 实验分流与埋点分流用了不同的哈希,人群对不上。
漏斗对不上时,先做「同一 orderId 的端上事件与服务端事件能否串起来」这一条检查。串不起来,先修标识,不要急着改埋点数量。
时间线还原
把以下事件按时间排序,画在一张表里:
| 时间 | 来源 | 事件 | 关键字段 |
|---|---|---|---|
| T0 | 端上 | 点击提交 | idempotencyKey |
| T1 | 服务端 | 创建订单 | orderId |
| T2 | 端上 | 拉起支付 | paymentId |
| T3 | 渠道 | 用户完成支付 | 渠道交易号 |
| T4 | 渠道 | 异步回调 | 回调序号 |
| T5 | 服务端 | 订单推进 | 版本号 |
| T6 | 端上 | 查询结果 | traceId |
时间线画出来后,大多数「到底谁的问题」会自然有答案。注意所有时间统一到同一时区,渠道时间可能是 UTC,端上日志可能是本地时间。
证据留存
排查结束后,至少留存:
- 订单快照(下单时的价格、优惠、地址)。
- 支付单列表与渠道交易号。
- 回调原始报文与处理结果。
- 端上日志片段(含
traceId)。 - 用户操作时间与描述。
证据要能回答「当时系统看到的是什么」,而不只是「现在是什么」。订单快照与版本号就是为此存在。
什么时候升级人工
以下情况停止端上自查,转人工或客服:
- 支付成功但订单已取消,需要退款。
- 同一订单存在两笔成功支付。
- 退款单成功但渠道显示失败,或反之。
- 金额差异无法用规则解释。
- 涉及多个账号或疑似盗刷。
- 用户情绪激烈且已多次进线。
升级时带上最小信息集与时间线,不要只转发用户原话。客服拿不到字段,只能再问一遍用户,体验会更差。
小结
交易排查的核心不是背原因清单,而是三件事:
- 先定性再定位。 确认事实、对齐时间、锁定对象。
- 以服务端与渠道为准。 端上展示是视图,不是事实。
- 留证据。 订单快照、支付单、回调报文、日志,缺一不可。
症状会变,方法不变:把「用户说的」翻译成「系统记录的」,再比较两者差在哪一步。
常见错误与边界
- 拿用户描述当事实,不查渠道账单。
- 只看最新一条支付记录,漏掉多次支付尝试。
- 用当前会员状态解释历史订单。
- 把「退款单成功」当成「用户已到账」。
- 时间线不统一时区,得出错误的先后顺序。
- 库存问题只看商品页,不看下单接口错误码。
- 漏斗差异先改埋点数量,不先统一标识。
- 证据只留结论,不留当时的快照与报文。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。