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_methodmeans there's no usable payment method yet. A PaymentIntent also returns here after a failed attempt, so the customer can try again.requires_confirmationmeans payment details are attached and the payment is ready to confirm. Most integrations skip this status.requires_actionmeans the customer has to do something, usually a 3D Secure check with their bank.processingmeans the payment is in flight. Card payments rarely stay here long, and bank debits can take a few days.requires_captureonly appears when you authorize now and capture the money later.succeededmeans the payment is complete and you can fulfill the order.canceledmeans 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:
amountandcurrency, 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.succeededwebhook, 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."
processingmeans a bank payment is still clearing.requires_actionusually means the customer abandoned an authentication step. - Finance reads
amount_receivedfor 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_failedevents 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
ChargeBellAPP
🔔 You got paid: $249.00
Jamie at Northloop
Gross $249.00 · Stripe fee −$7.52 · You keep $241.48
Visa ••4242