☰
扫码支付全流程拆解:从商家生成二维码到消费者付款的 PSP 链路
2026/10/2 21:23:27 网站建设 项目流程
  • 后端
  • 文档
  • 教程

【免费下载链接】system-design-101

Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.

项目地址:https://gitcode.com/GitHub_Trending/sy/system-design-101
点击查看免费下载

导读:本文基于 System Design 101 仓库的支付主题文档,完整拆解"扫一扫就完成支付"背后的两个子流程——商家端生成二维码的 7 个步骤,与消费者端扫码付款的 5 个步骤。读完本文,你将理解 PSP(支付服务提供商)、Payment Gateway(支付网关)、动态二维码、防重复支付与清结算在一条扫码交易链路中的真实分工,可用于面试讲解与支付系统设计实践。

扫码支付已经是我们习以为常的支付方式:无论是 Paypal、Paytm、Venmo 等数字钱包,还是微信、支付宝,都在收银台前上演着几乎相同的"扫一扫"。很多人以为这只是把二维码对准摄像头这么简单,但在一秒钟之内,背后其实串联着收银系统、商户电脑、PSP、支付网关和数据库之间的一连串消息传递。

要理解整条链路,最有效的方式是把 "scan to pay"(扫码支付)拆成两个相对独立的子流程:

  1. 子流程一:商家生成二维码并展示在屏幕上;
  2. 子流程二:消费者扫描二维码并完成付款。

两个子流程共同构成一次完整的扫码交易,缺一不可。

子流程一:商家端生成二维码(7 步)

第一个子流程的职责是:把一笔待支付订单转化为一张可被消费者钱包扫描的二维码。整个过程从收银台开始,到收银台结束,全部发生在商家侧,消费者此时还无需介入。

Step 1:收银台生成订单

假设你在超市购物,收银员把所有商品录入系统并计算出应付总额,例如$123.45。此时收银系统(checkout)会生成一个唯一的订单号,例如SN129803。收银员点击 "checkout"(结账)按钮,收银系统便持有了这笔订单的"订单 ID + 应付金额"。

Step 2:收银电脑把订单信息发送给 PSP

收银员点击结账后,收银员电脑(cashier's computer)将这笔订单的订单 ID(SN129803)与金额($123.45)发送给 PSP(Payment Service Provider,支付服务提供商)。这里的 PSP 承担的是"收单 + 处理"的角色,例如 Stripe、Paypal、Paytm 等服务商都具备类似能力。

Step 3:PSP 落库并生成二维码 URL

PSP 收到订单信息后,先将订单 ID、金额等数据持久化保存到数据库中,随后为这笔订单生成一个二维码 URL(QR code URL)。这个 URL 是整个扫码支付的关键载体——它通过 URL 的形式把订单信息(至少包括订单号与金额)编码进二维码内容中,后续消费者的钱包正是通过解析这个 URL 来定位这笔待支付订单。

Step 4:PSP 的支付网关读取二维码 URL

PSP 内部的Payment Gateway(支付网关)服务读取刚才生成的二维码 URL。支付网关是 PSP 面向外部暴露的入口服务,负责校验、路由和转发支付相关请求,因此二维码 URL 的生成与分发由它统一接管。

Step 5:支付网关把二维码 URL 返回给商户电脑

支付网关将二维码 URL(或直接返回二维码图片本身)返回给商户的电脑。这一步是信息从 PSP 侧回流到商户侧的转折点。

Step 6:商户电脑把二维码 URL/图片下发到收银台

商户电脑收到二维码 URL 或图片后,将其发送到具体的收银台(checkout counter)。在实际门店中,这一步通常经由商户局域网或云端收银服务完成。

Step 7:收银台展示二维码

收银台显示器或扫码盒展示出这张二维码,等待消费者扫描。

7 步全部完成耗时不到 1 秒。也就是说,从点击 "checkout" 到二维码亮屏,消费者几乎无感知,这正是"扫码即付"体验的起点。

子流程二:消费者端扫码支付(5 步)

二维码亮屏后,轮到消费者从自己的数字钱包中完成付款。这个子流程同样只有 5 步,但涉及身份校验、金额确认与"已支付"状态的落库。

Step 1:消费者打开数字钱包 App 扫码

消费者打开自己的数字钱包(Paypal、Venmo、Paytm 等),对准商家屏幕上的二维码进行扫描。钱包 App 解析二维码内容(即 Step 3 生成的二维码 URL),识别出订单 ID 与金额。

Step 2:确认金额后点击 "pay" 按钮

钱包 App 向消费者展示这笔订单的金额($123.45)供核对,消费者确认无误后点击 "pay"(支付)按钮。这一步是用户的显式授权,也是后续扣款操作的合法依据。

Step 3:钱包 App 通知 PSP:消费者已为指定二维码付款

消费者点击支付后,钱包 App 调用 PSP 的接口,通知 PSP:消费者已针对某个二维码(对应订单 SN129803)发起了付款。此时 PSP 侧才第一次把"消费者"与"这笔订单"关联起来。

Step 4:PSP 支付网关将二维码标记为已支付,并返回成功

PSP 的支付网关校验付款请求成功后,在数据库中把这张二维码(对应订单)标记为 "paid"(已支付),并向消费者的钱包 App 返回成功消息。这一步是整个链路中最关键的状态转换:二维码/订单状态从 "pending" 变为 "paid",从机制上杜绝了同一张二维码被再次重复支付。

Step 5:PSP 通知商户:消费者已付款

最后,PSP 的支付网关向商户系统发出通知,告知"消费者已为订单 SN129803 支付 $123.45"。商户收银系统据此确认收款成功、放行商品或更新订单状态,一次扫码支付至此闭环。

这次扫码属于四种 QR 支付模式中的哪一种

仓库配套文档 4 Ways of QR Code Payment 指出,所有 QR 码支付都可以从两个维度组合出2×2 = 4 种模式:

  • 谁出示二维码:消费者出示、商户扫描(consumer-presented / 被扫模式) vs 商户出示、消费者扫描(merchant-presented / 主扫模式);
  • 二维码是否动态:静态二维码(static) vs 动态二维码(dynamic)。

本文拆解的场景——商户收银台实时生成、消费者用钱包扫描——正是merchant-presented(商户出示)+ dynamic(动态二维码)的组合:

  • 动态二维码在每次交易时实时生成,因此可以承载丰富信息,例如应付金额、交易类型、订单号等(本例中的 $123.45 与 SN129803 正是被编码进二维码 URL 的信息);
  • 静态二维码只生成一次、随处复用,通常仅包含账户信息,无法携带单笔金额,也就无法直接支持本例这种"按订单金额出码"的模式。

理解了这四种模式,你就知道为什么超市、餐厅的扫码支付绝大多数采用"商户出示 + 动态码"——因为金额随订单变化,且动态码天然具备更强的防篡改与防重复使用能力。

链路背后的核心组件

把两个子流程放在一起看,整条链路围绕几个关键组件运转,这些组件在仓库的支付主题文档中均有印证:

组件在本流程中的职责
收银系统(Checkout)生成订单 ID 与金额,展示二维码(子流程一 Step 1、6、7)
PSP(支付服务提供商)落库订单信息、生成二维码 URL、维护支付状态(Step 2、3、4,子流程二 Step 3、4、5)
Payment Gateway(支付网关)PSP 的入口服务,读取/分发二维码 URL,接收付款通知并返回结果
数字钱包 App解析二维码、确认金额、发起付款、接收成功结果
支付数据库持久化订单、二维码 URL 与"已支付"状态

其中 PSP 与支付网关的关系,可对照仓库文档 The Payments Ecosystem 理解:在完整的支付生态中,商户侧要经过收单银行(acquiring bank)、卡组织(card network)、发卡银行(issuing bank)等多方协作,而 PSP 往往将收单与网关能力聚合后向商户提供统一接口——扫码支付正是 PSP 通过支付网关对外暴露的典型收单能力。

更宏观地看,Payment System 一文展示了点击 "Buy" 按钮后资金在支付服务、支付执行器、钱包、账本(ledger)之间的流转:支付事件入库、按支付订单执行、调用外部 PSP 完成扣款、更新钱包余额、追加账本记录、日终由 PSP 或银行下发结算文件。扫码支付本质上是这套通用支付流水线在"二维码 + 钱包"场景下的具体实例。

可靠性设计:防重复支付与幂等

子流程二 Step 4 中"PSP 支付网关把二维码标记为已支付"这一动作,是扫码支付防重复的核心机制。仓库文档 How to Avoid Double Payment 明确指出:支付系统最严重的问题之一就是向客户重复扣款(double charge),因此在设计时必须保证一笔支付订单被恰好执行一次(exactly-once),而 exactly-once 可以拆解为"至少一次(at least once,靠重试)+ 至多一次(at most once,靠幂等校验)"。

对应到扫码支付场景:

  • 重试(Retry):消费者点击 "pay" 后,若网络抖动导致请求超时,钱包 App 会重发请求,保证付款指令至少送达一次;
  • 幂等(Idempotency):每次支付请求携带唯一幂等键(实践中常用 UUID,Stripe、PayPal 等均推荐该做法,通过 HTTP 头idempotency-key: key_value传递)。PSP 侧对同一个订单/二维码只接受一次有效付款,二维码一旦被标记为 "paid",后续针对它的重复请求将被拒绝或直接返回相同结果,从而把"重复点击、重试、网络重放"都挡在重复扣款之外。

"二维码状态机"(pending → paid)与幂等键结合,正是这条扫码链路在支付可靠性上的两道保险。

支付完成后的资金流转:信息流与资金流分离

需要特别说明的是:消费者在钱包里"看到扣款成功",并不等于真实资金立刻划转到了商户账户。仓库文档 Money Movement 揭示了一个重要事实——信息流(information flow)与资金流(fund flow)是分离的:

  • 交易层与支付清算层属于信息流:在这里,钱"看起来"从一个账户扣除、加到另一个账户;
  • 结算层属于资金流:真实的资金移动发生在结算银行(settlement bank)的备付金账户之间,通常在日终(end-of-day)批量完成;
  • 中间过程依赖清分(clearing)与结算(settlement):清分计算"谁该付谁多少钱"并对交易进行轧差(netting),结算才让真实资金在备付金账户间移动。

正因如此,一笔扫码支付在消费者端的"成功"与资金真正到账之间存在时间差,商户侧需要依赖对账来保证各系统记录一致。仓库文档 Reconciliation in Payment 进一步指出:对账是比较不同系统记录、确保金额一致的过程,会面临数据格式不统一、数据量巨大、日切时间(cut-off time)错位等痛点,实践中通常需要数据规范化层、批处理或流式处理(如 Flink/Hadoop)以及"临时差错 + 次日比对"机制来兜底。可以说,对账系统是扫码支付这类高频交易系统的"安全网"。

总结:一张二维码背后的完整链路

回顾整条扫码支付链路:

  1. 出码阶段(约 1 秒内):收银台生成订单(SN129803 / $123.45)→ 商户电脑送 PSP → PSP 落库并生成二维码 URL → 支付网关读取并回传 → 商户电脑下发 → 收银台亮码;
  2. 付款阶段:消费者钱包扫码 → 确认金额点 "pay" → 钱包通知 PSP → 支付网关标记二维码为 "paid" 并返回成功 → PSP 通知商户收款完成;
  3. 清算阶段(日终/异步):支付指令与资金实际划转分离,依赖清结算与对账保障最终一致性。

下一次你在便利店扫完码、听到收银机"滴"的一声时,可以意识到:这一声背后是收银系统、商户电脑、PSP、支付网关、钱包 App、数据库与日终结算系统共同完成的一次精巧协作。理解这张链路图,也正是理解支付系统设计的第一步——更多支付主题内容可在仓库的 payment-and-fintech 分类 与 How Scan to Pay Works 原文 中继续深入。

  • 后端
  • 文档
  • 教程

【免费下载链接】system-design-101

Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.

项目地址:https://gitcode.com/GitHub_Trending/sy/system-design-101
点击查看免费下载

相关推荐

上一篇:Diffusers 中的 ConsistencyDecoderScheduler:基于一致性模型的两步图像解码调度器详解
下一篇:Ryujinx Switch模拟器:5个简单步骤让您在PC上畅玩任天堂游戏

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询