PaymentIntent

A Stripe PaymentIntent tracks one payment through every attempt, 3D Secure check, and bank delay until it succeeds or is canceled. See its statuses and events.

Updated October 1, 2026

A PaymentIntent is the Stripe object for one payment you're trying to collect. It follows that payment through every attempt until it succeeds or is canceled. Its ID starts with pi_. Checkout, Payment Links, and invoice payments all create PaymentIntents, so most payments on your account have one even if you've never called the API.

PaymentIntent statuses

A PaymentIntent moves through a small set of statuses.

  • requires_payment_method means there's no usable payment method yet. A PaymentIntent also returns here after a failed attempt, so the customer can try again.
  • requires_confirmation means payment details are attached and the payment is ready to confirm. Most integrations skip this status.
  • requires_action means the customer has to do something, usually a 3D Secure check with their bank.
  • processing means the payment is in flight. Card payments rarely stay here long, and bank debits can take a few days.
  • requires_capture only appears when you authorize now and capture the money later.
  • succeeded means the payment is complete and you can fulfill the order.
  • canceled means the PaymentIntent can't be used again. It can't be undone.

Each change fires a webhook event. The events are payment_intent.created, payment_intent.requires_action, payment_intent.processing, payment_intent.succeeded, payment_intent.payment_failed, and payment_intent.canceled.

The fields you'll read most:

  • amount and currency, what you asked for.
  • amount_received, what the PaymentIntent collected.
  • customer, who is paying, when a Customer is attached.
  • latest_charge, the Charge from the most recent attempt.
  • last_payment_error, the decline code and message from the last failure.
  • metadata, your own order or account IDs.

Why Stripe uses PaymentIntents instead of charges

One payment can take several attempts. The first card is declined, the customer tries a second, the bank asks for 3D Secure, and the next attempt succeeds. Each attempt creates a Charge, but there is one PaymentIntent, and it reaches succeeded once. That makes payment_intent.succeeded the reliable signal that you got paid. It fires once per completed payment however many attempts it took.

For the same reason, payment_intent.payment_failed isn't always a lost sale. The PaymentIntent drops back to requires_payment_method and can still succeed on the next attempt. For subscription renewals, Stripe's Smart Retries keep trying until the invoice is paid or the retry window ends.

When a PaymentIntent pays an invoice, you get events at both layers. payment_intent.succeeded arrives with invoice.paid, and payment_intent.payment_failed arrives with invoice.payment_failed. Pick one layer per workflow so one payment doesn't trigger the same action twice.

PaymentIntent vs SetupIntent

A PaymentIntent collects money now. A SetupIntent saves and authenticates a payment method for later without charging it. Use a SetupIntent when you want a card on file before a trial ends or before a usage bill, and a PaymentIntent when the customer pays today.

What each team should watch

  • Engineering fulfills orders from a payment_intent.succeeded webhook, not from the browser. Stripe warns that customers can close the page after paying and before client-side code runs.
  • Support checks the status when a customer says "I paid." processing means a bank payment is still clearing. requires_action usually means the customer abandoned an authentication step.
  • Finance reads amount_received for what was collected. The balance transaction on the latest Charge shows the Stripe fee and the net amount.
  • Founders look for patterns. Many payment_intent.payment_failed events with the same decline code across different customers can mean a checkout bug or card testing.

PaymentIntents and ChargeBell

ChargeBell's successful payment alert is built on payment_intent.succeeded. It posts the amount, the customer, what you keep after Stripe fees, and whether this is a first-time or returning customer, in a channel like #payments or #wins. If small payments are noise, set a minimum amount and let the daily digest cover the routine total. payment_intent.payment_failed drives the critical failed payment alert, which includes the decline reason. ChargeBell reads these events through a read-only connection, so it can never create, confirm, or refund a PaymentIntent. For what a useful payment message should contain, see what should a payment alert include.

Get alerted in Slack

Stripe events: payment_intent.created, payment_intent.requires_action, payment_intent.processing, payment_intent.succeeded, payment_intent.payment_failed, payment_intent.canceled

# payments

ChargeBellAPP

🔔 You got paid: $249.00

Jamie at Northloop

Gross $249.00 · Stripe fee −$7.52 · You keep $241.48

Visa ••4242

Related terms