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

Stripe PaymentIntent卡在requires_action或processing:状态排查指南

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

先在 Stripe Dashboard 和服务端 API 读取目标 PaymentIntent,保存 ID、livemode、amount、currency、customer、payment method、status、last_payment_errornext_action、latest charge 和创建/更新时间。若为 requires_action,确认客户端使用与该 PaymentIntent 匹配的 client secret 完成官方确认流程;若为 requires_payment_method,展示安全错误并收集新的付款方式;若为 processing,不要重复创建付款,等待最终 Webhook 并设置业务超时与对账。最终只在服务端确认 succeeded(或业务支持的可交付状态)后履约。

本文目录(19 节)

直接答案

先在 Stripe Dashboard 和服务端 API 读取目标 PaymentIntent,保存 ID、livemode、amount、currency、customer、payment method、status、last_payment_errornext_action、latest charge 和创建/更新时间。若为 requires_action,确认客户端使用与该 PaymentIntent 匹配的 client secret 完成官方确认流程;若为 requires_payment_method,展示安全错误并收集新的付款方式;若为 processing,不要重复创建付款,等待最终 Webhook 并设置业务超时与对账。最终只在服务端确认 succeeded(或业务支持的可交付状态)后履约。

一、先确认环境和对象没有看错

测试模式与正式模式对象相互独立。记录 PaymentIntent ID、livemode、Stripe account、Connect 子账户上下文和 API Key 所属环境。Dashboard 搜不到对象或状态与应用不同,常见原因是看错模式、平台与 connected account 混用,或应用日志记录了另一次尝试的 ID。

同一订单可能因前端重复点击创建多个 PaymentIntent。先按内部 order ID 列出所有关联对象,标出哪个是当前权威尝试、哪个已取消或失败。不要只挑状态最接近成功的一条。

二、理解关键状态的实际含义

requires_payment_method 表示 PaymentIntent 需要可用付款方式,可能是首次尚未绑定,也可能是确认失败后回到该状态。requires_confirmation 表示已经具备付款方式但仍需确认。requires_action 表示还要完成客户操作。processing 表示 Stripe 或支付网络仍在处理,最终可能成功或失败。

succeeded 才表示 PaymentIntent 已成功完成;若采用手动 capture,还可能出现 requires_capture,此时授权成功但尚未捕获。订单状态机必须覆盖实际集成采用的 capture 和 payment method 类型,不能把所有非 succeeded 都粗暴标为失败。

三、检查last_payment_error而不是猜原因

当对象回到 requires_payment_method,读取 last_payment_error 的 type、code、decline_code、message 和关联 payment method。面向用户只显示可操作且安全的提示,例如更换付款方式或联系发卡行;内部日志保留错误码和 PaymentIntent ID,不记录完整卡号或 client secret。

卡被拒绝、认证失败、参数错误和网络问题处理不同。不要对确定性拒绝无限自动确认同一付款方式,这既不能提高成功率,还可能造成不良体验或风险信号。

四、requires_action时检查next_action

requires_actionnext_action 描述客户端需要采取的步骤,例如执行 3D Secure 流程或跳转。前端必须使用 Stripe 官方 SDK 与该 PaymentIntent 的 client secret 完成对应确认,不能只显示自制“验证中”页面。

核对 client secret 是否来自当前 PaymentIntent、是否被旧页面或缓存复用、前后端模式是否一致,以及页面是否因 CSP、弹窗限制、第三方 Cookie 或路由卸载中断认证。client secret 可以交给对应客户完成付款,但不能写入日志、分析平台或 URL。

五、不要在requires_action状态反复创建对象

客户关闭认证窗口或网络短暂断开时,原 PaymentIntent 可能仍可继续。前端若每次点击都创建新对象,会产生多个未完成尝试,后续 Webhook 难以关联,客户也可能重复授权。订单创建流程使用稳定业务幂等键,让一次明确操作只得到一个 PaymentIntent。

重试前先从服务端读取原对象当前状态。仍可继续时恢复确认;已经 succeeded 时直接恢复订单;不可继续时才按受控规则更换付款方式或创建新尝试,并在数据库关联前后对象。

六、processing不等于失败

部分支付方式是异步的,确认后进入 processing,最终结果稍后通过 Webhook 到达。此时页面应显示“处理中”,不应让客户不断重付,也不能提前发货高风险商品。业务超时要根据实际支付方式设计,而不是统一等待几十秒后判失败。

若 processing 超过预期,查看 PaymentIntent、相关 Charge、payment method 与 Dashboard 事件,并核对 Webhook 是否正常。不要直接 cancel 一个可能接近结算的支付;先依据 Stripe 对该支付方式的支持行为与业务风险处理。

七、以Webhook推动最终订单状态

客户可能在认证成功后关闭浏览器,返回 URL 也可能被网络或广告拦截。因此最终状态应由服务端 Webhook 驱动,并对事件验签、持久化和幂等处理。常见事件包括支付成功、失败或处理状态变化,具体监听集合按集成文档配置。

Webhook 可能重试或乱序。以事件 ID 去重,以 PaymentIntent ID 关联订单,并在消费者中回查对象当前状态。不要仅按事件抵达顺序覆盖订单,也不要因重复事件再次发货或发送多封通知。

八、回跳页面只负责展示和恢复

return URL 页面应从自己的后端查询订单与 PaymentIntent,而不是相信查询参数写着 success。页面可以短暂轮询后端,显示“需要操作”“处理中”“成功”或“失败”;若仍 requires_action,提供安全继续入口。

不要在浏览器直接决定已付款并修改数据库。攻击者可以伪造 URL,合法客户也可能在支付最终失败前回到页面。服务端验证才是履约边界。

九、检查确认调用是否真正成功发出

在浏览器 Network 和服务端日志中关联创建、确认和状态查询。确认调用若被 CORS、CSP、JavaScript 异常或页面导航中断,PaymentIntent 会停在原状态。保存 Stripe SDK 返回的 error type/code 与 PaymentIntent 状态,但对敏感字段脱敏。

禁用按钮只能改善体验,不能替代后端幂等。双击、刷新、移动网络重试和多标签页都可能绕过单页面状态,必须由数据库唯一约束和 Stripe 幂等键保证一致性。

十、核对payment_method与customer归属

复用 PaymentMethod 时,检查它是否附加到正确 Customer,是否允许当前使用场景和币种,以及 off-session/未来使用设置是否与用户授权一致。把另一个客户的付款方式 ID 传入会导致错误,也属于严重数据隔离问题。

服务端不要接受前端任意 customer ID 并直接绑定。根据登录用户从数据库解析 Stripe Customer,并校验订单、PaymentIntent 和 Customer 归属一致。

十一、手动capture场景单独处理

capture_method=manual,授权完成后可能进入 requires_capture,这不是“卡住”。订单应记录授权金额、可捕获状态和授权期限,在履约节点执行一次幂等 capture。捕获失败或过期要进入异常流程。

不要把 requires_capture 当 succeeded,也不要让普通重试任务重复 capture。部分捕获、多次捕获支持与支付方式有关,应严格按当前 Stripe 文档和业务配置实现。

十二、建立订单与PaymentIntent状态机

本地订单状态不要简单复制 Stripe status,而应明确映射:待付款、待客户操作、处理中、已授权待捕获、已支付、失败、取消和需人工核对。每次转换保存来源事件、对象 ID、旧新状态、时间和执行结果。

只允许合法单向转换,旧事件不能把已支付订单退回处理中。退款与争议属于付款后的独立状态,不应复用“支付失败”覆盖原始收款事实。

十三、处理超时和未知结果

客户端确认或服务端 API 调用超时后,先查询原 PaymentIntent,而不是立即创建新对象。超时意味着响应未知,不等于确认未执行。使用稳定业务 operation ID 和请求账本记录每次尝试,避免同一订单产生不可控并发。

若查询暂时也失败,将订单标记“待核对”,通过后台对账恢复。不要向客户显示明确失败并鼓励重付,除非已从权威状态确认原支付未成功或不可继续。

十四、对账补偿不可缺少

定期按时间窗口查询 Stripe 中已更新的 PaymentIntent/Charge,与本地订单比对。发现 Stripe succeeded 而本地未支付时,走同一幂等消费者补偿;本地标支付但 Stripe 无成功证据时暂停履约并告警。

扫描窗口应重叠并按对象 ID 去重,以覆盖延迟和分页边界。对账不是绕过 Webhook 的第二套业务逻辑,而是复用同一状态机和副作用幂等层。

十五、上线验收清单

使用测试环境覆盖成功付款、3D Secure 成功/失败/取消、卡拒绝、异步 processing、Webhook 延迟与重复、页面关闭和网络超时。确认一个订单只关联受控尝试,重复事件不重复履约,return URL 不能伪造成功。

再覆盖手动 capture(若使用)、Connect 账户、测试/正式模式隔离和移动端回跳。上线监控各状态停留时长、requires_action 转化率、processing 超时、重复 PaymentIntent、Webhook 延迟、对账差异和人工核对量。

常见问题 FAQ

requires_action是不是支付失败?

不是。它表示还需要客户完成 3D Secure 等操作。应根据 next_action 继续官方确认流程,并等待最终状态。

processing多久算异常?

取决于支付方式和业务预期。不要设置一个适用于所有方式的几十秒阈值;监控停留时长并结合官方支付方式行为处理。

客户回到success页面能否立即发货?

不能只凭回跳。服务端应确认 PaymentIntent 最终状态,并以 Webhook/对象查询驱动订单。

超时后可以创建新PaymentIntent吗?

先查询原对象。请求可能已经执行但响应丢失;无条件新建可能造成重复付款和多个并发尝试。

requires_capture和succeeded一样吗?

不一样。requires_capture 通常表示已授权但尚未捕获,需要按手动捕获流程完成后再进入已支付/可履约状态。

总结

PaymentIntent “卡住”必须按具体状态处理:requires_action 恢复客户操作,requires_payment_method 更换付款方式,processing 等待异步最终结果,requires_capture 进入人工/自动捕获流程。所有最终订单状态以服务端对象和 Webhook 为依据,并用幂等键、状态机和对账处理重复、乱序与未知结果,才能避免漏单和重复付款。

官方资料