The Payment Intents API
Use the Payment Intents API to build a payments integration that can handle complexity. This API tracks a payment, from initial creation through the entire checkout process, and triggers additional authentication steps when required.
As global payments evolve, we expect to see an increase in dynamic payments. Regulatory mandates, custom Radar fraud rules, or redirect-based payment methods are just some examples that could trigger extra steps in a single payment process. Start accepting payments now.
Our Payment Intents API prepares your business for growth:
- Automatic authentication handling
- No double charges
- No idempotency key issues
- Support for Strong Customer Authentication (SCA) and similar regulatory changes
The Charges API is available for setting up basic payments—without handling additional authentication—in the U.S. and Canada. We strongly recommend updating your integration to make scaling your business simpler in a world of evolving payments regulations.
A complete set of APIs
Use the Payment Intents API together with the Setup Intents and Payment Methods APIs.
These new APIs help you handle dynamic payments (e.g., additional authentication like 3D Secure and prepare you for expansion to other countries. As new regulations and regional payment methods come with different requirements, these APIs help you support them.
Add payment methods with the Payment Methods API, set them up for future payments with the Setup Intents API, and drive the payment process with the Payment Intents API.
Building an integration with the Payment Intents API involves two actions: creating and confirming a PaymentIntent. Each PaymentIntent typically correlates with a single shopping cart or customer session in your application. The PaymentIntent encapsulates details about the transaction, such as the supported payment methods, the amount to collect, and the desired currency.
Creating a PaymentIntent
To get started, accept a payment.
In the guide, you’ll create a PaymentIntent on the server and pass its client secret to the client instead of passing the entire PaymentIntent object. The payment is confirmed on the client, and your server monitors webhooks to detect when the payment completes successfully or fails.
When you create the PaymentIntent, you can specify options like the amount and currency:
Best practices
We recommend creating a PaymentIntent as soon as the amount is known, such as when the customer begins the checkout process, to help track your sales funnel. If the amount changes, you can update its amount. For example, if your customer backs out of the checkout process and adds new items to their cart, you may need to update the amount accordingly when they start the checkout process again.
If the checkout process is interrupted and resumes later, you should attempt to reuse the same PaymentIntent instead of creating a new one. Each PaymentIntent has a unique ID that you can use to retrieve it if you need it again. In your application’s data model, you can store the PaymentIntent’s ID on the customer’s shopping cart or session in order to facilitate retrieval. The benefit of reusing the PaymentIntent is that the object helps track any failed payment attempts for a given cart or session.
You should also provide an idempotency key—typically based on the ID that you associate with the cart or customer session in your application—when creating the PaymentIntent to avoid erroneously creating duplicate PaymentIntents for the same purchase.
Passing the client secret to the client side
The PaymentIntent contains a client secret, a key that is unique to the individual PaymentIntent. On the client side of your application, the client secret is used as a parameter when invoking Stripe.js functions (such as stripe.confirmCardPayment or stripe.handleCardAction) to complete the payment.
To use the client secret, you must obtain it from the PaymentIntent on your server and pass it to the client side. There are different approaches that you can use to get the client secret to the client side. Choose the approach that best suits the architecture of your application.
The client secret can be used to complete the payment process with the amount specified on the PaymentIntent. It should not be logged, embedded in URLs, or exposed to anyone other than the customer. Make sure that you have TLS enabled on any page that includes the client secret.
Optimizing cards for future payments
The setup_future_usage parameter saves payment methods to use again in the future. For cards, it also optimizes authorization rates in compliance with regional legislation and network rules, such as SCA. To determine which value to use, consider how you want to use this payment method in the future.
How you intend to use the payment method | setup_future_usage enum value to use |
---|---|
On-session payments only | on_session |
Off-session payments only | off_session |
Both on and off-session payments | off_session |
A card set up for on-session payments can still be used to make off-session payments, but the bank is more likely to reject the off-session payment and require authentication from the cardholder.
The following example shows how to create a PaymentIntent and specify setup_future_usage
:
Dynamic statement descriptor
By default, your Stripe account’s statement descriptor appears on customer statements whenever you charge their card. To provide a different description on a per-payment basis, include the statement_descriptor
parameter.
Statement descriptors are limited to 22 characters, cannot 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 set in the Stripe Dashboard. An *
and an empty space are also added to separate the default statement descriptor from the dynamic portion. These two characters count towards the 22 character limit.
Storing information in metadata
Stripe supports adding metadata to the most common requests you make, such as processing payments. Metadata isn’t shown to customers or factored into whether or not a payment is declined or blocked by our fraud prevention system.
Through metadata, you can associate other information—meaningful to you—with Stripe activity. Any metadata you include is viewable in the Dashboard (e.g., when looking at the page for an individual payment), and is also available in common reports. As an example, your store’s order ID can be attached to the PaymentIntent used to pay for that order. Doing so allows you, your accountant, or your finance team to easily reconcile payments in Stripe to orders in your system.
If you are using Radar, consider passing any additional customer information and order information as metadata. By doing so, you can write Radar rules using metadata attributes and have more information about the payment available within the Dashboard which can expedite your review process.
When a PaymentIntent creates a charge, the PaymentIntent copies its metadata to the charge. Subsequent updates to the PaymentIntent’s metadata will not modify the metadata of charges previously created by the PaymentIntent.
Do not store any sensitive information (personally identifiable information, card details, etc.) as metadata or in the PaymentIntent’s description
parameter.