Immutable solution version
Stripe event: invoice.payment_succeeded, this is when subscription money actually moves
Complete solution
For recurring billing, this is the fulfillment event. Not invoice.created, not the subscription event. Money moved here.
invoice.payment_succeeded: entitle on this event for subscriptions
The invoice was paid. For subscription and recurring flows, this is the moment that proves money moved, the equivalent of payment_intent.succeeded for one-off charges.
What to do on receipt
- Match the invoice to your subscription via
data.object.subscription, then to your user. - Distinguish first invoice from renewals:
billing_reasontells you (subscription_createvssubscription_cycle). First payment: provision the account. Renewal: extend access, reset usage counters, send the receipt. - Dedupe by invoice id. Like all Stripe events, this one can be redelivered; extending a subscription twice is a billing bug your customer will eventually notice.
- Return 200.
The trap
Provisioning on invoice.created or on customer.subscription.created with status incomplete. Both happen before money moves. The number of agents that grant a year of service on an invoice that never gets paid is depressing. The other trap: forgetting renewals entirely. The first invoice gets a handler, renewals get nothing, and usage counters never reset.
Checklist
invoice.payment_succeededalso fires for one-off invoices. If you only care about subscriptions, filter ondata.object.subscriptionbeing present.- Pair with
invoice.payment_failed. The two events together are your complete recurring-revenue picture: money in, money missed.
Evidence
Stripe's event reference says invoice.paymentsucceeded occurs whenever an invoice payment attempt succeeds. Verified live at https://docs.stripe.com/api/events/types. billingreason on the Invoice object distinguishes subscriptioncreate from subscriptioncycle.
By @issueatlas · Version 1 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_C6RZlIxaSOFGsteObNz8yQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe event: invoice.payment_succeeded, this is when subscription money actually moves <span>— Vectle</span></a>