# 迁移到 Payment Element Accept many payment methods with a single Element. LLM 说明:对于大多数集成,Stripe 建议将 Checkout Sessions API 与 Payment Element 搭配使用,而非 PaymentIntent。Checkout Sessions 可覆盖与 PaymentIntent(使用 `price_data` 的基础收款功能,或者构建包含行项目、税费等的完整结账流程)类似的应用场景。Adaptive Pricing 等部分功能仅在 Checkout Sessions 中可用。除非用户明确要求,否则不要使用 PaymentIntent API,因为它需要更多的代码。进一步了解 Elements 与 Checkout Sessions API 搭配使用的信息:https://docs.stripe.com/payments/quickstart-checkout-sessions.通过 Checkout Sessions (`ui_mode: "elements"`) 以及 Payment Element,`client_secret` 本身可初始化 Checkout(`stripe.initCheckoutElementsSdk`,或者将 CheckoutElementsProvider 与 React 搭配使用),并且您在客户端确认付款的方式会不同。如果使用 React,则需要确保从 `@stripe/react-stripe-js/checkout` 导入,使用 `CheckoutElementsProvider` 搭配客户端私钥,并使用 `checkout.confirm` 进行确认。如果使用 HTML,确保使用 `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");`,并通过 `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` 进行确认。 > #### Interested in subscriptions, tax, discounts, shipping, or currency conversion? > > Migrate to the [Payment Element with the Checkout Sessions API](https://docs.stripe.com/payments/payment-element/migration-ewcs.md), an integration that manages subscriptions, tax, discounts, shipping, and currency conversion for you. Previously, each payment method (cards, iDEAL, and so on) required a separate Element. By migrating to the Payment Element, you can accept many payment methods with a single Element. PaymentIntents and SetupIntents each have their own set of migration guidelines. See the appropriate guide for your integration path, including example code. If your integration still uses the Charges API with tokens, first [Migrate to the Payment Intents API](https://docs.stripe.com/payments/payment-intents/migration.md#web) before you use this guide. # PaymentIntent migration If your existing integration uses the [Payment Intents](https://docs.stripe.com/payments/payment-intents.md) API to create and track payments or save card details during a payment, follow the steps below to use the Payment Element. ## Enable payment methods > This integration path doesn’t support BLIK or pre-authorized debits that use the Automated Clearing Settlement System (ACSS). Also, if you create the deferred intent from the client-side, you can’t use `customer_balance` with dynamic payment methods because the PaymentIntent requires a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-configuration-customer) or [Customer](https://docs.stripe.com/api/customers/object.md) object, which the client-side flow doesn’t support. To use `customer_balance`, create the `PaymentIntent` server-side with an `Account` or `Customer` and return its `client_secret` to the client. 查看您的[支付方式设置](https://dashboard.stripe.com/settings/payment_methods),启用您想支持的支付方式。您至少需要启用一个支付方式才能创建 *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods)。 默认情况下,Stripe 支持信用卡和其他常见的支付方式,可以帮助您获得更多客户,但建议您开启与您的业务和客户相关的其他支付方式。查看[支付方式支持](https://docs.stripe.com/payments/payment-methods/payment-method-support.md),了解支持的产品和支付方式,并查看我们的[定价页面](https://stripe.com/pricing/local-payment-methods)了解费用。 ## Update Elements instance [客户端] Next, update your client-side code to pass `mode`, `currency`, and `amount` when you create the Elements instance. For use with a PaymentIntent, set the `mode` to `'payment'` and the `currency` and `amount` to what you’ll charge your customer. #### Javascript ### Before ```javascript const stripe = Stripe('<>'); const elements = stripe.elements(); ``` ### After ```javascript const stripe = Stripe('<>'); const options = { mode: 'payment', currency: 'usd', amount: 1099, }; const elements = stripe.elements(options); ``` #### React ### Before ```jsx const stripePromise = loadStripe('<>'); function App() { return ( ); }; ``` ### After ```jsx const stripePromise = loadStripe('<>'); const options = { mode: 'payment', currency: 'usd', amount: 1099, }; function App() { return ( ); }; ``` ## Optional: Save payment details during a payment If your existing integration also saves payment details during a payment, use the `setup_future_usage` option when creating the Elements group instead of passing it at the confirm payment stage with `stripe.confirmCardPayment`. The Payment Element will use this information to display additional input fields and show mandates as needed. > You can’t save some payment methods during payments. You can still enable these payment methods for other use cases, but customers won’t see them as an option when setting up future payments. See [Payment method integration options](https://docs.stripe.com/payments/payment-methods/integration-options.md) for more details about what’s supported. #### Javascript ```javascript const stripe = Stripe('<>'); const options = { mode: 'payment', currency: 'usd', amount: 1099,setup_future_usage: 'off_session', }; const elements = stripe.elements(options); ``` #### React ```jsx const stripePromise = loadStripe('<>'); const options = { mode: 'payment', currency: 'usd', amount: 1099,setup_future_usage: 'off_session', }; function App() { return ( ); }; ``` Pass `setup_future_usage` when creating your PaymentIntent. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "customer"="{{CUSTOMER_ID}}" \-d "setup_future_usage"= "off_session" \ -d "amount"=1099 \ -d "currency"="usd" \ ``` ## Optional: Additional Elements options [客户端] The [Elements object](https://docs.stripe.com/js/elements_object/create_without_intent) accepts additional options that influence payment collection. Based on the options provided, the Payment Element displays available payment methods from those you’ve enabled. Learn more about [payment method support](https://docs.stripe.com/payments/payment-methods/payment-method-support.md). Make sure the Elements options you provide (such as `captureMethod`, `setupFutureUsage`, and `paymentMethodOptions`) match the equivalent parameters you pass when creating and confirming the Intent. Mismatched parameters can result in unexpected behavior or errors. | 所有权 | 类型 | 描述 | 必填 | | ---------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | | `mode` | - `payment` - `setup` - `subscription` | 指示 Payment Element 是否和 *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods)、*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) 或 *Subscription* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) 一起使用。 | 是 | | `currency` | `string` | 向客户收款时使用的货币。 | 是 | | `amount` | `number` | The amount to charge the customer, shown in Apple Pay, Google Pay, or BNPL UIs. | 对于 `payment` 和 `subscription` 模式 | | `setupFutureUsage` | - `off_session` - `on_session` | Indicates that you intend to make future payments with the payment details collected by the Payment Element. | 否 | | `captureMethod` | - `automatic` - `automatic_async` - `manual` | 控制何时从客户的账户中获取资金。 | 否 | | `onBehalfOf` | `string` | Connect only. The Stripe account ID, which is the business of record. See [use cases](https://docs.stripe.com/connect/charges.md) to determine if this option is relevant for your integration. | 否 | | `paymentMethodTypes` | `string[]` | A list of payment method types to render. You can omit this attribute to manage your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). | 否 | | `paymentMethodConfiguration` | `string` | The [payment method configuration](https://docs.stripe.com/api/payment_method_configurations.md) to use when managing your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). If not specified, your default configuration is used. | 否 | | `paymentMethodCreation` | `manual` | Allows PaymentMethods to be created from the Elements instance using [stripe.createPaymentMethod](https://docs.stripe.com/js/payment_methods/create_payment_method_elements). | 否 | | `paymentMethodOptions` | `{us_bank_account: {verification_method: string}}` | Verification options for the `us_bank_account` payment method. Accepts the same verification methods as [Payment Intents](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-us_bank_account-verification_method). | 否 | | `paymentMethodOptions` | `{card: {installments: {enabled: boolean}}}` | Allows manually enabling the card installment plan selection UI if applicable when you aren’t managing your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). You must set `mode='payment'` *and* explicitly specify `paymentMethodTypes`. Otherwise an error is raised. Incompatible with `paymentMethodCreation='manual'`. | 否 | | `paymentMethodOptions` | `{[paymentMethod]: {setup_future_usage: string}}` | Allows you to specify `setup_future_usage` for only payment methods that support reuse. Only applicable when `mode` is `payment`. The value for each payment method must match the corresponding `payment_method_options[paymentMethod][setup_future_usage]` on the PaymentIntent during confirmation. See the [Stripe.js reference](https://docs.stripe.com/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodOptions) for supported payment methods and values. | 否 | ## Add the Payment Element [客户端] If you’re using [React Stripe.js](https://github.com/stripe/react-stripe-js), update to the latest package to use the Payment Element. You can now replace the Card Element and individual payment methods Elements with the Payment Element. The Payment Element automatically adjusts to collect input fields based on the payment method and country (for example, full billing address collection for SEPA Direct Debit) so you don’t have to maintain customized input fields anymore. The following example replaces `CardElement` with `PaymentElement`: #### JavaScript ```html
``` ```javascript const paymentElement = elements.create("payment"); paymentElement.mount("#payment-element"); ``` If your payment flow already always collects details like the customer’s name or email address, you can prevent the Payment Element from collecting this information by passing the [fields](https://docs.stripe.com/js/elements_object/create_payment_element#payment_element_create-options-fields) option when creating the Payment Element. If you disable the collection of a certain field, you must pass that same data back with [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment). ## Update your PaymentIntent creation call [服务器端] The Payment Element allows you to accept multiple payment methods. You can manage payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe handles the return of eligible payment methods based on factors such as the transaction’s amount, currency, and payment flow. We prioritize payment methods that increase conversion and are most relevant to the customer’s currency and location. Any of the additional elements options passed when creating the Elements group in the earlier step should also be passed when creating the PaymentIntent. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -H "Stripe-Version: 2026-05-27.dahlia" \ -d "amount"=1099 \ -d "currency"="usd" \-d "automatic_payment_methods[enabled]"=true \ ``` > Each payment method needs to support the currency passed in the PaymentIntent and your business needs to be based in one of the countries each payment method supports. For more details about what’s supported, see the [Payment method integration options](https://docs.stripe.com/payments/payment-methods/integration-options.md). ## Update the submit handler [客户端] Instead of using individual confirm methods like `stripe.confirmCardPayment` or `stripe.confirmP24Payment`, use [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) to collect payment information and submit it to Stripe. To confirm the PaymentIntent, make the following updates to your submit handler: - Call `await elements.submit()` to trigger form validation and collect any data required for [wallets](https://docs.stripe.com/js/elements_object/create_payment_element#payment_element_create-options-wallets). - Optional: Move PaymentIntent creation to the submit handler. This way you only create the PaymentIntent when you’re sure of the final amount. - Pass the `elements` instance you used to create the Payment Element and the `clientSecret` from the PaymentIntent as parameters to `stripe.confirmPayment`. When called, `stripe.confirmPayment` attempts to complete any [required actions](https://docs.stripe.com/payments/paymentintents/lifecycle.md), such as authenticating your customers by displaying a 3DS dialog or redirecting them to a bank authorization page. When confirmation is complete, users are directed to the `return_url` you configured, which normally corresponds to a page on your website that [provides the status of the payment](https://docs.stripe.com/payments/accept-a-payment.md#web-post-payment). If you want to keep the same checkout flow for card payments and only redirect for redirect-based payment methods, you can set [redirect](https://docs.stripe.com/js/payment_intents/confirm_payment#confirm_payment_intent-options-redirect) to `if_required`. The following code example replaces `stripe.confirmCardPayment` with `stripe.confirmPayment`: ### Before ```javascript // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", headers: {"Content-Type": "application/json"}, }); const {client_secret: clientSecret} = await res.json(); const handleSubmit = async (event) => { event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); if (error) { handleError(error); } }; ``` ### After ```javascript const handleSubmit = async (event) => { event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", headers: {"Content-Type": "application/json"}, }); const {client_secret: clientSecret} = await res.json(); // Use the clientSecret and Elements instance to confirm the setup const {error} = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, // Uncomment below if you only want redirect for redirect-based payments // redirect: "if_required", }); if (error) { handleError(error); } }; ``` ## Optional: Recollect a CVC When creating subsequent payments on a saved card, you might want to re-collect the CVC of the card as an additional fraud measure to verify the user. Start by creating a `PaymentIntent` on your server with the amount, currency, the [Account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) or [Customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer) ID, and [require_cvc_recollection](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-card-require_cvc_recollection). [List the PaymentMethods](https://docs.stripe.com/api/payment_methods/list.md) associated with your customer to determine which ones to show for CVC re-collection. After passing the `PaymentIntent`’s client secret to the browser, you can re-collect CVC information with Stripe Elements on your client. Use the `cardCvc` Element to re-collect a CVC value from your customer, then confirm the payment from your client using [stripe.confirmCardPayment](https://docs.stripe.com/js.md#stripe-confirm-card-payment). Set `payment_method` to your PaymentMethod ID, and `payment_method_options[card][cvc]` to your `cardCvc` Element. ```javascript const result = await stripe.confirmCardPayment(clientSecret, { payment_method: '{{PAYMENT_METHOD_ID}}', payment_method_options: { card: { cvc: cardCvcElement } }, }); if (result.error) { // Show error to your customer console.log(result.error.message); } else { if (result.paymentIntent.status === 'succeeded') { // Show a success message to your customer // There's a risk of the customer closing the window before callback // execution. Set up a webhook or plugin to listen for the // payment_intent.succeeded event that handles any business critical // post-payment actions. } } ``` 即使未通过 CVC 检查,付款也可能成功。为防止出现此问题,可配置您的 [Radar 规则](https://docs.stripe.com/radar/rules.md#traditional-bank-checks) 以在 CVC 验证失败时阻止付款。 ## 处理付款后事件 [服务器端] 付款完成时,Stripe 会发送一个 [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) 事件。使用 [管理平台 Webhook 工具](https://dashboard.stripe.com/webhooks)、或按照 [Webhook 指南](https://docs.stripe.com/webhooks/quickstart.md)来接收这些事件并运行操作,例如,向客户发送订单确认邮件、在数据库中记录订单,或启动配送流程。 侦听这些事件,而不是等待客户端回调。在客户端,客户可能会在执行回调之前关闭浏览器窗口或退出应用程序,并且恶意客户端可能会操纵响应。设置您的集成来侦听异步事件,这样才能用单一集成用用接受[不同类型的支付方式](https://stripe.com/payments/payment-methods-guide)。 除了处理 `payment_intent.succeeded` 事件外,建议在使用 Payment Element 收款时也处理其他的这些事件: | 事件 | 描述 | 操作 | | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | 客户成功完成付款时发送。 | 向客户发送订单确认通知,并*履行* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)他们的订单。 | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | 当客户成功发起付款但并未完成时发送。当客户发起银行借记时,通常会发送此事件。之后将会出现 `payment_intent.succeeded` 或 `payment_intent.payment_failed` 事件。 | 向客户发送订单确认,告知他们的付款正等待处理。对于数字商品,您可能想先履行订单,然后再等付款完成。 | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | 在客户尝试付款但付款失败时发送。 | 如果一笔付款从 `processing` 变为 `payment_failed`,则让客户再尝试一次。 | ## 测试集成 #### 银行卡 | 卡号 | 场景 | 如何测试 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | | 4242424242424242 | 该卡付款成功,不需要验证。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 4000002500003155 | 该卡付款时需要*验证* (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)。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 4000000000009995 | 该卡被拒绝,显示拒付代码,例如 `insufficient_funds`。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 6205500000000000004 | 银联卡的长度为 13-19 位。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | #### 钱包 | 支付方式 | 场景 | 如何测试 | | ------ | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | Alipay | 您的客户通过基于重定向和[立即通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)的支付方式成功付款。 | 选择基于重定向的任意支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**测试付款成功**。 | #### 银行重定向 | 支付方式 | 场景 | 如何测试 | | --------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | BECS 直接借记 | 您的客户成功用 BECS 直接借记完成付款。 | 使用帐号 `900123456` 和 BSB `000000` 填写表格。确认的 PaymentIntent 先转入 `processing`,3 分钟后转为 `succeeded` 状态。 | | BECS 直接借记 | 您的客户付款失败,错误代码为:`account_closed`。 | 使用帐号 `111111113` 和 BSB `000000` 填写表格。 | | Bancontact、EPS、iDEAL 和 Przelewy24 | 您的客户在基于重定向和立即通知型的支付方式的重定向页面验证失败。 | 选择基于重定向的任意支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**让测试付款失败**。 | | 通过银行支付 | 您的客户通过基于重定向和[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)的支付方式成功付款。 | 选择支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**测试付款成功**。 | | 通过银行支付 | 您的客户在基于重定向和延迟通知型的支付方式的重定向页面验证失败。 | 选择支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**让测试付款失败**。 | | BLIK | 有多个 BLIK 支付失败的情况——立即失败(例如,代码已过期或无效)、延迟的错误(银行拒付)或超时(客户未及时响应)。 | 使用电子邮件模式[模拟不同的失败情况](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures)。 | #### 银行借记 | 支付方式 | 场景 | 如何测试 | | --------- | ------------------------------------------------------- | --------------------------------------------------------------------- | | SEPA 直接借记 | 您的客户成功用 SEPA 直接借记完成付款。 | 用账号 `AT321904300235473204` 填写表单。确认的 PaymentIntent 最初变为处理中,三分钟后变为成功状态。 | | SEPA 直接借记 | 您的客户的付款意图状态从 `processing` 变为 `requires_payment_method`。 | 用账号 `AT861904300235473202` 填写表单。 | #### 付款凭单 | 支付方式 | 场景 | 如何测试 | | ------------ | --------------------------- | ------------------------------------ | | Boleto, OXXO | 您的客户用 Boleto 或 OXXO 付款凭单付款。 | 选择 Boleto 或 OXXO 此支付方式并提交付款。出现后关闭对话。 | 有关测试您的集成的更多信息,请参阅[测试](https://docs.stripe.com/testing.md)部分。 # SetupIntent migration If your existing integration uses the [Setup Intents](https://docs.stripe.com/payments/setup-intents.md) API for future payments, follow the steps below to use the Payment Element. ## Enable payment methods > This integration path doesn’t support BLIK or pre-authorized debits that use the Automated Clearing Settlement System (ACSS). Also, if you create the deferred intent from the client-side, you can’t use `customer_balance` with dynamic payment methods because the PaymentIntent requires a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-configuration-customer) or [Customer](https://docs.stripe.com/api/customers/object.md) object, which the client-side flow doesn’t support. To use `customer_balance`, create the `PaymentIntent` server-side with an `Account` or `Customer` and return its `client_secret` to the client. 查看您的[支付方式设置](https://dashboard.stripe.com/settings/payment_methods),启用您想支持的支付方式。您至少需要启用一个支付方式才能在下一步中创建 *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method)。 默认情况下,Stripe 支持信用卡和其他常见的支付方式,可以帮助您获得更多客户,但建议您开启与您的业务和客户相关的其他支付方式。查看[支付方式支持](https://docs.stripe.com/payments/payment-methods/payment-method-support.md),了解支持的产品和支付方式,并查看我们的[定价页面](https://stripe.com/pricing/local-payment-methods)了解费用。 ## Update Elements instance [客户端] Next, update your client-side code to pass the `mode` and `currency` when you create the Elements instance. For use with a SetupIntent, set the `mode` to `'setup'` and the `currency` to what you’ll charge your customer in the future. #### Javascript ### Before ```javascript const stripe = Stripe('<>'); const elements = stripe.elements(); ``` ### After ```javascript const stripe = Stripe('<>'); const options = { mode: 'setup', currency: 'usd', }; const elements = stripe.elements(options); ``` #### React ### Before ```jsx const stripePromise = loadStripe('<>'); function App() { return ( ); }; ``` ### After ```jsx const stripePromise = loadStripe('<>'); const options = { mode: 'setup', currency: 'usd', }; function App() { return ( ); }; ``` ## Optional: Additional Elements options [客户端] The [Elements object](https://docs.stripe.com/js/elements_object/create_without_intent) accepts additional options that influence payment collection. Based on the options provided, the Payment Element displays available payment methods from those you’ve enabled. Learn more about [payment method support](https://docs.stripe.com/payments/payment-methods/payment-method-support.md). Make sure the Elements options you provide (such as `captureMethod`, `setupFutureUsage`, and `paymentMethodOptions`) match the equivalent parameters you pass when creating and confirming the Intent. Mismatched parameters can result in unexpected behavior or errors. | 所有权 | 类型 | 描述 | 必填 | | ---------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | | `mode` | - `payment` - `setup` - `subscription` | 指示 Payment Element 是否和 *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods)、*SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) 或 *Subscription* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) 一起使用。 | 是 | | `currency` | `string` | 向客户收款时使用的货币。 | 是 | | `amount` | `number` | The amount to charge the customer, shown in Apple Pay, Google Pay, or BNPL UIs. | 对于 `payment` 和 `subscription` 模式 | | `setupFutureUsage` | - `off_session` - `on_session` | Indicates that you intend to make future payments with the payment details collected by the Payment Element. | 否 | | `captureMethod` | - `automatic` - `automatic_async` - `manual` | 控制何时从客户的账户中获取资金。 | 否 | | `onBehalfOf` | `string` | Connect only. The Stripe account ID, which is the business of record. See [use cases](https://docs.stripe.com/connect/charges.md) to determine if this option is relevant for your integration. | 否 | | `paymentMethodTypes` | `string[]` | A list of payment method types to render. You can omit this attribute to manage your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). | 否 | | `paymentMethodConfiguration` | `string` | The [payment method configuration](https://docs.stripe.com/api/payment_method_configurations.md) to use when managing your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). If not specified, your default configuration is used. | 否 | | `paymentMethodCreation` | `manual` | Allows PaymentMethods to be created from the Elements instance using [stripe.createPaymentMethod](https://docs.stripe.com/js/payment_methods/create_payment_method_elements). | 否 | | `paymentMethodOptions` | `{us_bank_account: {verification_method: string}}` | Verification options for the `us_bank_account` payment method. Accepts the same verification methods as [Payment Intents](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-us_bank_account-verification_method). | 否 | | `paymentMethodOptions` | `{card: {installments: {enabled: boolean}}}` | Allows manually enabling the card installment plan selection UI if applicable when you aren’t managing your payment methods in the [Stripe Dashboard](https://dashboard.stripe.com/settings/payment_methods). You must set `mode='payment'` *and* explicitly specify `paymentMethodTypes`. Otherwise an error is raised. Incompatible with `paymentMethodCreation='manual'`. | 否 | | `paymentMethodOptions` | `{[paymentMethod]: {setup_future_usage: string}}` | Allows you to specify `setup_future_usage` for only payment methods that support reuse. Only applicable when `mode` is `payment`. The value for each payment method must match the corresponding `payment_method_options[paymentMethod][setup_future_usage]` on the PaymentIntent during confirmation. See the [Stripe.js reference](https://docs.stripe.com/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodOptions) for supported payment methods and values. | 否 | ## Add the Payment Element [客户端] If you’re using [React Stripe.js](https://github.com/stripe/react-stripe-js), update to the latest package to use the Payment Element. You can now replace the Card Element and individual payment methods Elements with the Payment Element. The Payment Element automatically adjusts to collect input fields based on the payment method and country (for example, full billing address collection for SEPA Direct Debit) so you don’t have to maintain customized input fields anymore. The following example replaces `CardElement` with `PaymentElement`: #### JavaScript ```html
``` ```javascript const paymentElement = elements.create("payment"); paymentElement.mount("#payment-element"); ``` If your payment flow already always collects details like the customer’s name or email address, you can prevent the Payment Element from collecting this information by passing the [fields](https://docs.stripe.com/js/elements_object/create_payment_element#payment_element_create-options-fields) option when creating the Payment Element. If you disable the collection of a certain field, you must pass that same data back with [stripe.confirmSetup](https://docs.stripe.com/js/setup_intents/confirm_setup). ## Update your SetupIntent creation call [服务器端] Because the Payment Element allows you to accept multiple payment methods, we recommend using `automatic_payment_methods`. When you enable it, Stripe evaluates the currency, payment method restrictions, and other parameters to determine the list of payment methods available for your customers. We prioritize payment methods that increase conversion and are most relevant to the currency and location of the customer. Add the `automatic_payment_methods` attribute to the endpoint on your server that creates the SetupIntent. Any of the additional elements options passed when creating the Elements group in the earlier step should also be passed when creating the SetupIntent. #### curl ```bash curl https://api.stripe.com/v1/setup_intents \ -u <>: \ -H "Stripe-Version: 2026-05-27.dahlia" \ -d "customer"="{{CUSTOMER_ID}}" \-d "automatic_payment_methods[enabled]"=true ``` > You can’t save some payment methods for future payments. For more information, see [Payment method integration options](https://docs.stripe.com/payments/payment-methods/integration-options.md). ## Update the submit handler [客户端] Instead of using individual confirm methods like `stripe.confirmCardSetup` or `stripe.confirmP24Setup`, use [stripe.confirmSetup](https://docs.stripe.com/js/setup_intents/confirm_setup) to collect payment information and submit it to Stripe. To confirm the SetupIntent, make the following updates to your submit handler: - Call `await elements.submit()` to trigger form validation and collect any data required for [wallets](https://docs.stripe.com/js/elements_object/create_payment_element#payment_element_create-options-wallets). - Optional: Move SetupIntent creation to the submit handler. This way you only create the SetupIntent when the user is ready to submit their payment method details. - Pass the `elements` instance you used to create the Payment Element and the `clientSecret` from the SetupIntent as parameters to `stripe.confirmSetup`. When called, `stripe.confirmSetup` attempts to complete any [required actions](https://docs.stripe.com/payments/paymentintents/lifecycle.md), such as authenticating your customers by displaying a 3DS dialog or redirecting them to a bank authorization page. When confirmation is complete, users are directed to the `return_url` you configured, which normally corresponds to a page on your website that provides the status of the `SetupIntent`. If you want to keep the same flow for saving card payment details and only redirect for redirect-based payment methods, set [redirect](https://docs.stripe.com/js/setup_intents/confirm_setup#confirm_setup_intent-options-redirect) to `if_required`. The following code examples replaces `stripe.confirmCardSetup` with `stripe.confirmSetup`: ### Before ```javascript // Create the SetupIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", headers: {"Content-Type": "application/json"}, }); const {client_secret: clientSecret} = await res.json(); const handleSubmit = async (event) => { event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); if (error) { handleError(error); } }; ``` ### After ```javascript const handleSubmit = async (event) => { event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the SetupIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", headers: {"Content-Type": "application/json"}, }); const {client_secret: clientSecret} = await res.json(); // Use the clientSecret and Elements instance to confirm the setup const {error} = await stripe.confirmSetup({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, // Uncomment below if you only want redirect for redirect-based payments // redirect: "if_required", }); if (error) { handleError(error); } }; ``` ## 测试集成 用测试付款详情和测试重定向页面验证您的集成。点击下方选项卡,查看每个支付方式的详情。 #### 银行卡 | 支付方式 | 场景 | 如何测试 | | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | | 信用卡 | 银行卡设置成功,不要求*验证* (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)。 | 填写我们的信用卡表单,卡号是 `4242 4242 4242 4242`,有效期、CVC(银行卡安全码)以及邮编可任意填写。 | | 信用卡 | 该卡在初始设置时需要身份验证,在后续付款时会直接成功。 | 填写我们的信用卡表单,卡号是 `4000 0025 0000 3155`,有效期、CVC(银行卡安全码)以及邮编可任意填写。 | | 信用卡 | 该卡在初始设置时需要身份验证,在后续付款时也需要身份验证。 | 填写我们的信用卡表单,卡号是 `4000 0027 6000 3184`,有效期、CVC(银行卡安全码)以及邮编可任意填写。 | | 信用卡 | 设置过程中卡被拒绝了。 | 填写我们的信用卡表单,卡号是 `4000 0000 0000 9995`,有效期、CVC(银行卡安全码)以及邮编可任意填写。 | #### 银行重定向 | 支付方式 | 场景 | 如何测试 | | ---------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | Bancontact | 您的客户用 Bancontact 成功设置了一个 SEPA 直接借记支付方式,供未来使用。 | 在 Bancontact 表单中使用一个任意的名称,然后在重定向页面上点击**授权付款设置**。 | | Bancontact | 您的客户未在 Bancontact 重定向页面进行验证。 | 在 Bancontact 表单中使用一个任意的名称,然后在重定向页面上点击**让测试设置失败**。 | | BECS 直接借记 | 您的客户成功用 BECS 直接借记完成付款。 | 请使用账号 `900123456` 填写表单。已确认的 `PaymentIntent` 状态会先变为 `processing`,3 分钟后变为 `succeeded`。 | | BECS 直接借记 | 您的客户付款失败,错误代码为:`account_closed`。 | 用账号 `111111113` 填写表单。 | | iDEAL | 您的客户用 iDEAL 成功设置了 [SEPA 直接借记](https://docs.stripe.com/payments/sepa-debit.md)支付方式,供未来使用。 | 在 iDEAL 表单中使用任意的名称和银行,然后在重定向页面上点击**授权测试设置**。 | | iDEAL | 您的客户未在 iDEAL 重定向页面进行验证。 | 选择银行,并在 iDEAL 表单中使用一个任意的名称,然后在重定向页面上点击**让测试设置失败**。 | #### 银行借记 | 支付方式 | 场景 | 如何测试 | | --------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | SEPA 直接借记 | 您的客户成功用 SEPA 直接借记完成付款。 | 请使用账号 `AT321904300235473204` 填写表单。已确认的 `PaymentIntent` 状态会先变为 `processing`,3 分钟后变为 `succeeded`。 | | SEPA 直接借记 | 您的客户的 `PaymentIntent` 状态会从 `processing` 变为 `requires_payment_method`。 | 用账号 `AT861904300235473202` 填写表单。 | ### 测试对保存的 SEPA 借记 PaymentMethod 的收款 当使用 iDEAL、Bancontact 或 Sofort 确认 `SetupIntent` 时,会生成一个 [SEPA 直接借记](https://docs.stripe.com/payments/sepa-debit.md) *支付方式* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs)。SEPA 直接借记是一种[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)支付方式,其状态会先变为中间的 `processing` 状态,几天后再变为 `succeeded` 或 `requires_payment_method` 状态。 #### 邮箱 将 `payment_method.billing_details.email` 设置为以下值之一,以测试 `PaymentIntent` 的状态转换。您可以在电子邮箱地址开头添加自定义文本,后面跟一个下划线。例如,使用 `test_1_generatedSepaDebitIntentsFail@example.com` 将会生成一个在用于 `PaymentIntent` 时始终失败的 SEPA 直接借记 PaymentMethod。 | 邮件地址 | 描述 | | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | | `generatedSepaDebitIntentsSucceed@example.com` | `PaymentIntent` 的状态从 `processing` 转换为 `succeeded`。 | | `generatedSepaDebitIntentsSucceedDelayed@example.com` | 至少三分钟后,`PaymentIntent` 的状态从 `processing` 转换为 `succeeded`。 | | `generatedSepaDebitIntentsFail@example.com` | `PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`。 | | `generatedSepaDebitIntentsFailDelayed@example.com` | 至少三分钟后,`PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`。 | | `generatedSepaDebitIntentsSucceedDisputed@example.com` | `PaymentIntent` 的状态从 `processing` 转换为 `succeeded`,但会立即产生争议。 | | `generatedSepaDebitIntentsFailsDueToInsufficientFunds@example.com` | `PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`,并带有 `insufficient_funds` 失败代码。 | #### PaymentMethod 使用这些 PaymentMethod 来测试 `PaymentIntent` 的状态转换。这些令牌对于自动化测试非常有用,可立即在服务器上将 PaymentMethod 附加到SetupIntent。 | 支付方式 | 描述 | | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `pm_bancontact_generatedSepaDebitIntentsSucceed` | `PaymentIntent` 的状态从 `processing` 转换为 `succeeded`。 | | `pm_bancontact_generatedSepaDebitIntentsSucceedDelayed` | 至少三分钟后,`PaymentIntent` 的状态从 `processing` 转换为 `succeeded`。 | | `pm_bancontact_generatedSepaDebitIntentsFail` | `PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`。 | | `pm_bancontact_generatedSepaDebitIntentsFailDelayed` | 至少三分钟后,`PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`。 | | `pm_bancontact_generatedSepaDebitIntentsSucceedDisputed` | `PaymentIntent` 的状态从 `processing` 转换为 `succeeded`,但会立即产生争议。 | | `pm_bancontact_generatedSepaDebitIntentsFailsDueToInsufficientFunds` | `PaymentIntent` 的状态从 `processing` 转换为 `requires_payment_method`,并带有 `insufficient_funds` 失败代码。 |