【免费下载链接】hyperswitch-prism
One library | Many payment processors | Scale to multiple processors with few lines of code.
支付不是一次"请求—返回"那么简单:卡片先被冻结(Authorize),资金在发货后才真正划走(Capture/Settlement),退款可能一周后才发生,3DS 验证还会把交易"挂起"在等待用户确认的中间态。本文带你用 5 个关键环节看懂 hyperswitch-prism 的支付生命周期——它把 Stripe、Adyen、PayPal 等 50+ 支付处理器的差异收敛成一台清晰的状态机,让"授权、捕获、结算、退款、回调"每一步都有明确的边界。
先搞清楚:Authorize 和 Settlement 到底差在哪?
很多新手把"支付"当成一个动作,但在真实的资金世界里,一笔支付是一条时间线:
- Authorize(授权):只是"冻结"这笔钱,用户卡上会多出一笔 pending 交易;
- Capture(捕获):真正把冻结的钱划走,这一步之后才算"收到了钱";
- Settlement(结算):银行/卡组织之间的清算落账,通常由处理器侧异步完成,通过 Webhook 通知你最终结果。
⚠️ 常见坑:在 Authorize 成功的瞬间就发货,万一冻结后来被拒绝或过期,你就白发了货。
hyperswitch-prism 把这条时间线拆成 5 个关键环节,每个环节对应独立的 API 方法,而不是一个可随意改写的status字段。
| 关键环节 | 干什么 | Prism 中的方法/客户端 |
|---|---|---|
| ① 认证与风控 | 3DS / SCA 验证持卡人身份 | MerchantAuthenticationClient、authType |
| ② Authorize 授权 | 冻结资金,不真正扣款 | PaymentClient.authorize() |
| ③ Capture 捕获与 Settlement | 划走资金、等待结算落账 | capture()、get()、Webhook |
| ④ Refund 与 Void | 退钱,或释放未捕获的冻结 | refund()、void()、reverse() |
| ⑤ 异步 Webhook | 结算/退款等事件的统一入口 | EventClient.handleEvent() |
官方对状态机和服务划分的完整描述见 docs/blogs/authorization-to-settlement.md 与 docs/architecture/concepts/services-and-methods.md。
环节一:认证与风控——AUTHENTICATION_PENDING 状态
第一环发生在扣钱之前:验证"这个持卡人本人是否真的在付款"。常见形式有 3D Secure(3DS)和欧洲的 SCA 强客户认证。
在 Prism 的生命周期状态机里,支付一开始是STARTED,如果需要风控挑战,会进入AUTHENTICATION_PENDING——整个交易被"挂起",等待用户在一个你的服务器看不见的浏览器窗口里完成验证。
STARTED → AUTHENTICATION_PENDING → AUTHORIZED → CHARGED → (refund 子流程) │ │ │ (3DS / SCA) (钱被冻结) (钱被划走)Prism 的 API 直接映射这台状态机:生命周期被拆成一个个"动词"方法,分布在不同的客户端里,你能调用的方法就是这笔支付实际允许的状态迁移,而不是update({ status: "..." })这种可以写错的方式。
图:钱包支付中"用户在设备端授权 → 令牌交给处理器 → Authorize"的完整链路,认证环节对商户服务器完全透明。
环节二:Authorize 授权——冻结资金的核心一步
authorize()是生命周期的主入口。无论底层是 Stripe 还是 Adyen,你都用同一个请求结构发起授权,核心字段只有几个:
| 字段 | 含义 |
|---|---|
merchantTransactionId | 你自己系统里的交易号(幂等键) |
amount | { minorAmount, currency }金额 + 币种 |
captureMethod | AUTOMATIC(授权即扣款)或MANUAL(稍后捕获) |
authType | 是否触发 3DS 风控 |
paymentMethod | 卡片、钱包 token 等支付方式 |
两个容易忽略的细节:
- 金额是"按币种缩放的整数":
minorAmount: 1000在 USD 里是 $10.00,在 JPY 里是 ¥1000。Prism 统一用最小货币单位(minor unit),自动转换成各处理器的原生格式,从根上消灭"100 倍偏差"和浮点误差。详见 docs/architecture/frameworks/money-struct.md。 captureMethod决定业务语义:SaaS/数字商品用AUTOMATIC立即扣款;电商常用MANUAL,等仓库确认发货再捕获。
授权成功拿到connectorTransactionId——它是后续所有环节(捕获、退款、撤销)的唯一钥匙。
环节三:Capture 捕获——从 AUTHORIZED 到 CHARGED
捕获是"真正收到钱"的时刻,对应状态从AUTHORIZED迁移到CHARGED。Prism 里capture是独立方法,而不是改一个状态字段——你没法对一个从未授权的支付"手滑"触发捕获。
这一环有几个实用玩法(完整示例见 docs/getting-started/extend-to-more-flows.md):
- 部分捕获(Partial Capture):授权 $100,第一批发货捕获 $40,第二批再捕获 $60;
- 增量授权(Incremental Authorization):酒店入住先冻 $100,客人加了客房服务后把冻结提到 $150,退房时按实际金额捕获;
- Settlement 落账:捕获后,资金在银行侧完成清算,最终结果往往通过 Webhook(
PAYMENT_INTENT_CAPTURE_SUCCESS之类的事件)异步确认。所以查状态时如果还没有结果,Prism 会返回PENDING而不是报错——"未知"意味着"过一会儿再查",而不是"这单失败了"。
✅ 最佳实践:发货/交付只认 Capture,不认 Authorize。这是大多数支付事故的根源。
各方法的完整参数与返回见 API 参考:authorize、capture。
环节四:Refund 与 Void——两种"把钱还回去"
资金已经动了和没动,处理方式完全不同,Prism 为此设计了不同方法:
| 操作 | 场景 | 方法 |
|---|---|---|
| Void 撤销 | 发货前取消订单,释放冻结资金 | void() |
| Refund 退款 | 已捕获后退货(支持部分退款) | refund() |
| Reverse 冲正 | 没有原始订单号,凭交易 ID 直接冲正 | reverse() |
退款是一条独立的子状态机:它有自己的一套状态(如REFUND_SUCCESS、pending、失败),而不是复用支付状态。把三种事件(授权成功、捕获成功、退款成功)硬塞进同一个status字段,正是很多支付代码"看起来对、行为错"的根源。
退款与争议处理的 API 见 refund、void。
环节五:Webhook——异步真相的统一入口
Settlement、退款、争议……这些事件不会等你去轮询,而是乱序、可能重复地通过 Webhook 涌进来。EventClient.handleEvent()是所有异步事件的统一入口,它做两件关键的事:
- 验签:检查 webhook 来源(HMAC 等),验不过的事件直接当作伪造拒绝——没有"开发模式跳过验证"的后门;
- 归一化:把各处理器的原始事件映射成统一的
WebhookEventType枚举(如PAYMENT_INTENT_SUCCESS、PAYMENT_INTENT_CAPTURE_SUCCESS),你的业务代码只写一次判断逻辑。
同一客户端家族里,DisputeClient负责争议(chargeback)的accept/defend/submitEvidence,docs/getting-started/extend-to-more-flows.md 中有完整用法。
收尾:把支付当生命周期,你会少踩这些坑
| 习惯 | 原因 |
|---|---|
不要只按一个status分支 | 授权成功 ≠ 捕获成功 ≠ 退款成功,是不同的流 |
| 发货只认 Capture | 授权只是冻结,随时可能失败或过期 |
| 同步查询视为"暂定答案" | 未知默认 PENDING,让已验证的 Webhook 事件来定案 |
| 金额用带币种的整数 | minorAmount + currency,永远不要传浮点数 |
| 换处理器只换一行配置 | 请求结构不变,路由逻辑留在你自己的业务层 |
想完整跑一遍授权→捕获→退款,可以直接看 docs/getting-started/first-payment.md 或 demo/e-commerce/ 里 Stripe + Adyen 的示例工程;想按语言接入,参考 sdk/python/README.md 与 sdk/javascript/README.md。
【免费下载链接】hyperswitch-prism
One library | Many payment processors | Scale to multiple processors with few lines of code.
相关推荐
CANN/runtime:如何通过plog日志定位Device侧异常
如何通过plog日志定位Device侧异常 问题现象描述 现象1:算子执行失败但无法定位错误原因和位置 Runtime应用在Device侧执行任务时发生异常,H
CANNAscend人工智能性能剖析系统编程Livewire生命周期钩子:掌握组件生命周期的关键
Livewire生命周期钩子:掌握组件生命周期的关键 Livewire生命周期钩子是Laravel Livewire框架中至关重要的功能,它允许开发者在组件生命
后端前端BullMQ任务生命周期详解:从等待到完成的7个关键状态
BullMQ任务生命周期详解:从等待到完成的7个关键状态 BullMQ作为基于Redis的Node.js和Python消息队列系统,其任务处理的生命周期是理解和
后端消息队列任务调度
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考