Most Stripe tutorials stop at "create a Checkout Session and listen for checkout.session.completed." That gets you a demo. It does not get you a billing system you can trust with real European customers, real SEPA debits, real VAT and real cancellations.
This guide collects the configuration decisions that actually bite once money flows. It is written from the perspective of an EU-incorporated SaaS selling subscriptions to both consumers and businesses, across EUR and USD. Every code sample is generic. Adapt the IDs and plan names to your own account.
The running theme: your Stripe Dashboard config and your webhook code are two halves of one system. When they drift apart, customers pay and get nothing, or cancel and keep access. Most of the work below is keeping the two halves in sync.
1. Treat the webhook as your source of truth
The browser redirect after Checkout is a UI convenience. It is not proof that money moved. A user can close the tab, lose connection or pay with a method that settles days later. The only reliable signal that a subscription exists and is paid is a verified webhook event.






