How Stripe Subscriptions Work in a Website or Web App
Stripe handles the payment, but your app still decides who gets premium access. Checkout starts the subscription, then a Stripe webhook tells your app when that subscription changes.
What happens when someone subscribes?
- Someone picks a paid plan on your pricing page.
- Your app sends them to Stripe Checkout, which is hosted by Stripe — your site never touches their card details.
- Stripe collects the payment and starts the subscription.
- Stripe sends the person back to your site. This is the part they see, and it is only a page.
- Separately, Stripe sends a webhook — a message straight to your server — saying what just happened.
- Your backend checks that the message really came from Stripe, stores the subscription status, and that stored status is what unlocks premium access. Every later renewal, failed payment or cancellation arrives the same way.
The main pieces
Your pricing page — A page on your own site listing the plans. Its only job is to find out which plan this person wants and then hand them over to Stripe — no card details are ever typed here.
Stripe Checkout — A payment page hosted and secured by Stripe. It takes the card, charges it, and starts the subscription. Because it is Stripe's page, card details never reach your servers — and because it is Stripe's, Stripe is the one that knows what happened.
Back in your app — After paying, Stripe sends the person back to a URL on your site. This is the confirmation they see — and it is the whole of what it is. It is a browser redirect, so it can be interrupted, refreshed or opened again later, which is exactly why nothing important should depend on it.
Stripe webhook event — A message Stripe sends straight to your server the moment something changes — this subscription started, renewed, failed or was cancelled. It arrives whether or not anyone has a browser open, and it is signed, so your app can prove it really came from Stripe.
Your webhook endpoint — A single URL on your backend that Stripe posts events to. It checks the signature, works out what the event means for this customer, and updates the subscription status you keep. It answers Stripe, not the browser.
Subscription status — What you store against each account: which plan they are on, whether it is active, and the Stripe ids that tie the two together. It is written only by the webhook path, which is what keeps it honest.
Premium access — The paid part of your product. Every time it loads it asks the same question — what does the stored subscription status say right now? — which is why access appears when someone subscribes and disappears on its own when they stop.
Why isn't the success page enough?
The redirect back from Checkout is a browser navigation, and browsers are not reliable messengers. The tab can be closed mid-redirect, the connection can drop, and the success URL can simply be visited again later — by anyone.
The webhook is a message from Stripe's servers to yours. It arrives whether or not the person is still looking, it can be checked to prove it really came from Stripe, and it keeps arriving: when the subscription renews, when a payment fails, when someone cancels.
So the success page is where you say thank you, and the webhook is where you decide what somebody is allowed to use.
Do you need subscriptions?
Subscriptions are for products people keep using. If someone pays you once, or does not pay you at all, a subscription adds billing states you would then have to keep in sync for no reason.
The moment access should continue — or stop — on its own, recurring billing starts earning its place.