What Are Payment Intents?
The Payment Intents API represents your intent to collect a payment from a customer. Stripe designed this API to handle complex payment flows while automatically managing the nuances of different payment methods, regulatory requirements, and authentication flows. When you create a PaymentIntent, you initiate a payment process that Stripe manages through to completion, whether that results in a successful charge, requires additional customer action, or fails for some reason.
The Payment Intents API is Stripe's recommended approach for most payment integrations. It consolidates the capabilities of several legacy APIs into a single, unified interface that adapts to the payment method being used. This means you can accept credit cards, debit cards, bank transfers, digital wallets, and buy-now-pay-later options without needing to understand the intricacies of each method's specific flow. The API handles 3D Secure authentication, fraud prevention signals, and retry logic automatically, reducing the complexity your code must manage.
Key capabilities:
- Unified API for 135+ payment methods
- Automatic handling of 3D Secure and authentication
- Status-driven lifecycle for predictable behavior
- Future-proof with new payment types as they're added
Before the Payment Intents API, developers had to choose between different Stripe products based on their payment method needs. The legacy Charges API offered simplicity but couldn't handle authentication challenges well. Payment Intents combines the best of both approaches, providing a status-driven model that tells you exactly where you are in the payment process and what you need to do next. This transparency makes it easier to build robust, user-friendly payment experiences that adapt to whatever situation arises during checkout. For teams building custom e-commerce solutions, the Payment Intents API provides the foundation for secure, reliable checkout flows that handle the complexity of modern payments automatically.
Core benefits that make Payment Intents the foundation of modern Stripe integrations
Unified Payment Interface
Accept cards, bank transfers, digital wallets, and buy-now-pay-later options through a single API without handling each method's unique requirements.
Automatic Payment Method Detection
The automatic_payment_methods feature dynamically determines which payment methods to offer based on your settings and customer context.
Status-Driven Lifecycle
A clear state machine guides payments from creation through authentication challenges to final success or failure, making error handling predictable.
Future-Proof Integration
New payment methods are automatically available without code changes when Stripe adds them, keeping your checkout competitive.
Built-in Security
Stripe handles PCI compliance, fraud prevention, and authentication challenges, reducing your security burden.
Graceful Degradation
If one payment method fails, your integration can smoothly offer alternatives without starting over.
Creating a PaymentIntent
Creating a PaymentIntent is straightforward, but the parameters you choose significantly impact how the payment flow behaves. The core required fields are amount and currency, which define what you're charging. The amount must be expressed in the smallest currency unit (cents for USD, for example), so a $10.00 charge would use an amount of 1000. This integer-based approach avoids floating-point precision issues that can cause incorrect charges.
Required Parameters
{
"amount": 1000,
"currency": "usd"
}
Amount must be in the smallest currency unit (cents for USD). A $10.00 charge uses amount: 1000.
Currency accepts ISO codes like "usd", "eur", or "gbp". When specifying currency, consider whether you need to support currency conversion or if you're charging in a single currency.
Optional Parameters
| Parameter | Purpose |
|---|---|
automatic_payment_methods.enabled | Let Stripe determine available payment methods |
payment_method_types | Restrict to specific payment methods |
confirm | Whether to immediately attempt charging |
payment_method | Specify the payment method to use |
description | Human-readable description for your records |
metadata | Custom data attached to the payment |
The automatic_payment_methods parameter, when set to enabled, tells Stripe to dynamically determine which payment methods to show based on your Stripe dashboard settings and the customer's context. This is the recommended approach for most integrations, as it simplifies configuration while remaining flexible.
You can specify a payment_method_types array to restrict which payment methods are available for a particular PaymentIntent. This is useful when certain products or services can only be paid for with specific methods. For example, you might allow credit cards and Apple Pay for digital goods while adding bank transfers for high-value items where customers prefer to pay via ACH.
The confirm parameter determines whether Stripe immediately attempts to charge the payment method when you create the PaymentIntent. Setting this to true is appropriate when you already have the payment method details collected, while leaving it false (the default) lets you create the PaymentIntent first and confirm later after additional validation or customer action.
Server-Side Creation Example
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
automatic_payment_methods: { enabled: true },
description: 'Digital product purchase',
metadata: {
order_id: '12345',
customer_email: '[email protected]'
}
});
Each payment method type has specific options that control its behavior. For card payments, you can specify whether to require 3D Secure authentication, which cards to accept (debit, credit, prepaid), and currency-specific BIN ranges. These configuration options are passed in the payment_method_options object when creating the PaymentIntent.
The PaymentIntent Object
Understanding the PaymentIntent object's structure helps you work with the API effectively. The id field provides a unique identifier for the PaymentIntent, formatted as "pi_XXXXXXXXXXXXXXXXXXXXXXXX". This ID is used in all subsequent API calls related to this specific payment attempt and should be stored in your database to correlate payments with orders or customers.
Core Fields
{
"id": "pi_3NiCSa2eZvKYlo2C0...",
"object": "payment_intent",
"amount": 1000,
"amount_received": 0,
"currency": "usd",
"status": "requires_payment_method",
"client_secret": "pi_xxx_secret_xxx",
"payment_method": null,
"created": 1704730000,
"metadata": {}
}
id - Unique identifier for this PaymentIntent. Store this in your database to track the payment through its lifecycle.
client_secret - Used for client-side confirmation; never expose in logs or client-side code bundles. This secret value allows Stripe's client-side libraries to securely communicate with Stripe's servers during payment confirmation. It encodes the PaymentIntent's current state and permissions without exposing your secret API key.
status - Current position in the lifecycle. Understanding status transitions is essential for building correct payment flows. When you first create a PaymentIntent, it typically starts in requires_payment_method status.
amount_received - Amount that has been successfully captured. Compare this to the original amount to determine if a partial capture occurred.
payment_method - The payment method attached to this PaymentIntent, if any. This field is populated after a payment method is attached.
created - Unix timestamp (seconds) indicating when the PaymentIntent was created. Use this for auditing and tracking purposes.
metadata - Custom key-value pairs you can attach to the PaymentIntent. Use this to store your internal identifiers like order IDs, customer references, or any business-specific data.
1{2 "id": "pi_3NiCSa2eZvKYlo2C0",3 "object": "payment_intent",4 "amount": 2000,5 "amount_received": 0,6 "currency": "usd",7 "status": "requires_payment_method",8 "client_secret": "pi_3NiCSa2eZvKYlo2C0_secret_abc123",9 "payment_method": null,10 "payment_method_types": ["card"],11 "created": 1704730000,12 "metadata": {13 "order_id": "12345"14 }15}Sources
- Stripe: The Payment Intents API - Official documentation covering the core Payment Intents API, lifecycle, and integration patterns
- Stripe: The PaymentIntent Object - Complete reference for the PaymentIntent object structure and properties
- Stripe: Payment Intents API Reference - Primary API reference for all Payment Intents operations
- Stripe: Payment Element Migration Guide - Best practices for migrating to Payment Element with Payment Intents