全球支付网关(Adyen & Stripe)接口级安全策略与架构深度全景图
支付系统的核心安全诉求是**“不仅要防黑客,还要防内鬼,更要防意外”**。为了达到这个目的,全球顶级的支付网关(如 Adyen 和 Stripe)在基础设施、环境隔离、密码学鉴权和前端交互上,构建了一整套极度严密的安全体系。
本文将从支付行业核心概念、通用安全策略、交互流程与安全防线,以及公私钥(RSA/HMAC)非对称/对称加密的交互细节进行全面解析。
一、 支付行业核心概念与标准解析 (Industry Core Concepts)
在深入具体接口前,我们必须理解支付行业用来保命的底层标准和技术概念。
1.1 PCI-DSS (支付卡行业数据安全标准)
- 概念说明:PCI-DSS (Payment Card Industry Data Security Standard) 是由 Visa、Mastercard 等五大信用卡品牌联合制定的信息安全标准,旨在保护持卡人数据,防止信用卡欺诈。这是支付行业的“宪法”。
- 到底管什么?:它严格规定了商户、支付网关、收单行等所有参与方在处理、存储和传输持卡人数据(如 16 位主账号 PAN、姓名、有效期、CVV 验证码等)时必须满足的物理和逻辑安全要求。例如:绝对禁止任何人(包括商户)存储 CVV 码;数据库中敏感数据必须强加密等。
- 对开发者的影响(范围最小化原则):PCI 合规的审计极其严苛且昂贵。为了降低合规成本(即“降级”审核范围),现代支付网关(如 Stripe, Adyen)通过提供前端 UI 组件(如 iframe)或客户端加密技术(CSE),确保商户服务器的内存或数据库根本触碰不到明文的“16位卡号+CVV”。这样商户后端只需处理不敏感的“标记(Token)”即可,极大降低了 PCI 合规负担。
1.2 3D Secure (3DS) / 3DS2
- 概念说明:3D Secure 是一种 XML 协议,用作增加在线信用卡和借记卡交易安全性的额外认证层。它由 Visa 首次推出(即 Verified by Visa),随后 Mastercard (SecureCode) 等也加入。
- 它是干啥用的?:在用户提交卡号后,它会额外引入发卡行(Issuing Bank)的验证流程。
- 怎么验证的?:
- 3DS 1.0 (已淘汰):通常是在支付过程中,突然弹出一个发卡行的丑陋网页,要求用户输入密码或接收短信验证码。这严重破坏了用户体验,导致大量掉单。
- 3DS 2.0 (当前主流):也就是常说的“无感验证”或“强客户认证 (SCA)”。在用户支付时,网关会在后台收集超过 100 个数据点(如设备指纹、IP 地址、浏览器信息、历史购物习惯等)发送给发卡行。
- 无摩擦流程 (Frictionless Flow):如果发卡行的风控系统认为这笔交易风险极低(如老用户在常用设备上小额购物),则直接授权通过,用户完全感知不到 3DS 的存在。
- 挑战流程 (Challenge Flow):只有当系统认为风险较高(如异地大额新设备购物)时,才会要求用户进行二次验证(如输入短信验证码或在银行 App 中确认)。
- 核心优势:一旦使用了 3DS 验证成功的交易发生欺诈性拒付(Chargeback),责任会从商户转移到发卡行(Liability Shift),这能极大保护商户的利益。
二、 支付网关与银行的底层交互链路解析 (How It Actually Works)
了解了基本概念后,我们需要明白,当用户在前端点击“支付”按钮后,这笔钱到底是怎么从用户的银行卡跑到商户的口袋里的?这是一个涉及多方交互的复杂链路。
2.1 参与角色定义
- 持卡人 (Cardholder):想买东西的用户。
- 商户 (Merchant):卖东西的你。
- 支付网关 (Payment Gateway):例如 Stripe, Adyen。它们是连接商户与金融网络的桥梁,负责安全地捕获支付信息并将其路由到正确的地方。
- 收单行 (Acquiring Bank / Acquirer):商户的银行。代表商户处理信用卡付款并维护商户账户的金融机构。Adyen 本身就拥有收单行牌照(这也是它所谓的“全栈”单一平台优势)。
- 卡组织 (Card Networks):如 Visa, Mastercard, AMEX。它们是制定规则和连接发卡行与收单行的中央高速公路。
- 发卡行 (Issuing Bank / Issuer):给用户发信用卡的银行。最终决定这笔钱能不能扣的“大 Boss”。
2.2 资金流转与交互步骤拆解
sequenceDiagram
autonumber
participant User as 用户
participant Merchant as 商户 (前/后端)
participant Gateway as 支付网关 (Stripe/Adyen)
participant Acquirer as 收单行
participant Network as 卡组织 (Visa/MC)
participant Issuer as 发卡行
User->>Merchant: 1. 提交订单并输入卡片信息
note over Merchant: 卡号通过安全组件/加密<br>直接传给网关,商户不碰明文
Merchant->>Gateway: 2. 发起扣款请求 (含Token/密文)
note over Gateway: 3. 网关内部风控 (Radar/RevenueProtect)<br>可能触发 3D Secure 验证
Gateway->>Acquirer: 4. 路由交易请求 (授权阶段)
Acquirer->>Network: 5. 将请求通过对应卡组织网络转发
Network->>Issuer: 6. 请求发卡行授权
note over Issuer: 7. 发卡行检查:卡号对吗?<br>余额够吗?有欺诈风险吗?
Issuer-->>Network: 8. 返回授权结果 (Approved / Declined)
Network-->>Acquirer: 9. 转发结果
Acquirer-->>Gateway: 10. 转发结果
Gateway-->>Merchant: 11. 通知商户支付结果 (同步API + 异步Webhook)
Merchant-->>User: 12. 页面显示支付成功/失败
note over Merchant,Issuer: --- 以下为后续资金清算流程 (Clearing & Settlement) ---
Merchant->>Gateway: [T+1或更久] 批量发起清算请求 (Capture)
Gateway->>Acquirer: 请求结算资金
Acquirer->>Network: 请求卡组织清算
Network->>Issuer: 从发卡行划拨真实资金
Issuer-->>Network: 资金划转给卡组织
Network-->>Acquirer: 资金划转给收单行
Acquirer-->>Merchant: 资金打入商户最终的银行账户 (Payout)
关键交互节点说明:
- 授权 (Authorization - 步骤 1-12):这一步是最快的,通常只需几秒钟。发卡行只是冻结了用户卡里的这笔钱,并没有真正把钱划走。这就是为什么你买东西时会立刻收到扣款短信,但资金还没真正结算。
- 清算与结算 (Clearing & Settlement - 步骤后面的流程):这是实际转移资金的过程,通常在授权后的 1-3 天内批量发生(通常称为 T+1, T+3 等)。
- Stripe 的模式:通常默认开启自动捕获 (Auto-Capture),在授权成功后自动进入清算流程。
- Adyen 的模式:Adyen 同时扮演网关和收单行的角色,这使得它能省去网关到收单行之间的通信损耗,提供更高的授权成功率和更透明的数据分析。
三、 核心安全策略与架构防线 (Security Strategies)
为了保护上述复杂的流转过程,防止黑客、内鬼和意外,支付网关设计了以下防御心法:
3.1 零信任架构 (Zero Trust Architecture)
- 概念说明:永远不要相信从前端传来的任何“成功”状态,永远不要相信没有携带签名的异步回调。
- 策略实现:基于 HMAC 算法的 Webhook 签名验签(确保通知是官方发的),以及前端页面渲染必须依赖后端请求网关获取的一次性“加密票据”(确保金额和订单号没被篡改)。
3.2 防重放与幂等性 (Idempotency against Replay Attacks)
- 概念说明:网络波动时,由于没有收到响应,服务器可能会重试扣款请求。如果没有防重放机制,用户会被连环扣费(重大事故)。
- 策略实现:所有创建订单/扣款的 POST 请求,Header 中必须强制携带
Idempotency-Key(通常是订单号或 UUID)。网关对同一个 Key 只处理一次,后续相同 Key 的请求直接返回第一次的缓存结果。
3.3 环境隔离与密钥体系管理 (Environment & Key Isolation)
为了防止“测试环境的测试卡号不小心真扣了钱”,或者“真实的生产密钥被泄露到了测试服务器”,Stripe 和 Adyen 在环境和路由隔离上做出了精妙的设计。
- 密钥字面量隔离 (Stripe):在密钥的字符串设计上直接进行了物理级隔离:
- Test 环境:公钥
pk_test_...,私钥sk_test_... - Live 环境 (生产):公钥
pk_live_...,私钥sk_live_... - 这种设计使得代码审查极其容易,运维可以瞬间阻断将测试密钥发布到生产的错误。
- Test 环境:公钥
- 端点路由级隔离与防 DDoS (Adyen):不仅在逻辑上区分了 Live 和 Test 的 API Key,更在网络路由层做出了基于企业的物理级隔离:
- Live 环境必须使用专属的 Live URL Prefix (企业前缀)。例如
https://[1797a841fbb37ca7-CompanyDemo]-checkout-live.adyenpayments.com/v70/payments。 - 防止吵闹的邻居与 DDoS:如果某个商户遭遇 DDoS,黑客只能攻击该商户专属的域名,其他商户丝毫不受影响。同时这种设计也能将请求极速路由到离该商户数据最近的物理集群。
- Live 环境必须使用专属的 Live URL Prefix (企业前缀)。例如
3.4 网络层访问控制与白名单防御 (Network Access Control & Whitelists)
仅有密钥和签名是不够的,支付系统必须在网络传输层建立起白名单围栏:
- API 请求的 IP 白名单 (Outbound):商户调用支付网关(如支付宝、微信、Adyen)时,网关后台可以强制配置只接受来自商户“特定服务器公网出口 IP”的请求。哪怕私钥被内鬼或黑客盗取,只要他不在商户真实的机房里发起扣款或退款请求,就会被网关在防火墙层直接拦截。
- Webhook 回调的 IP 白名单 (Inbound):商户服务器的防火墙/网关(如 Nginx, WAF)必须配置,只放行支付机构官方公布的网段所发送的回调请求(如 Stripe/Adyen/微信的官方 IP 列表),从根源上拦截所有来自未知公网 IP 的伪造回调请求。
- 域名与目录白名单 (Domain Whitelisting):在前端唤起支付组件(如微信 JSAPI 支付、Stripe Elements)时,支付机构会严格校验前端发起请求的
Referer和Origin。如果请求不是来自商户在后台提前登记认证过的安全域名或授权目录,会被直接阻断。这极大地防止了黑客通过 XSS 或跨站伪造把商户的支付组件嵌到钓鱼网站上去骗用户的钱。
3.5 金额与状态的最终一致性对账 (Reconciliation)
- 概念与风险:虽然所有的架构都设计了实时异步回调(Webhook),但在极端的网络故障、机房断电或代码 Bug 下,依然可能出现回调丢失,导致“单边账”(比如用户的钱被扣了,但是商户的数据库没更新,没给用户发货)。
- 兜底策略:安全体系的最后一道防线是建立“推拉结合”的最终一致性对账机制。
- 短周期主动查询 (Polling):在发起支付后,商户后端应开启退避重试的定时任务(如 1分钟、5分钟、15分钟),主动调用网关的“订单状态查询 API”来核实支付结果。绝对不能“死等” Webhook。
- 长周期 T+1 清算对账 (Settlement Reconciliation):每天凌晨,商户财务系统自动下载支付网关和收单行前一天的清算明细账单(Settlement Report),与商户本地数据库的订单表进行逐笔核对金额和流水号,发现长款或短款(差错账)立即触发冲正或人工介入。
四、 Stripe 与 Adyen 详细安全交互流程拆解
接下来,我们将从开发者接入的视角,基于目前最主流的前端嵌入式组件接入方式,拆解两家巨头是如何在代码层面落实上述安全策略的。
4.1 Stripe 交互流程 (基于 Elements / Payment Intents)
Stripe 的核心安全哲学是基于状态的 PaymentIntent 结合前端 Token化隔离。
sequenceDiagram
autonumber
participant User as 用户
participant Client as 商户前端 (Browser / App)
participant Server as 商户后端 (Server)
participant Stripe as Stripe 服务器
note over Server,Stripe: 后端通信使用 Secret Key (绝对保密)
Server->>Stripe: 创建 PaymentIntent (含金额、币种、防重放 Idempotency-Key)
Stripe-->>Server: 返回 client_secret (该订单的唯一标识)
Server-->>Client: 将 client_secret 传递给前端
note over Client,Stripe: 前端通信使用 Publishable Key (公钥)
User->>Client: 在页面输入卡号 (实为 Stripe 托管的 iframe)
Client->>Stripe: 前端组件用公钥 + client_secret 直接提交加密卡号
note over Stripe: Stripe 内部执行 Radar 风控与 3D Secure 判断
Stripe-->>Client: 若需 3DS,直接在前端弹窗验证;验证后返回最终状态
Client-->>Server: 前端回调 (通知后端支付操作已结束,但状态不可靠)
note over Server,Stripe: 极其重要的最终安全确认环节
Stripe->>Server: 异步触发 Webhook (如 payment_intent.succeeded)
Server->>Server: 校验 Webhook Header 中的 Stripe-Signature 签名
Server->>User: 确认签名无误后,更新数据库并完成发货
核心安全防线与内部验证机制拆解:
-
微观拆解:公钥 + client_secret 是如何工作的?(步骤 4 & 5)
- 角色分工:
Publishable Key(如pk_live_xxx):只用来在 Stripe 内部定位“这是哪家商户的请求”,它没有任何扣款权限,只能用来对敏感数据进行 Token 化。client_secret(如pi_3Mxxx_secret_yyy):这是商户后端在步骤 2 创建PaymentIntent(支付意图)时,Stripe 生成的一把“一次性钥匙”。它不仅包含了这笔订单的 ID(pi_3Mxxx),其后半段的secret则是用来证明“当前前端会话是被授权来完成这笔特定订单的”。
- 内部提交流程:当用户点击“支付”时,商户页面上的 JS 代码调用
stripe.confirmPayment。此时,Stripe 托管的iframe会直接向 Stripe 的 API 服务器(api.stripe.com)发起 HTTPS POST 请求。这个请求中包含了:用户输入的原始明文卡号(因为是 iframe 直接连 Stripe,中途不经过商户,所以极其安全)、Publishable Key和client_secret。 - Stripe 的内部验证逻辑:
- Stripe 收到请求,先用
Publishable Key确认是你的商户账号。 - Stripe 从
client_secret中提取出PaymentIntent ID,去数据库里查到对应的“支付意图”(里面有事先锁定的金额 100 美元、币种等)。 - 【最核心的鉴权】 Stripe 校验传过来的
secret是否与数据库中该PaymentIntent匹配。如果匹配,说明这个前端请求是合法的,不是黑客凭空捏造的。 - Stripe 将明文卡号安全地转换为
PaymentMethod(支付方式 Token),并将其绑定到这个PaymentIntent上,随后立刻向发卡行发起 100 美元的授权请求。整个过程,卡号的明文只在用户的浏览器内存和 Stripe 的核心机房里出现过,商户端全程“隐身”。
- Stripe 收到请求,先用
- 角色分工:
-
前端跨域隔离 - iframe 机制 (步骤 4):用户输入信用卡号时,实际上是在填写一个嵌入在你网页中的跨域
iframe。基于浏览器的同源策略,商户网页的任何脚本(包括被黑客植入的恶意 XSS 脚本)都绝对无法读取该 iframe 内部的内容(即真实卡号),完美豁免 PCI。 -
零信任的最终确认 - Webhook 验签 (步骤 8 & 9):前端状态绝对不可信(因为前端页面可以被篡改显示“支付成功”)。商户后端必须依赖 Stripe 服务器异步发送的带有
Stripe-Signature头部的 Webhook。商户后端进行 HMAC 验签,这是防伪造发货的最关键节点。
4.2 Adyen 交互流程 (基于 Drop-in / Sessions API)
Adyen 的最新安全架构倾向于基于生命周期的 Session 闭环控制。后端先向 Adyen 注册一笔交易,前端在此 Session 内完成所有敏感交互。
sequenceDiagram
autonumber
participant User as 用户
participant Client as 商户前端 (Browser / App)
participant Server as 商户后端 (Server)
participant Adyen as Adyen 服务器
note over Server,Adyen: 后端通信使用 API Key
Server->>Adyen: 发起 /sessions 请求 (含金额、币种、防欺诈购物者数据)
Adyen-->>Server: 返回 sessionData 和 sessionId
Server-->>Client: 将 sessionData 传递给前端
note over Client,Adyen: Client Key 用于前端组件初始化验证
Client->>Client: 使用 sessionData 初始化 Adyen Drop-in 组件
User->>Client: 在 Drop-in iframe 中输入支付信息
Client->>Adyen: 组件内部直接与 Adyen 通信,提交加密卡号并进行鉴权
note over Adyen: Adyen 执行 RevenueProtect 风控与 3D Secure 路由
Adyen-->>Client: 直接在组件内完成 3DS 验证,返回最终支付结果 (Authorised 等)
Client-->>Server: 将 resultCode 传给商户后端做页面展示
note over Server,Adyen: 基于 HMAC 的权威状态确认
Adyen->>Server: 异步触发 Webhook Notification (AUTHORISATION)
Server->>Server: 校验 Webhook 请求体中的 HMAC 签名
Server->>User: 签名校验通过,更新订单状态为已支付
核心安全防线拆解:
- Session 防篡改机制 (步骤 1 & 2):后端先用高权限
API Key向 Adyen 注册交易获取加密的sessionData。前端凭借此数据初始化组件,彻底堵死了前端篡改支付金额、篡改回调地址的攻击路径。 - 客户端加密 (CSE - 基于 RSA 公私钥的底层加密交互):
如果商户不使用全托管 iframe,Adyen 强制要求在浏览器端进行 RSA 非对称加密。
- Adyen 服务器持有私钥并保管在最高安全级的物理加密机 (HSM) 中。
- 商户前端获取公钥(Client Key),在浏览器端直接使用公钥将卡号加密成不可逆的密文 Blob。
- 密文 Blob 经过商户后端(后端无法解密,彻底豁免 PCI)传给 Adyen 网关,最后进入 Adyen HSM 解密。
- RevenueProtect 风控指纹网络:在 Session 初始化和组件通信时,静默收集设备指纹、网络环境等数据,通过机器学习模型实时判断是否需要触发 3D Secure。
- IP 白名单与 Basic Auth 兜底:除了 Webhook 的 HMAC 签名校验外,Adyen 强烈建议商户在防火墙层面配置只允许 Adyen 的官方网段 IP 发起回调,并支持配置 Basic Auth,构建深度防御。
五、 核心安全差异总结 (开发与架构视角)
| 安全维度 | Stripe | Adyen |
|---|---|---|
| 整体架构 | 边界防御。通过极简 API 隔离商户系统与 Stripe 的核心账本。 | 单一封闭平台。从网关到收单全部在自建封闭系统中,无第三方接口外露。 |
| 前端敏感数据隔离 (PCI降级) | 极其成熟的 iframe 跨域隔离 (Stripe Elements),商户代码无权触碰卡号输入框。 | iframe 隔离 (Drop-in) + 强制的客户端非对称加密 (CSE)。 |
| 防篡改与金额保护 | 通过后端先创建 PaymentIntent 锁定金额,前端凭 client_secret 支付。 | 通过后端创建 Session 加密包,前端凭 sessionData 启动组件。 |
| 欺诈拦截与 3DS | Radar:侧重纯线上互联网生态数据。原生支持无感 3DS2 验证。 | RevenueProtect:侧重跨国大型商户全渠道数据打通。强大的设备指纹收集体系。 |
| 权威状态确认 (防伪造) | 异步 Webhook + Header 中的 Stripe-Signature (HMAC验签 + 时间戳防重放)。 | 异步 Notification + JSON Body 中的 HMAC 签名 + IP 白名单。 |
结论: 从技术落地的角度看,两家都完美贯彻了**“敏感信息绝对不碰商户后端”和“支付最终状态绝对不信任前端”**这两个安全铁律。
- Stripe 把安全设计的重心放在了开发者体验上,用最少的 API 调用次数和极其优雅的前后端隔离,帮开发者把安全漏洞堵死。
- Adyen 则更偏向企业级管控,其 Session 机制、强制路由前缀和底层全栈收单属性,最大程度消除了全渠道支付中可能产生的数据流转风险。
六、 中国本土支付双巨头:支付宝 (Alipay) 与微信支付 (WeChat Pay) 安全架构全景解析
与基于信用卡体系(需严格遵守 PCI-DSS)的 Stripe 和 Adyen 完全不同,支付宝和微信支付属于基于账户体系(电子钱包生态)的支付方式。商户系统完全不需要触碰用户的银行卡等敏感金融信息,因此天然豁免 PCI 合规要求。
它们的安全性主要依赖于复杂的非对称加密/对称加密体系、X.509 证书信任链以及端到端(App 唤起/小程序闭环)的严格授权机制。
6.1 支付宝 (Alipay) 交互流程与安全细节
支付宝接入(如 App 支付、手机网站支付)的核心心法是:“前端凭单跳转,后端把控签名”。防伪造的核心在于双向 RSA2 (SHA256WithRSA) 非对称加密。
sequenceDiagram
autonumber
participant User as 用户
participant Client as 商户前端 (App/H5)
participant Server as 商户后端 (Server)
participant Alipay as 支付宝 (作为收单机构)
participant NUCC as 网联/银联 (清算机构)
participant Issuer as 发卡行
participant PBOC as 央行 (备付金存管/支付系统)
User->>Client: 1. 提交订单并选择支付宝
Client->>Server: 2. 请求支付参数 (含业务单号、金额等)
note over Server: 3. 核心加签:使用【应用私钥】对订单<br/>及业务参数进行 RSA2 签名
Server-->>Client: 4. 返回加签后的 OrderString (含sign)
note over Client,Alipay: 5. 跨应用信任闭环
Client->>Alipay: SDK 携带 OrderString 唤起支付宝App/收银台
Alipay->>Alipay: 内部使用商户预留的【应用公钥】验签<br/>展示支付密码盘与金额
User->>Alipay: 6. 输入支付密码或刷脸验证
note over Alipay,Issuer: 7. “断直连”架构:必须经清算机构路由至发卡行扣款
Alipay->>NUCC: 发起快捷支付扣款请求
NUCC->>Issuer: 转发扣款指令
Issuer-->>NUCC: 扣款成功 (真实资金冻结/转移)
NUCC-->>Alipay: 返回扣款结果 (成功)
Alipay-->>Client: 8. 同步返回前端支付结果 (仅作UI提示,绝对不可信)
note over Server,Alipay: 9. 绝对权威的异步通知与验签
Alipay->>Server: 异步触发 Webhook (POST 请求携带 sign)
Server->>Server: 强制使用【支付宝公钥】对回调报文进行 RSA2 验签
Server->>User: 10. 验签无误且金额核对一致,更新状态并完成发货
note over Alipay,PBOC: --- 以下为底层异步资金清算与结算流程 (T+1 等) ---
NUCC->>PBOC: 每日定时发送清算轧差指令
PBOC->>PBOC: 央行支付系统(ACS):将资金从发卡行准备金账户划拨至支付宝在央行的集中交存备付金账户
Alipay->>Server: (T+1或协议周期) 将资金结算打入商户真实的银行对公账户
核心安全防线拆解 (支付宝):
- 私钥绝不出内网:最终唤起支付宝的
OrderString(包含金额、订单号等一切核心参数)必须在商户服务器内部,使用商户应用私钥进行计算签名。前端无法篡改任何字段(比如改金额),因为一旦篡改,支付宝内部用公钥验签必败。 - 双向非对称鉴权:商户向支付宝发请求,用“应用私钥”签名,支付宝用“应用公钥”验签;支付宝向商户发异步通知,用“支付宝私钥”签名,商户用“支付宝公钥”验签。以此完成彻底的双向身份互信。
- 防重放与唯一性屏障:商户侧的
out_trade_no(商户订单号)在支付宝系统中是唯一凭证,重复或被拦截篡改的二次重放请求将被直接拒接。
6.2 微信支付 (WeChat Pay API v3) 交互流程与安全细节
微信支付 API v3 采用了严格的 RESTful 架构和基于 Authorization 请求头的 HTTP 签名认证体系,安全性极为严苛,甚至引入了平台证书定时轮换机制和敏感报文 AES 加密机制。
sequenceDiagram
autonumber
participant User as 用户
participant Client as 商户前端 (微信小程序/App)
participant Server as 商户后端 (Server)
participant WeChat as 微信支付 (作为收单机构)
participant NUCC as 网联/银联 (清算机构)
participant Issuer as 发卡行
participant PBOC as 央行 (备付金存管/支付系统)
User->>Client: 1. 提交订单并选择微信支付
Client->>Server: 2. 请求统一下单 (通常需携带用户 openid)
note over Server,WeChat: 3. 严格的 HTTP Header 签名认证
Server->>WeChat: 调用 v3/pay/transactions 下单 API<br/>(Header 带上用【商户私钥】生成的签名)
WeChat->>WeChat: 使用【商户证书】验证签名,生成预支付会话 prepay_id
WeChat-->>Server: 4. 返回 prepay_id
note over Server: 5. 关键的二次签名:将 prepay_id、时间戳、<br/>随机串等,用【商户私钥】再次签名
Server-->>Client: 6. 返回二次签名后的支付参数 (含 paySign)
Client->>WeChat: 7. 调用 wx.requestPayment (携带 paySign) 唤起收银台
User->>WeChat: 8. 验证指纹/密码完成支付
note over WeChat,Issuer: 9. “断直连”架构:必须经清算机构路由至发卡行扣款
WeChat->>NUCC: 发起快捷支付扣款请求
NUCC->>Issuer: 转发扣款指令
Issuer-->>NUCC: 扣款成功 (真实资金冻结/转移)
NUCC-->>WeChat: 返回扣款结果 (成功)
WeChat-->>Client: 10. 前端同步回调 (仅作UI提示)
note over Server,WeChat: 11. Webhook 证书验签 + 报文 AES 深度解密
WeChat->>Server: 异步通知 (报文 resource 部分被 AES-256-GCM 加密)
Server->>Server: 1. 使用动态下载的【微信平台证书】验证通知 Header 签名<br/>2. 使用【APIv3密钥】解密报文密文 (还原订单号、支付者等数据)
Server->>User: 12. 验证订单金额与状态,更新状态并完成发货
note over WeChat,PBOC: --- 以下为底层异步资金清算与结算流程 (T+1 等) ---
NUCC->>PBOC: 每日定时发送清算轧差指令
PBOC->>PBOC: 央行支付系统(ACS):将资金从发卡行准备金账户划拨至微信支付在央行的集中交存备付金账户
WeChat->>Server: (T+1或协议周期) 将资金结算打入商户真实的银行对公账户
核心安全防线拆解 (微信支付 v3):
- 平台证书动态信任链:为了防范证书静态泄露,微信支付会定期更换平台证书。商户系统必须实现平台证书的定时下载与平滑更新机制。如果证书过期,商户将立刻无法验证微信的回调签名。
- 二次签名防注入机制:获取到
prepay_id后绝不能直接给前端,商户后端必须将prepay_id配合当前时间戳和随机字符串,使用商户私钥再做一次 RSA 签名 (paySign)。前端带着这个paySign才能唤起微信。这彻底防范了恶意劫持者注入伪造prepay_id诱导用户替他人买单的风险。 - 双重防线 (Header 验签 + 密文解密):微信的回调通知极其谨慎。不仅请求头有 RSA 签名防伪造,其核心业务数据更是被强制使用对称算法(
AES-256-GCM)结合商户配置的APIv3密钥进行加密。即使网络链路被劫持且签名被意外绕过,没有 APIv3 密钥,黑客也只能看到一堆乱码,杜绝了数据泄露。
6.3 总结对比 (Stripe/Adyen vs 支付宝/微信支付)
| 安全维度 | 国际网关 (Stripe / Adyen) | 本土巨头 (支付宝 / 微信支付) |
|---|---|---|
| 底层生态与合规 | 信用卡网络主导,必须利用 iframe / CSE 加密等手段隔离 16位卡号与 CVV,应对严苛的 PCI-DSS 审查。 | 电子钱包生态主导,卡号在官方 App 内闭环,商户只处理流水号,天然无 PCI 合规负担。 |
| 前端鉴权交互 | 颁发一次性密钥。如 Stripe 的 client_secret 或 Adyen 的 sessionData 启动前端组件。 | 颁发加签参数。后端直接对支付参数进行 RSA 签名 / 二次签名 (OrderString 或 paySign),交给前端去唤起官方 App。 |
| 异步回调与防伪造 | Webhook 基于 HMAC 对称摘要验签 (或基于 IP 白名单限制)。 | Webhook 基于 RSA 非对称验签(验证支付宝公钥 / 微信平台证书签名)。微信进一步要求 AES-256-GCM 密文解密。 |
| 风控侧重点 | 极其依赖设备指纹采集与基于规则/机器学习的风控系统 (Radar/RevenueProtect) 以及 3D Secure 弹窗拦截欺诈。 | 极其依赖官方 App/小程序内部的风控体系、实名认证体系和设备可信环境(由腾讯/阿里安全部在端内兜底风控)。 |
七、 补充架构原理解析:收单机构与断直连
在对比国内外支付网关时,有两个容易混淆的底层金融架构概念需要特别澄清:
7.1 为什么 Adyen 和 Stripe 不是国内意义上的“收单机构”?
这本质上是国际信用卡四方模式与国内电子钱包生态的区别:
- Adyen 为什么是收单机构?:Adyen 拥有欧洲的银行牌照和全球多地的收单牌照。在国际上,它确确实实是正牌的“收单机构”(Acquiring Bank),能自己完成资金的收单清算(这也是它“全栈”的优势)。
- 为什么全栈了还要和别的收单行交互?:其实在 Adyen 的“全栈”模式下,它通常不需要再把请求转给其他收单行了(这正是图中它比 Stripe 强的地方)。但图 2.2 中的
Gateway->>Acquirer是为了展现通用的支付网关架构。在某些国家/地区,如果 Adyen 没有拿到当地的收单牌照(Local Acquiring License),它就只能降级为纯“支付网关”角色,此时它必须将请求路由给当地合作的真实“收单行”来完成扣款。
- 为什么全栈了还要和别的收单行交互?:其实在 Adyen 的“全栈”模式下,它通常不需要再把请求转给其他收单行了(这正是图中它比 Stripe 强的地方)。但图 2.2 中的
- Stripe 的定位:Stripe 早期没有收单牌照,定位是“支付服务商/网关”(PayFac)。当你用 Stripe 扣款时,Stripe 背后实际上要调用它合作的真正的“收单行”(比如美国的 Wells Fargo 富国银行)来向卡组织发起请求。
- 支付宝/微信的“收单”角色:在国内电子钱包生态下,商户直接调用微信/支付宝的 API,此时支付宝/微信对商户来说就是收单机构(它们持有央行颁发的《支付业务许可证》)。它们在内部闭环处理交易,然后通过网联去发卡行扣钱,中间不需要像 Stripe 那样再去挂靠一个传统的商业银行作为“收单行”。
7.2 什么是中国特有的“断直连”架构?
“断直连”(断开直接连接)是中国央行(PBOC)在 2018 年前后强制推行的一项底层清算架构改革。
- 断直连之前(野蛮生长时代):支付宝和微信绕开银联,直接和全国几家百家银行拉专线建接口(直连)。资金直接在“买家银行卡 支付宝在各银行的备付金账户”间流动。这导致央行看不到真实的资金流向,存在极大的监管盲区。
- 断直连之后(合规枢纽模式):
- 信息流强制路由:央行规定第三方支付机构严禁与银行直连。所有的跨行快捷支付请求,必须先发送给国家级的清算枢纽——网联(NUCC)或银联,由它们转发给具体的发卡行。这就是为什么在时序图中,必须画出
支付宝 -> 网联 -> 发卡行的路径。 - 资金流 100% 集中交存:支付宝/微信不能再把钱存在商业银行吃利息,所有沉淀资金必须 100% 存入央行指定的备付金集中交存账户。用户的真实资金划转,最终都在央行的支付系统(ACS)内完成。
- 信息流强制路由:央行规定第三方支付机构严禁与银行直连。所有的跨行快捷支付请求,必须先发送给国家级的清算枢纽——网联(NUCC)或银联,由它们转发给具体的发卡行。这就是为什么在时序图中,必须画出