Sources 用法最佳实践已废弃
警告
我们已放弃使用 Sources API,并计划停止支持本地支付方式。如果您当前是使用 Sources API 处理任何本地支付方法,则必须将其迁移到 Payment Methods API。我们将发送电子邮件,详细告知何时停止这种支持。
虽然我们不打算取消支持银行卡支付,但我们建议用 PaymentMethods API 替换掉 Sources API,通过这个 API 可以访问我们的最新功能和支付方式类型。
Sources API 的灵活性可以让您在添加支持的额外支付方式时,将需要进行的更改降到最低。
银行卡付款的典型流程
在典型的银行卡付款的结账流程中(排除要求 3DS 验证的),您的集成需要收集银行卡信息,创建来源,然后用它创建收款请求。由于不需要客户额外操作,而且银行卡付款可以同步确认,因此支付成功时我们可以立即确认,资金定可到账——因而也没有必要使用 webhooks。
需要使用 Webhooks
其他支付方式可能要求您的客户采取额外操作(例如,重定向),然后某个来源才能变为 chargeable
,进而再用于创建收款请求(例如,iDEAL)这种状态转变通常是异步的,甚至会发生在客户离开您的网站以后。基于这些原因,您的集成就必须依靠 Webhooks 来确定某个来源何时变为可扣款状态,然后才能创建收款。
Stripe 给您发送以下 Webhooks 事件,通知您来源的状态变化:
事件 | 描述 | 建议操作 |
---|---|---|
source.chargeable | 在客户授权并验证付款后,Source 变为 chargeable 。 | 创建 Charge。 |
source.failed | 由于客户拒绝验证付款,Source 对象未能变为可扣款状态。 | 取消订单,然后(可以选择)重新让客户进入您的付款流程。 |
source.canceled | Source 对象超时,不能用它创建收款。 | 取消订单,然后(可以选择)重新让客户进入您的付款流程。 |
与之类似,创建收款时,某些异步的支付方式可能需要数天才能确认资金并成功收款,这就需要靠 Webhook 来知道何时确认,并最终履行订单。
Stripe 给您发送以下 Webhooks 事件,通知您收款的状态变化:
事件 | 描述 | 建议操作 |
---|---|---|
charge.pending | Charge 待处理(仅异步支付方式)。 | 不需要操作。 |
charge.succeeded | Charge 成功,付款完成。 | 确认订单,通过邮件给客户发送通知。 |
charge.failed | Charge 失败,无法完成付款。 | 取消订单,然后(可以选择)重新让客户进入您的付款流程。 |
构建灵活的集成
为确保您的结账流程的灵活性,能够随时支持多种支付方式,建议采取以下方法:
创建 Source
创建 Sources 时,在您的内部订单表示上记录下来源的 ID,这样即可在收到并处理 source.chargeable
webhooks 时检索订单。为有效查询,一定要根据这个 source
属性建立订单对象索引。
创建 Charge
提交 source.chargeable
webhook 即对 Source 扣款。收到 Webhook 后,通过查询收到的来源 ID 检索您的内部订单表示,然后确认该订单正在等待付款。
创建收款请求时,将您的内部订单 ID 作为幂等性密钥,避免任何可能的竞争条件。此外,如果支付来源可重复使用,而且您想要重复使用,那一定要先将它绑定到 Customer,然后再扣款。参考一次性使用或重复使用及 Source 和 Customer 指南,更多地了解一次性使用和可重复使用的 Sources 的处理方式,以及它们与 Customers 的交互方式。
与创建 Souce 类似,在您的内部订单表示上记录下收款的 ID,这样即可在收到并处理 charge.succeeded
webhooks 时检索订单。
确认页面
在客户采取了授权付款所需的操作后(例如,重定向),您应该呈现一个确认页面,为期显示订单的状态。该操作可通过内部轮询订单来实现。
由于不能保证 Webhook 的提交时延,因此如果您想进一步简化您的确认页面,可以在您的客户端代码中轮询相关的 Source 的状态。一旦检测到您的 Source 变为 chargeable
状态,即可开始用这个 Source 创建 Charge,不必等到 source.chargeable
webhook 到达。
注意,某些类型的 Sources 需要几分钟(甚至几天)才能变成 chargeable
状态。如决定轮询 Source,那么建议在某一时点作超时处理,然后告诉客户他们的订单正在等待付款,然后异步向其发送支付确认邮件。下表为我们针对各个 Source 状态建议给客户发送的消息。
如果客户离开您的页面,则客户端轮询停止。这意味着,您还必须集成 source.chargeable
webhook,确保不会失去对客户订单的跟踪。
如果您使用着 Stripe.js,则可以用 stripe.retrieveSource() 来实施您自己的轮询:
// In order-confirmation-page.js const stripe = Stripe(
); // After some amount of time, we should stop trying to resolve the order synchronously: const MAX_POLL_COUNT = 10; let pollCount = 0; const pollForSourceStatus = async () => { const {source} = await stripe.retrieveSource({id: SOURCE_ID, client_secret: CLIENT_SECRET}) if (source.status === 'chargeable') { // Make a request to your server to charge the Source. // Depending on the Charge status, show your customer the relevant message. } else if (source.status === 'pending' && pollCount < MAX_POLL_COUNT) { // Try again in a second, if the Source is still `pending`: pollCount += 1; setTimeout(pollForSourceStatus, 1000); } else { // Depending on the Source status, show your customer the relevant message. } }; pollForSourceStatus();'pk_test_TYooMQauvdEDq54NiTphI7jx'
下表为推荐的您可能会用到的用户消息,可根据 Source 的状态来显示。
状态 | 向客户显示的消息 |
---|---|
Source 为 chargeable | 已收到订单,正等待确认付款。 |
Source 已 canceled | 付款失败,无法处理订单。 |
Source 已 failed | 付款失败,无法处理订单。 |
轮询一段时间后 Source 仍为 pending 状态 | 已收到订单,正等待确认付款。 |
创建完 Charge 后(并且如果用户仍在您的确认页面的话),可根据 Charge 的状态向其显示以下消息:
状态 | 向客户显示的消息 |
---|---|
Charge 正 pending | 已收到订单,正等待确认付款。 |
Charge 已 failed | 付款失败,无法处理订单。 |
Charge 已 succeeded | 付款已确认,订单已完成。 |
订单确认
仅在收到 charge.succeeded
webhook 后再确认您的订单(可能会即时发生,也可能不会)。在这个阶段就要向客户发送邮件,因为对于异步付款,有时候好几天才能确认。
取消与故障
侦听 source.canceled
和 source.failed
webhooks,并且一定要取消相关来源所关联的订单。如果遵从了上面的最佳实践,那么您应该永远不会收到关于之前 chargeable
来源的 source.canceled
webhook(因为您的 source.chargeable
处理程序应该立即创建了收款,防止了来源被取消)。对于从未变成 chargeable
及一直为 pending
的 Source,您仍会收到 source.canceled
webhooks,这通常说明您的客户过早地离开了您的结账流程。在 Customer 拒绝付款或付款方案层面发生技术故障时,您也可能收到 source.failed
webhook。
您还应该侦听 charge.failed
webhooks,确保取消与收到的 Charge 关联的订单。
对于这些当中的每个事件,都建议通知客户他们的订单失败了,然后邀请他们重新进入您的付款流程(酌情考虑)。