支付结算:付款按钮点下去之后,到底发生了什么?
这是「电商产品能力拆解」系列的第 7 篇·支付结算的上篇。上一篇讲了订单中心——三层结构、12 步生命周期、异常订单三大来源、逆向流程、超时与编排。支付结算这一关非常沉重,所以拆成上下两篇:上篇聚焦"钱怎么进来"——支付方式、支付链路、支付状态机这三个地基;下篇再聊"钱进来之后怎么不出事"——对账、分账、退款、异常资金池。

先看一个”付款报错”的现场
时间:新店铺支付模块上线第二天,早上 10 点。
小A 正在工位上喝咖啡,客服群突然开始连环炸:
用户A: “我付完钱了,订单怎么还显示’待支付’?”
用户B: “我明明没付成功,为什么钱被扣了?”
用户C: “我取消了订单,钱什么时候退给我?”
小A 赶紧打开后台一看,傻眼了——
同一批订单里,“待支付”“支付中”“已支付”“支付失败”“已退款”五种状态交叉打架,有的订单同时出现在”待支付”列表和”已支付”列表里,还有几笔订单钱已经进了商户账户、但订单状态还停在“支付中”。
她翻出前一天熬夜画的支付链路时序图,越看越冷汗:
- 根本没画状态机——订单状态和支付状态揉在同一张表里,一个字段搞定一切;
- 只做了同步跳转——支付结果全靠前端跳回来调一次接口,没做异步回调;
- 没做幂等——用户多点几次”确认支付”,就出现了重复扣款;
- 没有主动查询兜底——只要微信/支付宝的回调丢一次,订单就永远”支付中”。
小A 硬着头皮拨通了老张的电话。

老张听完小A 的描述,只回了一句:
“你这不是‘支付接口写错了’,是把支付当成了一个动作。它不是一个动作,是一条链路——而链路的地基,就是三件事。”
接着老张发来一段话,小A 把它存成了备忘:
做支付产品,要先分清三件事——
一、交易流:用户 → 订单;
二、资金流:钱 → 账户;
三、信息流:状态 → 系统同步。
这三条流在理想情况下一一对应,但在真实生产环境里,它们永远会错位。你的产品工作,就是把这些错位“兜回来”。

先澄清两个认知
在正式拆关之前,先澄清两个小A 一开始就搞混的认知——也是 90% 新手都会栽的坑:
认知一:支付不是”一个接口”,是”一条链路”
很多人以为”接入微信支付”= 调一个 API。错。一次完整的支付涉及 7 个系统 + 2 个异步回调 + N 个状态流转。后面关卡二会展开。
认知二:订单状态机 ≠ 支付状态机
订单篇讲过订单状态机,但订单状态 ≠ 支付状态。一个订单”已支付”不代表钱真到账了,可能只是”支付成功回调到了”。这两个状态机必须分开设计、双轨管理。后面关卡三会展开。
上篇拆 3 道关 · 先把”地基”打稳
支付结算整套完整拆解要过 7 道关卡,上下篇分开讲:
上篇(本篇)· 地基三关 —— 钱怎么进来
第 1 关 · 支付方式全景 —— 用户能用什么付钱
第 2 关 · 支付链路 —— 点“付款”之后发生了什么
第 3 关 · 支付状态机 —— 钱到底在哪一步
下篇 · 进阶四关 —— 钱怎么不出事
第 4 关 · 对账 —— 财务最怕出事的环节
第 5 关 · 分账 —— 多方分钱怎么分
第 6 关 · 退款 —— 钱怎么原路退回
第 7 关 · 异常资金池 —— 最后一道防线
上篇讲完,你可以独立设计一个“能把钱收进来”的支付系统;下篇讲完,才能做到”钱进来之后不出事”。
第一关:支付方式全景图——用户能用什么付钱
小A 的第一个反问:“不就是微信、支付宝、银行卡吗?”
老张笑:“电商平台的收银台里,平均要接 12-18 种支付方式。你要是只知道三种,写出来的 PRD 就只能支撑一个最小 MVP。”
为什么支付方式这么多
每一种支付方式的存在,都对应着某个特定场景下用户最低阻力的选择:
- 用户买 9.9 元的小商品 → 愿意用微信(免密)
- 用户买 999 元的家电 → 愿意用花呗(分期)
- 用户做跨境代购 → 只能用 PayPal 或境外卡
- 用户在门店自提 → 愿意刷 POS(现场核销)
- 企业采购 → 要求对公转账开发票
产品经理的第一课:不是选“最好的支付方式”,是覆盖“用户触达时的最低阻力路径”。
按资金流向分类

每种支付方式的产品要点

产品决策:选支付方式的 3 个原则
原则一:用户画像优先
品牌 X 的数据:
- 30 岁以下用户 → 70% 用微信支付
- 40 岁以上用户 → 50% 用支付宝
- 高客单(>1000 元)→ 35% 选花呗分期
- 跨境商品 → 必须接 PayPal 和境外卡
如果不接花呗,高客单商品转化率会下降 15-20%。
原则二:费率与到账时效平衡

原则三:接入成本要控制
每接一种支付方式 = 一套对接 + 一套回调 + 一套对账 + 一套退款。不要盲目追求“支付方式最全”,要评估 ROI。

第二关:支付链路——点”付款”之后发生了什么
小A 的第二个反问:“不就是前端调个 API 嘛?”
老张说:“这也是你整天对不上账的根因——你以为支付是一个动作,它其实是一条链路。”
7 个系统跳数(完整时序图)
从用户点击”立即支付”按钮,到最终”钱到账”,一笔支付要经过 7 个系统角色 × 2 次异步回调:

7 个跳数的产品要点

为什么第 10 步最容易出事
三个真实事故(品牌 X 上月发生):
- 回调丢失(网络抖动):三方发了通知,订单系统没收到。订单状态还停在”支付中”,用户付了钱订单没更新。
- 回调延迟(支付系统拥堵):订单系统等了 35 分钟才收到回调,但订单已因支付超时自动取消,结果”钱后到账”,变成异常资金。
- 重复回调(三方重试策略):三方 3 秒内发了 3 次回调,订单系统没做幂等,把库存扣了 3 次,用户收到 3 条短信。

这三个事故的解法都写在订单篇下篇“支付三道防线”里——但真正在支付结算模块里实现的,是这些:
支付链路兜底设计
防线一:被动回调 + 主动查询双保险
– 三方通知到 → 立即更新(最快路径)
– 超过 30 秒没通知 → 订单系统主动反查一次
– 每 30 秒主动查询,最多查 10 次(共 5 分钟)
– 任一次成功即完成支付闭环
防线二:全链路幂等
– 支付单号(而非订单号)作为幂等键
– 同一支付单号的任何操作(成功通知/失败通知/查询响应)都要幂等
– 重复请求的返回值必须和第一次请求一致
防线三:异常资金池
– 所有”钱进账但找不到订单”或”订单已取消但钱到了”的交易,进入异常池
– 72 小时内必须处理完:原路退回 / 人工对账 / 转公司应付账款
– 详见关卡七

一个产品小心机
为什么用户看到的是“支付中”而不是“支付成功”?
答:因为用户点击的一刻,钱还没扣。扣款发生在第 8 步,那时用户可能已经退出 App 了。
好的设计:
- 用户点击 → 显示“支付中”
- App 轮询订单系统(5 秒一次)
- 一旦订单系统收到第 10 步回调 → 推送给 App → 显示“支付成功”
坏的设计(小A 第一版设计):
- 用户点击 → 直接显示“支付成功”(基于乐观假设)
- 结果第 10 步回调失败 → 订单实际没支付成功 → 用户以为付款了但系统里是“待支付” → 客诉
第三关:支付状态机——钱到底在哪一步
小A 的第三个反问:“订单状态机不就够了吗?为什么还要单独的支付状态机?”
老张说:“订单关心的是‘货的进度’,支付关心的是‘钱的进度’。这两件事在 80% 的时间里是同步的,但在 20% 的异常时刻会错位——而恰恰是那 20% 决定了你的产品水平。”
支付状态全集
一笔完整的支付,在产品设计上至少要覆盖 8 种状态:

8 种状态说明

+ 1 个兜底状态:异常资金 — 第 7 关展开。
订单状态机 × 支付状态机:映射矩阵
这是小A 在第一版 PRD 里漏掉的——她只设计了订单状态机,没有独立的支付状态机,结果”订单已支付”和”支付成功”混在一起,对账时根本拆不清。

矩阵的价值:
- 绿色(✓ 合法):组合成立,不用管
- 红色(— 非法):组合不该发生,PRD 里必须明确”不可进入”
- 橙色(⚠ 异常):组合可能发生但不合理,是产品必须设计兜底的地方
小A 上月踩的坑——“已取消 + 已支付”组合(矩阵右下橙色加粗格):
订单被超时取消,但支付回调 30 分钟后才到。结果订单是”已取消”,支付是”已支付”。这笔钱就挂在了系统里,进入异常资金池。
解法(关卡七深度展开):
- 检测到“订单已取消 + 支付已到账” → 立即进入异常池
- 系统自动判断:补单(让订单从“已取消”恢复为“已支付”)或原路退款
- 72 小时内必须闭环
支付状态机的 3 条铁律
铁律一:订单状态由支付状态驱动
很多新手 PRD 的错误写法:
“用户支付成功后,把订单状态改为’已支付’。”
这句话逻辑上没问题,但在系统层面是反的。正确的是:
“支付状态机从’支付中’流转到’已支付’时,触发订单状态机从’待支付’流转到’已支付’。”
区别在于:支付状态是因,订单状态是果。如果把它们耦合在一个状态机里,就做不到独立兜底。
铁律二:所有状态变更必须带“来源”
字段设计:
payment_status_log:
– payment_id: 支付单号
– from_status: 变更前状态
– to_status: 变更后状态
– source: 变更来源(user / system / callback / reconcile / manual)
– operator: 操作人(用户ID / 系统名 / 财务人员)
– timestamp: 变更时间
– remark: 备注(必填)
为什么必须带来源?因为财务对账、客诉排查、合规审计,三个场景都要追溯“是谁让它变成这个状态的”。
铁律三:每个异常态都要有退出通道
支付状态机里最容易出事的”死状态”:
- 支付中 → 过了 1 小时还没收到回调:要么主动查询、要么超时关闭
- 部分支付 → 另一通道长时间未到账:要么回滚已到账部分、要么提示用户继续
- 异常资金 → 不能永久卡在这里,72 小时内必须处理
任何状态都要有“进入规则 + 退出规则”,不能只有进入没有退出。

一个小A 踩过的典型坑
场景:品牌 X 上线”组合支付”,允许用户用”积分 + 微信”支付。
小A 第一版设计:
- 积分扣减成功 → 订单状态“已支付”
- 微信支付再进行
问题:积分成功了但微信支付失败,订单状态已经是”已支付”但实际只支付了积分部分。
正确设计:
- 积分扣减成功 → 订单状态“部分支付”
- 微信支付成功 → 订单状态“已支付”
- 微信支付失败 → 回滚积分扣减 → 订单状态“待支付”
关键:组合支付必须有“部分支付”这个中间态,而不是每个支付通道成功就是”已支付”。
自查清单:你的支付地基稳不稳
订单篇问的是“订单系统扎不扎实”和“抗不抗压”,支付篇上篇先问一件事:地基稳不稳。能答对 3 题以上的,才好进下篇的对账、分账、退款、异常资金池。
支付地基(4 题)
1. 所有支付通道都有“被动回调 + 主动查询”双保险吗? 只靠被动回调=钱进账但订单没更新
2. 所有支付接口都做了幂等吗? 用”支付单号”做幂等键,不是订单号——重复回调必须识别出来
3. 订单状态机和支付状态机是独立的吗? 而不是一个字段 status 揉完订单和支付
4. 支付方式的接入是按“用户画像 × 客单价 × 资金成本”选的吗? 还是上来先接个微信和支付宝了事
总结:上篇 · 6 条支付地基认知

一句话总结上篇: 支付系统的地基,不是”接完三个通道就完事”,而是把一条链路、一张双轨状态机、一套兜底与幂等,都提前画清楚。地基稳了,下篇才有资格谈”能扛”。
作者:Zoe产品手记 公众号:Zoe产品手记
本文由 @Zoe产品手记 原创发布于人人都是产品经理。未经作者许可,禁止转载
题图来自作者提供
- 目前还没评论,等你发挥!

起点课堂会员权益




