Transition to the Payment Intents and Payment Methods APIs
Learn how to transition from the Sources and Tokens APIs to the Payment Methods API.
The Payment Methods API replaces the existing Tokens and Sources APIs as the recommended way for integrations to collect and store payment information. It works with the Payment Intents API to create payments for a wide range of payment methods.
We plan to turn off Sources API support for local payment methods. If you currently handle any local payment methods using the Sources API, you must migrate them to the Payment Methods API. We’ll send email communication with more information about the end of support for the Sources and Tokens APIs.
While we don’t plan to turn off support for card payment methods, we still recommend that you migrate them to the Payment Methods and Payment Intents APIs. For more information about migrating card payment methods, see Migrating to the Payment Intents API.
Migrate local payment methods from the Sources API to the Payment Intents API
To migrate your integration for local payment methods, update your server and front end to use the PaymentIntents API. There are three typical integration options:
- Redirect to Stripe Checkout for your payment flow.
- Use the Stripe Payment Element on your own payment page.
- Build your own form and use the Stripe JS SDK to complete the payment.
If you use Stripe Checkout or the Payment Element, you can add and manage most payment methods from the Stripe Dashboard without making code changes.
For specific information about integrating a local payment method using the Payment Methods API, see the instructions for that payment method in the payment methods documentation. The following table provides a high-level comparison of the different payment types.
Old integration | Stripe Checkout | Payment Element | Own form |
---|---|---|---|
Low complexity | Medium complexity | High complexity | |
Create a Source on the front end or on the server | Create a Checkout Session on the server | Create a PaymentIntent on the server | Create a PaymentIntent on the server |
Authorize payment by loading a widget or redirecting to a third party | Not needed | Pass the client secret to the front end and use the Stripe JS SDK to render a Payment Element to complete the payment | Pass the client secret to the front end, use your own form to collect details from your customer, and complete the payment according to the payment method |
Confirm the source is chargeable and charge the Source | Not needed | Not needed | Not needed |
Confirm the Charge succeeded asynchronously with the charge. webhook | Confirm the Checkout session succeeded with the payment_ webhook | Confirm the PaymentIntent succeeded with the payment_ webhook | Confirm the PaymentIntent succeeded with the payment_ webhook |
Caution
A PaymentIntent object represents a payment in the new integration, and it creates a Charge when you confirm the payment on the front end. If you previously stored references to the Charge, you can continue to do so by fetching the Charge ID from the PaymentIntent after the customer completes the payment. However, we also recommend that you store the PaymentIntent ID.
Checking payment status
Previously, your integration should have checked both the status of the Source and the status of the Charge after each API call. You no longer need to check two statuses—you only need to check the status of the PaymentIntent or the Checkout Session after you confirm it on the front end.
payment_intent.status | Meaning | Special instructions |
---|---|---|
succeeded | The payment succeeded. | Not applicable |
requires_ | The payment failed. | Not applicable |
requires_ | The customer hasn’t completed authorizing the payment. | If the customer doesn’t complete the payment within 48 hours, then the PaymentIntent transitions to requires_ and you can retry the confirmation. |
Always confirm the status of the PaymentIntent by fetching it on your server or listening for the webhooks on your server. Don’t rely solely on the user returning to the return_
that’s provided when you confirm the PaymentIntent.
Refunds
You can continue to call the Refunds API with a Charge that the PaymentIntent creates. The ID of the Charge is accessible on the latest_
parameter.
Alternatively, you can provide the PaymentIntent ID to the Refunds API instead of the Charge.
Error handling
Previously, you had to handle errors on the Sources. With PaymentIntents, instead of checking for errors on a Source, you check for errors on the PaymentIntent when it’s created and after the customer has authorized the payment. Most errors on the PaymentIntent are of invalid_
type, returned in an invalid request.
When you migrate your integration, keep in mind that PaymentIntent error codes can differ from the corresponding error codes for Sources.
Webhooks
If you previously listened to Source events, you might need to update your integration to listen to new event types. The following table shows some examples.
Old webhook | New webhook on Checkout | New webhook on PaymentIntents | Special instructions |
---|---|---|---|
source. | Not applicable | Not applicable | |
source. | Not applicable | Not applicable | |
source. | Not applicable | Not applicable | |
charge. | checkout. | payment_ | The charge. webhook is also sent, so you don’t have to update your integration to listen to the new webhook. |
charge. | Not applicable - The customer can re-attempt the payment on the same Checkout Session until it expires, at which point you receive a checkout. event. | payment_ | The charge. webhook is also sent, so you don’t have to update your integration to listen to the new webhook. |
charge. | charge. | charge. |
Transitioning to the Payment Methods API
The main difference between the Payment Methods and Sources APIs is that Sources describes the transaction state through the status property. That means that each Source
object must transition to a chargeable state before you can use it for a payment. By contrast, a PaymentMethod
is stateless, relying on the PaymentIntent object to represent payment state.
Note
The following table isn’t a comprehensive list of payment methods. If you integrate other payment methods with the Sources API, migrate them to the Payment Methods API as well.
Flows | Integrate Payment Method with Payment Intents API | Tokens or Sources with Charges API |
---|---|---|
Cards | Card payments | Supported on Tokens; Not recommended on Sources |
ACH Direct Debit | US bank account direct debits | Supported on Tokens Not supported on Sources |
Alipay | Alipay payments | Deprecated |
Bancontact | Bancontact payments | Deprecated |
EPS | EPS payments | Deprecated |
giropay | giropay payments | Deprecated |
iDEAL | iDEAL payments | Deprecated |
Klarna | Klarna payments | Deprecated |
Multibanco | Multibanco payments | Deprecated Beta |
Przelewy24 | Przelewy24 payments | Deprecated |
SEPA Direct Debit | Single Euro Payments Area direct debits | Deprecated |
Sofort | Sofort payments | Deprecated |
WeChat Pay | WeChat Pay payments | Deprecated |
After you choose the API to integrate with, use the guide to payment methods to help you determine the right payment method types you need to support.
This guide includes detailed descriptions of each payment method and describes the differences in the customer-facing flows, along with the geographic regions where they’re most relevant. You can enable any payment method available to you within the Dashboard. Activation is generally instantaneous and doesn’t require additional contracts.
Compatibility with legacy reusable payment methods
If you previously processed any of the following reusable payment methods using Sources, the existing saved sources don’t migrate automatically:
- Alipay
- Bacs Direct Debit
- SEPA Direct Debit
To preserve your existing customers’ saved payment methods, you must convert those sources to payment methods using a data migration tool in the Stripe Dashboard. For instructions on how to convert them, see the support page.
Compatibility with legacy card objects
If you previously collected card customer payment details with Stripe using cards or Sources, you can start using the Payment Methods API immediately without migrating any payment information.
Compatible payment instruments that have been saved to a Customer are usable in any API that accepts a PaymentMethod object. For example, you can use a saved card as a PaymentMethod when creating a PaymentIntent:
Remember to provide the customer ID that your compatible payment instrument is saved to when attaching the object to a PaymentIntent.
You can retrieve all saved compatible payment instruments through the Payment Methods API.
With this compatibility, no new objects are created; the Payment Methods API provides a different view of the same underlying object. For example, updates to a compatible payment instrument through the Payment Methods API is visible through the Sources API, and vice versa.