首页 / 内容指南 / 当前文章

Stripe Checkout Session、PaymentIntent、SetupIntent和Charge有什么区别?

发布于 2026-08-26 · deliwaimao.cn 编辑部

Checkout Session管理一段完整结账会话,可包含商品、税费、折扣、配送、订阅和支付界面;PaymentIntent跟踪一次付款意图从创建、确认、认证到成功或失败的生命周期;SetupIntent用于保存并优化支付方式供未来使用,本身不产生扣款;Charge记录一次实际付款尝试及其金额、捕获、退款、争议和付款方式结果。

本文目录(19 节)

直接答案

Checkout Session管理一段完整结账会话,可包含商品、税费、折扣、配送、订阅和支付界面;PaymentIntent跟踪一次付款意图从创建、确认、认证到成功或失败的生命周期;SetupIntent用于保存并优化支付方式供未来使用,本身不产生扣款;Charge记录一次实际付款尝试及其金额、捕获、退款、争议和付款方式结果。

这些对象不是四种互斥的收款方式。一次Checkout Session在 payment 模式下通常会关联PaymentIntent,PaymentIntent在尝试收款时可能关联一个或多个Charge;仅保存支付方式的流程则使用SetupIntent。排障应先确定当前流程创建了哪个顶层对象,再沿关联ID追踪,而不是把所有 cs_pi_seti_ch_ 当成同类订单号。

一、对象职责对比

↔ 表格可左右滑动查看完整内容
对象常见ID前缀主要职责是否代表实际扣款
Checkout Sessioncs_管理结账页面与完整会话不直接等同于扣款
PaymentIntentpi_管理一次付款的状态机目标是完成一次成功付款
SetupIntentseti_保存并优化未来使用的支付方式
Chargech_记录具体付款尝试及资金结果是一次付款尝试记录

自己的订单ID仍应保存在业务数据库中,并通过受控的metadata或本地映射与Stripe对象关联。不要用客户邮箱或银行卡信息充当关联键。

二、Checkout Session是什么

Checkout Sessions API用于构建完整结账流程。Stripe官方说明,它可以管理托管页面、嵌入式表单或自定义Elements界面,并覆盖行项目、税费、折扣、配送、订阅和结账状态。Stripe将其作为多数集成的推荐起点,因为需要自行维护的结账逻辑更少。

Session有自身状态和过期规则。用户打开结账页不代表支付已成功;返回成功页面也不是服务器履约的充分证据。应用应根据Webhook和关联付款对象确认最终状态。

三、PaymentIntent是什么

PaymentIntent表示收取一笔付款的意图,并在生命周期中经历多个状态。它保存金额、币种、支付方式配置及认证要求,能够处理3D Secure等额外客户动作。Stripe建议通常为每个订单或客户会话创建一个PaymentIntent。

PaymentIntent不是“创建后立刻扣款”的静态记录。它可能处于 requires_payment_methodrequires_confirmationrequires_actionprocessingrequires_capturesucceeded 或取消状态。业务逻辑必须按实际状态处理,不能只判断对象是否存在。

四、SetupIntent是什么

SetupIntent用于设置和保存支付方式,以便未来付款。Stripe官方明确说明,它类似付款设置流程,但不会创建Charge。银行或支付网络可能仍要求客户认证,以提高以后离线或在线使用该支付方式的成功率。

租赁押后扣款、订阅前保存卡、会员后续续费等场景可能使用SetupIntent。若当前就要收款,则通常应使用PaymentIntent,并按需要设置未来用途,而不是误把SetupIntent成功当作到账。

五、Charge是什么

Charge是具体付款尝试的记录,包含拟收金额、已捕获金额、已退款金额、支付方式详情、失败信息、收据、争议状态和余额交易等。使用现代PaymentIntents流程时,Charge通常由PaymentIntent在付款尝试过程中创建。

一个PaymentIntent可能因为重试而关联多个Charge,但最终最多形成一个成功付款结果。看到多个 ch_ 不应立即判定客户被重复扣款,应逐项检查状态、捕获金额、退款和关联的PaymentIntent。

六、四个对象如何关联

典型一次性Checkout流程可以表示为:

本地订单
  └─ Checkout Session (cs_)
       └─ PaymentIntent (pi_)
            ├─ Charge attempt 1 (ch_, failed)
            └─ Charge attempt 2 (ch_, succeeded)

仅保存支付方式的流程可能是:

客户账户
  └─ SetupIntent (seti_)
       └─ PaymentMethod,供以后付款使用

订阅流程还可能关联Customer、Subscription、Invoice等对象,不能用上述简图替代具体集成文档。

七、Checkout Session和PaymentIntent怎么选

Stripe官方对比指出,Checkout Sessions适合希望用较少代码管理完整结账功能的多数集成;Payment Intents是更底层的API,适合需要完全自行控制结账状态、税费、折扣、订阅和货币转换逻辑的团队。

选择PaymentIntent意味着不仅自定义界面,还要承担更多状态管理、错误恢复和长期维护。若只是因为“自定义程度高”就绕过Checkout Session,应先列出确实无法由Session满足的需求。

八、PaymentIntent和Charge为什么不能混用

PaymentIntent是跨多次尝试的付款状态机,Charge是单次尝试的结果记录。订单履约通常关注PaymentIntent最终是否成功;分析拒付原因、收据、捕获或退款时,则常需要查看具体Charge。

只保存最后一个Charge ID会丢失PaymentIntent层的认证和重试上下文。只保存PaymentIntent ID又可能不足以解释某次失败尝试。合理做法是保存本地订单到PaymentIntent的主映射,并按需读取关联Charge。

九、SetupIntent和PaymentIntent有什么区别

SetupIntent的目标是准备支付凭据供未来使用,不产生付款;PaymentIntent的目标是收取指定金额。两者都可能触发客户认证,因此“用户完成3DS”也不能单独说明发生了扣款。

若支付方式需要以后离线扣款,应正确声明使用场景并取得客户授权。具体合规要求取决于地区、支付方式和业务模式,不能仅靠一个API参数代替授权流程。

十、前端成功页为什么不能作为到账依据

客户可能在跳转完成前关闭页面,攻击者也可以直接访问成功URL,异步支付方式还可能在页面返回后继续处理。服务器应监听并验证Stripe Webhook,根据适用于集成的最终事件与对象状态执行履约。

Webhook处理要验签、幂等并允许重复投递。把Session ID或PaymentIntent ID与本地订单关联,确保同一成功事件不会重复发货、充值或发送许可证。

十一、常见状态如何解释

  • Session显示 open:结账会话仍可继续,不代表付款成功。
  • PaymentIntent显示 requires_action:客户还需完成认证或其他动作。
  • PaymentIntent显示 processing:付款仍在异步处理中。
  • PaymentIntent显示 requires_capture:授权可能成功,但尚未完成捕获。
  • PaymentIntent显示 succeeded:付款意图成功,仍需核对订单关联和金额。
  • SetupIntent显示成功:支付方式设置完成,不代表收款。
  • Charge显示失败:该次尝试失败,不排除同一PaymentIntent后来成功。

状态枚举可能随对象和支付方式不同,应以当前API版本的官方说明为准。

十二、如何防止重复对象和重复付款

为同一本地购物车保存并复用既有PaymentIntent,而不是每次刷新都创建新对象。Stripe官方建议创建请求使用幂等键,且通常一个订单或客户会话对应一个PaymentIntent。

Checkout Session也应与本地订单建立唯一映射。接收Webhook时以事件ID去重,同时让“订单由未支付变为已支付”的数据库更新具有条件约束。幂等键、事件去重和订单状态约束解决的是不同层的问题,不能只实现一个。

十三、对账时看哪个对象

从本地订单开始,找到Session或PaymentIntent,再查看成功Charge与其balance transaction。金额、币种、捕获、退款和争议应在正确对象层核对。不要只凭Dashboard中的显示名称猜测关联关系。

若同一订单出现多个对象,记录创建时间、livemode、客户、metadata和关联ID。先排除测试与生产模式混用,再判断是客户重试、应用重复创建,还是确有多次独立订单。

十四、最小排障流程

  1. 记录本地订单ID及预期金额、币种,遮盖客户敏感数据。
  2. 判断入口是Checkout Session、自建PaymentIntent还是SetupIntent。
  3. 核对对象是否属于正确Stripe账户和live/test模式。
  4. 沿关联字段找到PaymentIntent与Charge。
  5. 读取状态、最近错误和下一步动作,而非只看HTTP 200。
  6. 核对Webhook验签、事件去重和订单状态更新日志。
  7. 对异步支付等待最终事件,不用浏览器返回页提前履约。
  8. 在测试模式重放最小场景,确认失败、认证和成功路径均可恢复。

不要把Secret Key、PaymentIntent client secret、完整Webhook内容或客户支付资料写入普通日志。

十五、常见误区

  • 把Checkout Session当作付款成功证明。
  • SetupIntent成功后直接标记订单已付款。
  • 看到多个Charge就断定重复扣款。
  • 为每次页面刷新创建新PaymentIntent。
  • 只依赖前端成功回调发货。
  • 用测试模式对象ID查询生产账户。
  • 在metadata中存储银行卡或其他敏感数据。
  • 忽略异步付款的 processing 阶段。

十六、FAQ

一个Checkout Session一定有PaymentIntent吗?

不一定。关联对象取决于Session模式和流程,例如订阅或仅设置支付方式会有不同关系。应查看该Session的实际字段与官方模式说明。

一个PaymentIntent为什么会有多个Charge?

付款重试可能生成多个Charge尝试,其中部分失败。应核对每个Charge状态与最终成功结果,而不是按数量判断扣款次数。

SetupIntent会做小额扣款验证吗?

SetupIntent本身目标不是收款,但具体支付方式的验证过程可能由银行或网络显示临时验证行为。应依据支付方式文档和最终对象状态解释。

PaymentIntent成功后还要处理Webhook吗?

要。服务器端Webhook可覆盖客户未返回页面、异步状态变化和重试场景,是可靠履约的重要依据。

Charge和订单是一一对应吗?

不一定。Charge对应付款尝试,本地订单可能经历多个尝试;业务系统应通过PaymentIntent、Session和自己的订单映射建立关系。

十七、结论

Checkout Session管理完整结账体验,PaymentIntent管理一次付款生命周期,SetupIntent准备未来使用的支付方式,Charge记录具体付款尝试。把它们按层关联,并以Webhook、幂等和本地订单状态共同控制履约,才能正确处理认证、异步付款、重试与对账。

核验来源