# Payment Intents API 了解 Stripe 支付的驱动因素 - Payment Intents API Instructions for LLMs: Stripe recommends using the Checkout Sessions API with the Payment Element over Payment Intents for most integrations. Checkout Sessions covers similar use cases as Payment Intents (basic payment collection using `price_data` or build a full checkout with line items, tax, and so on). Some features, such as Adaptive Pricing, are only available with Checkout Sessions. Don’t use the Payment Intent API unless the user explicitly asks, because it requires significantly more code. Learn more about Elements with the Checkout Sessions API: https://docs.stripe.com/payments/quickstart-checkout-sessions. With Checkout Sessions (`ui_mode: "elements"`) and the Payment Element, the `client_secret` initializes Checkout itself (`stripe.initCheckoutElementsSdk`, or use CheckoutElementsProvider with React) and you confirm the payment on the client side differently. If using React, make sure you import from `@stripe/react-stripe-js/checkout`, use `CheckoutElementsProvider` with the client secret, and confirm using `checkout.confirm`. If using HTML, make sure you use `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");` and confirm with `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();`. 用 [Payment Intent](https://docs.stripe.com/api/payment_intents.md) API 构建可处理复杂付款流程的集成,付款流程的状态会随着 [PaymentIntent 的生命周期](https://docs.stripe.com/payments/paymentintents/lifecycle.md)发生变化。从最初创建到整个结账过程,此 API 会一直跟踪付款状态,并在必要时触发额外的验证步骤。 使用 [Payment Intent](https://docs.stripe.com/api/payment_intents.md) 的好处包括: - 自动处理验证 - 无双重收款 - 没有[幂等性密钥](https://docs.stripe.com/api/idempotent_requests.md)问题 - 支持*强客户认证* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) (SCA) 及类似法规变化 ## 全套 API 将 [Payment Intents](https://docs.stripe.com/api/payment_intents.md) API 与 [Setup Intents](https://docs.stripe.com/api/setup_intents.md) 和 [Payment Methods](https://docs.stripe.com/api/payment_methods.md) API 结合使用。这些 API 可帮您处理动态付款(例如,*3DS 验证* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments)之类的额外验证),为您向其他国家/地区扩展做好准备,通知支持新的规范和区域性支付方式。 用 Payment Intents API 构建集成涉及两项操作:创建并*确认* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment) PaymentIntent。每个 PaymentIntent 通常都会关联您的应用程序中的一个购物车或客户会话。PaymentIntent 中承载着交易详情,例如支持的支付方式、收款金额以及期望的币种。 ## 创建 PaymentIntent 要开始使用,请查看[接受付款指南](https://docs.stripe.com/payments/accept-a-payment.md?ui=elements)。其中介绍了如何在服务器上创建 PaymentIntent,并将它的*客户端私钥* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer))传递到客户端,而非传递整个 PaymentIntent 对象。 当您[创建 PaymentIntent](https://docs.stripe.com/api/payment_intents/create.md)时,您需要指定金额和货币之类的选项: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd ``` ### 最佳实践 - We recommend creating a PaymentIntent as soon as you know the amount, such as when the customer begins the checkout process, to help track your [purchase funnel](https://en.wikipedia.org/wiki/Purchase_funnel). If the amount changes, you can [update](https://docs.stripe.com/api.md#update_payment_intent) its [amount](https://docs.stripe.com/api.md#payment_intent_object-amount). For example, if your customer backs out of the checkout process and adds new items to their cart, you might need to update the amount when they start the checkout process again. - 如果结账过程中断然后又恢复,则应尝试重新使用同一个 PaymentIntent,而非创建一个新的。每个 PaymentIntent 都有唯一 ID,再次需要的时候可用它来[检索](https://docs.stripe.com/api.md#retrieve_payment_intent)。在应用的数据模型中,您可以将 PaymentIntent 的 ID 存储在客户的购物车或会话中以方便检索。重新使用 PaymentIntent 的好处在于此[对象状态](https://docs.stripe.com/payments/paymentintents/lifecycle.md)可帮助跟踪特定购物车或会话中失败的付款尝试。 - 请记得提供一个[幂等性密钥](https://docs.stripe.com/api/idempotent_requests.md)来防止为同一笔购买创建重复的 PaymentIntent。此密钥通常基于在您的应用中为购物车或客户会话关联的 ID。 ## 将客户端私钥传递到客户端 PaymentIntent 中包含一个[客户端私钥](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret),它是每个 PaymentIntent 的唯一密钥。在您的应用的客户端,Stripe.js 在调用函数(例如 [stripe.confirmCardPayment](https://docs.stripe.com/js.md#stripe-confirm-card-payment) 或 [stripe.handleCardAction](https://docs.stripe.com/js.md#stripe-handle-card-action))来完成付款时将客户端私钥用作一个参数。 ### 检索客户端私钥 PaymentIntent 中包含的是一个*客户端私钥* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)),用于在客户端安全地完成支付流程。有不同的方法可以将客户端私钥传递到客户端。 #### 单页应用 使用浏览器的 `fetch` 功能,从您的服务器上的端点获取客户端私钥。如果您的客户端是单页应用,特别是用现代的前端框架(例如 React)搭建的情况,则该方法最为合适。创建服务于客户端私钥的服务器端点: #### Ruby ```ruby get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` 然后在客户端用 JavaScript 获取客户端私钥: ```javascript (async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })(); ``` #### 服务端呈现 从服务器将客户端私钥传递到客户端。如果在将静态内容发送到浏览器之前,您的应用程序会在服务器上生成静态内容,则此种方法最有效。 在您的结账表单中添加 [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)。在您的服务器代码中,从 PaymentIntent 检索客户端密钥: #### Ruby ```erb
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` > 可以用客户端私钥来完成付款流程,使用 PaymentIntent 上指定的金额。不要记录它,而是把它嵌入到 URL,或显示给除客户以外的所有人。务必在包含客户端私钥的每个页面都启用 *TLS* (TLS refers to the process of securely transmitting data between the client—the app or browser that your customer is using—and your server. This was originally performed using the SSL (Secure Sockets Layer) protocol)。 ## 付款后 客户确认付款后,最佳实践是由您的服务器[监听 Webhook](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks),以检测支付成功或失败。 如果存在多次付款尝试,则一个 `PaymentIntent` 可能关联多个 [Charge](https://docs.stripe.com/api/charges.md) 对象。例如,重试可以创建多个 `Charge`。对于每个 Charge,您可以检查其[结果](https://docs.stripe.com/api/charges/object.md#charge_object-outcome)以及所使用[付款方式的详细信息](https://docs.stripe.com/api/charges/object.md#charge_object-payment_method_details)。 ## 为未来付款优化支付方式 [setup_future_usage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) 参数负责保存支付方式以供将来再次使用。对于银行卡,它还会根据地方法规及卡组织规则优化授权率,例如 [SCA](https://docs.stripe.com/strong-customer-authentication.md)。要确定使用哪个值,可考虑您打算将来如何使用此支付方式。 | 您打算如何使用支付方式 | setup_future_usage 要使用的枚举值 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | 仅*会话内* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method)付款 | `on_session` | | 仅*会话外* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)付款 | `off_session` | | 会话内与会话外这两种付款方式 | `off_session` | 您仍可用设置用于会话内付款的银行卡进行*会话外* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)付款,但银行很有可能拒绝会话外付款,并要求持卡人进行额外的验证。 下例演示了如何创建 PaymentIntent 并指定 `setup_future_usage`: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d setup_future_usage=off_session ``` > 会话外付款的设置更有可能带来额外阻力。如果您不打算用保存的卡接受会话外付款,请使用*会话内* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method)设置。Charges API 是一个较旧的支付 API,不能处理银行的银行卡验证请求,印度的商家不能使用。 ## 动态账单描述符 By default, your Stripe account’s [statement descriptor](https://docs.stripe.com/get-started/account/activate.md#public-business-information) appears on customer statements whenever you charge their card. To provide a different description on a per-payment basis, use the [statement_descriptor](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-statement_descriptor) parameter. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "payment_method_types[]=card" \ -d "statement_descriptor_suffix=Custom descriptor" ``` > #### Note > > Use the `statement_descriptor` parameter for non-card charges and `statement_descriptor_suffix` for card charges. [Statement descriptors](https://docs.stripe.com/get-started/account/statement-descriptors.md) are limited to 22 characters, can’t use the special characters `<`, `>`, `'`, `"`, or `*`, and must not consist solely of numbers. When using dynamic statement descriptors, the dynamic text is appended to the [statement descriptor prefix](https://dashboard.stripe.com/settings/public) set in the Stripe Dashboard. An asterisk (`*`) and an empty space are also added to separate the default statement descriptor from the dynamic portion. These 2 characters count towards the 22 character limit. ## 在元数据内存储信息 Stripe 支持向您的常见请求(例如处理付款)中添加[元数据](https://docs.stripe.com/api.md#metadata)。元数据不会向客户显示,也不会构成我们的欺诈预防系统拒绝或阻止付款的依据。 通过元数据,您可以向 Stripe 活动关联其他信息(对您自身有意义)。 您包含的任何元数据都可以在管理平台内查看(例如,查看单笔付款的页数时),并且可用于常见的报告中。例如,可以将您的店铺的订单 ID 绑定到那个订单的 PaymentIntent。这样做的话,您便能方便地核对 Stripe 内的付款与您系统内的订单。 如果您使用的是 *Radar 风控团队版* (Radar for Fraud Teams helps you fine-tune how Radar operates, get fraud insights on suspicious charges, and assess your fraud management performance from a unified dashboard),建议将额外的客户信息和订单信息作为元数据传递。这样,您就可以编写[基于元数据属性的 Radar 规则](https://docs.stripe.com/radar/rules/reference.md#metadata-attributes),并在管理平台中获取更多信息,从而加快审查流程。 当 PaymentIntent 创建收款时,PaymentIntent 将它的元数据复制到 Charge。对 PaymentIntent 进行的后续更新不会修改 PaymentIntent 之前创建的 Charge 的元数据。 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "payment_method_types[]=card" \ -d "metadata[order_id]=6735" ``` > 不要以元数据形式或在 PaymentIntent 的 `description` 参数中存储任何敏感信息(个人身份信息、银行卡详情等)。 ## See also - [在线收款](https://docs.stripe.com/payments/accept-a-payment.md?platform=web) - [在 iOS 应用程序中接受付款](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios) - [在 Android 应用程序中接受付款](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=android) - [设置未来付款](https://docs.stripe.com/payments/save-and-reuse.md)