# 迁移到 PaymentIntent 和支付方式 API 了解如何从 Sources 和 Tokens API 过渡到 Payment Methods API。 [Payment Methods API](https://docs.stripe.com/api/payment_methods.md) 替换了当前的 [Tokens](https://docs.stripe.com/api/tokens.md) 和 [Sources](https://docs.stripe.com/api/sources.md),为多种支付方式创建付款。它可以和 [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) 一起使用,为多种支付方式创建付款。 我们计划停止对*本地支付方式* (Payment methods used in specific countries or regions, such as bank transfers, vouchers, and digital wallets. Examples include Pix (Brazil, bank transfers), Konbini (Japan, vouchers), and WeChat Pay (China, digital wallet))的 Sources API 支持。如果您当前正使用 Sources API 处理任何本地支付方式,则必须[将其迁移至 Payment Methods API](https://docs.stripe.com/payments/payment-methods/transitioning.md#migrate-local-payment-methods)。我们将通过电子邮件发送有关 Sources API 和 Token API 停止支持事宜的更多详细信息。 虽然我们不打算停止支持银行卡支付方式,但仍建议您将其迁移至 Payment Methods 和 Payment Intents API。有关迁移银行卡支付方式的更多信息,请参阅[迁移到 Payment Intents API](https://docs.stripe.com/payments/payment-intents/migration.md)。 ## 将本地支付方式从 Sources API 迁移到 Payment Intents API 要迁移您的本地支付方式集成,更新您的服务器和前端以使用 [PaymentIntents API](https://docs.stripe.com/api/payment_intents.md)。通常涉及三种典型的集成选项: - 在您的支付流程中重定向到 [Stripe Checkout](https://docs.stripe.com/payments/checkout.md)。 - 在您自己的支付页面使用 Stripe [Payment Element](https://docs.stripe.com/payments/payment-element.md)。 - 构建自己的表单并使用 Stripe JS SDK 完成付款。 如果您使用 Stripe Checkout 或 Payment Element,则可以从 Stripe 管理平台添加和管理大多数支付方式,不需要更改代码。 有关用 Payment Methods API 集成本地支付方式的具体信息,请查看[支付方式文档](https://docs.stripe.com/payments/payment-methods/overview.md)中该支付方式的说明。下表对不同支付类型进行了更高级别的比较。 | 旧集成 | Stripe Checkout | Payment Element | 自己的表单 | | --------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | | | 低度复杂 | 中度复杂 | 高度复杂 | | 在前端或服务器上创建 Source | 在服务器上创建 Checkout Session | 在服务器上创建 PaymentIntent | 在服务器上创建 PaymentIntent | | 通过加载小工具或重定向到第三方来授权付款 | 不需要 | 将客户端私钥传递给前端,并使用 Stripe JS SDK 呈现 Payment Element 以完成付款 | 将客户端私钥传递给前端,用您自己的表单收集客户的详细信息,然后根据支付方式完成付款 | | 确认可对扣款来源扣款,并对 Source 扣款 | 不需要 | 不需要 | 不需要 | | 使用 `charge.succeeded` Webhook 异步确认 Charge 已成功 | 使用 `payment_intent.succeeded` Webhook 确认 Checkout Session 已成功 | 使用 `payment_intent.succeeded` Webhook 确认 PaymentIntent 已成功 | 使用 `payment_intent.succeeded` Webhook 确认 PaymentIntent 已成功 | > PaymentIntent 对象表示新集成中的付款,当您在前端确认付款时,它会创建 Charge。如果您之前存储了对 Charge 的参考信息,则可以在客户完成付款后通过从 PaymentIntent 获取 Charge ID 来继续这样做。但是,我们也建议您存储 PaymentIntent ID。 ### 检查支付状态 之前,您的集成应该会在每次 API 调用后都检查 Source 的状态和 Charge 的状态。您现在不再需要检查这两个状态——只需要在前端确认后检查 PaymentIntent 或 Checkout Session 的状态即可。 | payment_intent.status | 含义 | 特别说明 | | ------------------------- | ----------- | ---------------------------------------------------------------------------- | | `succeeded` | 支付成功。 | 不适用 | | `requires_payment_method` | 支付失败。 | 不适用 | | `requires_action` | 客户尚未完成付款授权。 | 如果客户没有在 48 小时内完成付款,则 PaymentIntent 将转化为 `requires_payment_method`,然后您可以重试确认。 | 一定要通过在您的服务器上获取 PaymentIntent 或侦听您的服务器上的 Webhook 来确认 PaymentIntent 的状态。不要只依赖您确认 PaymentIntent 时返回到提供的 `return_url` 的用户。 ### 退款 您可以继续通过 PaymentIntent 创建的 Charge 调用 Refunds API。Charge ID 可通过 `latest_charge` 参数获取。 或者,您可以向 Refunds API 提供 PaymentIntent ID,而非向 Charge 提供。 ### 错误处理 以前,您必须处理 Source 上的错误。使用 PaymentIntent,您可以在创建 PaymentIntent 时以及客户授权付款后检查 PaymentIntent 上的错误,而非检查 Source 上的错误。PaymentIntent 上的大多数错误属于 `invalid_request_error` 类型,在无效请求中返回。 迁移您的集成时,请记住 PaymentIntent 错误代码可能与 Source 的相应错误代码存在差异。 ### Webhook 如果您以前侦听过 Source 事件,则您可能需要更新您的集成来侦听新的事件类型。下表所示为一些示例。 | 旧的 Webhook | Checkout 上的新 Webhook | PaymentIntent 上的新 Webhook | 特别说明 | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ | | `source.chargeable` | 不适用 | 不适用 | | | `source.failed` | 不适用 | 不适用 | | | `source.canceled` | 不适用 | 不适用 | | | `charge.succeeded` | `checkout.session.completed` | `payment_intent.succeeded` | 同时还会发送 `charge.succeeded` Webhook,因此您不必更新您的集成即可侦听新的 Webhook。 | | `charge.failed` | 不适用——客户可以在同一个 Checkout Session 上重新尝试付款,直至其[过期](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-expires_at),此时您会收到一个 `checkout.session.expired` 事件。 | `payment_intent.payment_failed` | 同时还会发送 `charge.failed` Webhook,因此您不必更新您的集成即可侦听新的 Webhook。 | | `charge.dispute.created` | `charge.dispute.created` | `charge.dispute.created` | | ## 转移到 Payment Methods API Payment Methods 和 Sources API 之间的主要区别在于 Source 是通过[状态](https://docs.stripe.com/api/sources/object.md#source_object-status)属性描述交易状态。这意味着每个 `Source` 对象在可以用于支付之前必须转换到可扣款状态。与之相反,`PaymentMethod` 是无状态的,靠 *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) 对象来表示付款状态。 > 下表并非完整的支付方式列表。如果您将其他支付方式与 Sources API 进行集成,则也将它们迁移到 Payment Methods API。 | 流程 | 用 Payment Intents API 集成 Payment Method | Tokens 或 Sources 使用 Charges API | | ---------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | 银行卡 | [银行卡支付](https://docs.stripe.com/payments/cards.md) | [Tokens 上支持](https://docs.stripe.com/payments/charges-api.md);Source 上不建议 | | ACH 直接借记 | [美国银行账户直接借记](https://docs.stripe.com/payments/ach-direct-debit.md) | [Tokens 上支持](https://docs.stripe.com/ach-deprecated.md) Source 上不支持 | | ACH 贷记转账 | [美元银行转账](https://docs.stripe.com/payments/customer-balance/migrating-from-sources.md) | [已弃用](https://docs.stripe.com/sources/ach-credit-transfer.md) | | 支付宝 | [支付宝支付](https://docs.stripe.com/payments/alipay.md) | [已弃用](https://docs.stripe.com/sources/alipay.md) | | Bancontact | [Bancontact 支付](https://docs.stripe.com/payments/bancontact.md) | [已弃用](https://docs.stripe.com/sources/bancontact.md) | | EPS | [EPS 支付](https://docs.stripe.com/payments/eps.md) | 已弃用 | | giropay | [giropay 支付](https://docs.stripe.com/payments/giropay.md) | [已弃用](https://docs.stripe.com/sources/giropay.md) | | iDEAL | [iDEAL 支付](https://docs.stripe.com/payments/ideal.md) | [已弃用](https://docs.stripe.com/sources/ideal.md) | | Klarna | [Klarna 支付](https://docs.stripe.com/payments/klarna.md) | 已弃用 | | Multibanco | [Multibanco 支付](https://docs.stripe.com/payments/multibanco.md) | [已弃用 Beta](https://docs.stripe.com/sources/multibanco.md) | | Przelewy24 | [Przelewy24 支付](https://docs.stripe.com/payments/p24.md) | [已弃用](https://docs.stripe.com/sources/p24.md) | | SEPA 贷记转账 | [欧元银行转账](https://docs.stripe.com/payments/customer-balance/migrating-from-sepa-credit-transfer.md) | [已弃用](https://docs.stripe.com/sources/sepa-credit-transfer.md) | | SEPA 直接借记 | [单一欧元支付区直接借记](https://docs.stripe.com/payments/sepa-debit.md) | [已弃用](https://docs.stripe.com/sources/sepa-debit.md) | | WeChat Pay | [微信支付](https://docs.stripe.com/payments/wechat-pay.md) | [已弃用](https://docs.stripe.com/sources/wechat-pay.md) | 选择了要集成的 API 之后,可使用我们的[支付方式指南](https://stripe.com/payments/payment-methods-guide)确定正确的支付方式来支持您的客户。 本指南中包含对各个支付方式的详细描述,并讲述了它们在面向客户的流程中的差异,同时还给出了最相关的[地理区域](https://stripe.com/payments/payment-methods-guide#payment-methods-fact-sheets)。您可以在[管理平台](https://dashboard.stripe.com/account/payments/settings)中启用可使用的支付方式。激活通常是即时的,不需要额外的合同。 ## 与旧版可重复使用的支付方式兼容 如果您之前用 [Sources](https://docs.stripe.com/sources.md) 处理过以下任何可重复使用的支付方式,则不会自动迁移当前已保存的支付来源。 - 支付宝 - BACS 直接借记 - SEPA 直接借记 要保留当前客户保存的支付方式,您必须用 Stripe 管理平台内的数据迁移工具将这些来源转化为支付方式。有关转化方式的说明,请参阅[支持页面](https://support.stripe.com/questions/reusable-object-migration)。 ## 与旧版银行卡对象的兼容性 如果您之前使用 Stripe 的[银行卡](https://docs.stripe.com/payments/charges-api.md) 或 [Sources](https://docs.stripe.com/sources.md) 收集了银行卡客户的支付信息,可以即刻开始使用支付方式 API,无需迁移任何支付信息。 已保存到 *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) 的兼容支付方式可以用于接受 *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) 对象的任意 API。例如,创建 PaymentIntent 时,您可以将保存的银行卡用作一个 PaymentMethod: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "payment_method_types[]=card" \ -d amount=1099 \ -d currency=usd \ -d "customer={{CUSTOMER_ID}}" \ -d "payment_method={{CARD_ID}}" ``` 切记,在将对象绑定到 PaymentIntent 时,务必要提供您的兼容支付方式所保存到的 Customer ID。 您可以通过 Payment Methods API [检索](https://docs.stripe.com/api/payment_methods/retrieve.md)所有已保存的兼容支付方式。 #### 银行卡 ```json { "id": "card_1EBXBSDuWL9wT9brGOaALeD2", "object": "card", "address_city": "San Francisco", "address_country": "US", "address_line1": "1234 Fake Street", "address_line1_check": null, "address_line2": null, "address_state": null, "address_zip": null, "address_zip_check": null, "brand": "Visa", "country": "US", "customer": "{{CUSTOMER_ID}}", "cvc_check": null, "dynamic_last4": null, "exp_month": 8, "exp_year": 2024, "fingerprint": "53v265akSHAnIk1X", "funding": "credit", "last4": "4242", "metadata": { }, "name": null, "tokenization_method": null } ``` ```json { "id": "card_1EBXBSDuWL9wT9brGOaALeD2", "object": "payment_method", "billing_details": { "address": { "city": "San Francisco", "country": "US", "line1": "1234 Fake Street", "line2": null, "postal_code": null, "state": null }, "name": null, "phone": null, "email": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": null }, "country": "US", "exp_month": 8, "exp_year": 2024, "fingerprint": "53v265akSHAnIk1X", "funding": "credit", "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 123456789, "customer": "cus_EepWxEKrgMaywv", "livemode": false, "metadata": { }, "type": "card" } ``` #### 银行卡资源 ```json { "id": "src_1AhIN74iJb0CbkEwmbRYPsd4", "object": "source", "amount": null, "client_secret": "src_client_secret_sSPHZ17iQG6j9uKFdAYqPErO", "created": 1500471469, "currency": null, "flow": "none", "livemode": false, "metadata": { }, "owner": { "address": { "city": "Berlin", "country": "DE", "line1": "Nollendorfstraße 27", "line2": null, "postal_code": "10777", "state": null }, "email": "jenny.rosen@example.com", "name": "Jenny Rosen", "phone": null, "verified_address": null, "verified_email": null, "verified_name": null, "verified_phone": null }, "status": "chargeable", "type": "card", "usage": "reusable", "card": { "exp_month": 4, "exp_year": 2024, "address_line1_check": "unchecked", "address_zip_check": "unchecked", "brand": "Visa", "country": "US", "cvc_check": "unchecked", "funding": "credit", "last4": "4242", "three_d_secure": "optional", "tokenization_method": null, "dynamic_last4": null } } ``` ```json { "id": "card_1EBXBSDuWL9wT9brGOaALeD2", "object": "payment_method", "billing_details": { "address": { "city": "Berlin", "country": "DE", "line1": "Nollendorfstraße 27", "line2": null, "postal_code": "10777", "state": null }, "name": "Jenny Rosen", "phone": null, "email": "jenny.rosen@example.com" }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": null }, "country": "US", "exp_month": 4, "exp_year": 2024, "fingerprint": "53v265akSHAnIk1X", "funding": "credit", "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1500471469, "customer": "{{CUSTOMER_ID}}", "livemode": false, "metadata": { }, "type": "card" } ``` 有了这种兼容性,就不会创建新的对象;Payment Methods API 为同一底层对象提供了一个不同的视图。例如,通过 Payment Methods API 对兼容支付方式进行的更新可以通过 Sources API 看到,反之亦然。 ## See also - [支付方式指南](https://stripe.com/payments/payment-methods-guide) - [Connect 支付](https://docs.stripe.com/connect/charges.md) - [Payment Methods API 参考](https://docs.stripe.com/api/payment_methods.md)