支付结算:付款按钮点下去之后,到底发生了什么?

0 评论 116 浏览 1 收藏 19 分钟

这是「电商产品能力拆解」系列的第 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 上月发生):

  1. 回调丢失(网络抖动):三方发了通知,订单系统没收到。订单状态还停在”支付中”,用户付了钱订单没更新。
  2. 回调延迟(支付系统拥堵):订单系统等了 35 分钟才收到回调,但订单已因支付超时自动取消,结果”钱后到账”,变成异常资金。
  3. 重复回调(三方重试策略):三方 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 分钟后才到。结果订单是”已取消”,支付是”已支付”。这笔钱就挂在了系统里,进入异常资金池。

解法(关卡七深度展开):

  1. 检测到“订单已取消 + 支付已到账” → 立即进入异常池
  2. 系统自动判断:补单(让订单从“已取消”恢复为“已支付”)或原路退款
  3. 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产品手记 原创发布于人人都是产品经理。未经作者许可,禁止转载

题图来自作者提供

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 目前还没评论,等你发挥!