Back to all terms
Payment
Paymentsintermediate

Payment Intent Flow

The server-driven flow using Stripe's PaymentIntent API to create, confirm, and track a payment through its complete lifecycle from creation to settlement.

Also known as: PaymentIntent API, payment intent lifecycle, confirm payment flow

Description

The PaymentIntent flow is Stripe's recommended approach for handling one-time payments. A PaymentIntent object represents a single payment attempt and tracks the payment through every stage: creation, authentication (if required by 3D Secure or the issuing bank), confirmation, and capture. The flow begins server-side where you create a PaymentIntent with the amount, currency, and optional metadata, then pass its client_secret to the frontend for confirmation using Stripe.js.

On the client side, stripe.confirmCardPayment() or stripe.confirmPayment() handles the entire confirmation process, including any required authentication challenges like 3D Secure modals. The PaymentIntent transitions through statuses: requires_payment_method, requires_confirmation, requires_action (for 3D Secure), processing, and finally succeeded or requires_capture (for manual capture flows). Your backend should never assume a payment succeeded based on the client response alone; instead, rely on the payment_intent.succeeded webhook event as the authoritative confirmation.

Manual capture mode (capture_method: 'manual') is useful for workflows like hotel reservations or marketplace holds, where you authorize a charge upfront but only capture funds later. PaymentIntents support automatic retries via Stripe's Smart Retries and can be updated or canceled before confirmation. Each PaymentIntent should carry metadata linking it to your internal order or transaction ID for reconciliation.

Prompt Snippet

Create the PaymentIntent server-side with stripe.paymentIntents.create() specifying amount, currency, customer, metadata (including your internal order_id), and automatic_payment_methods enabled. Return only the client_secret to the frontend, never the full PaymentIntent object. On the client, confirm with stripe.confirmPayment() and handle the redirect-based flow for 3D Secure. Treat the payment as pending until you receive the payment_intent.succeeded webhook event; do not fulfill orders based solely on the client-side confirmation callback.

Tags

stripepayment-intentone-time-payment3d-securepayment-lifecycle