Skip to content
Money in Your Database

04.02 · Concept · Free

The Webhook Is the Only Thing That Knows

Provision access from a verified server-side event rather than from a browser redirect, and say why a customer who closes the tab must still get what they paid for.

The player loads only when you ask for it, so this page stays fast.

Curated for this lesson

Money in Your Database

How to secure your Stripe Integration: API keys, webhooks & zero-trust best practices

Directly targets secure Stripe integrations and webhooks, matching the server-side trust boundary this lesson needs.

A payment success page is not proof of payment. Access should be granted only after your backend receives and verifies the provider’s webhook, then records the entitlement idempotently. Browser redirects are useful for user experience, but they cannot be the authority for subscriptions, downloads, credits, or upgrades.

What this lesson answers

  • should payment access depend on success url
  • why use webhooks for payment fulfilment
  • how to handle closed tab after payment

Notes

A payment redirect is a user experience signal, not a business truth. The browser can be closed, lose network, be blocked by an extension, or be deliberately manipulated. If your system grants access because a customer landed on a success page, you are trusting the least reliable part of the flow: the customer’s device and session.

The reliable mental model is that the payment provider is the source of payment events, and your backend is the place where those events become durable product state. The checkout page may say “thanks,” but the webhook says “this payment actually succeeded.” Your server should receive the verified event, check that it came from the payment provider, make the database change idempotently, and then provision the entitlement, subscription, download, credits, or account upgrade.

The common misconception is “the success URL means the payment worked.” It does not. It means the customer’s browser was sent somewhere after an attempted checkout flow. A real payment system must handle asynchronous reality: delayed confirmations, abandoned tabs, retries, duplicate events, failed payments, disputes, and network partitions. Webhooks exist because money and fulfillment must survive all of that.

After this lesson, you should be able to describe a safe payment architecture: create the payment intent or checkout session server-side, let the browser complete the hosted or embedded payment flow, but only update access from a verified webhook event. You should also be able to explain to a product manager why a customer who closes the tab after paying must still receive what they bought: the purchase is confirmed by the provider-to-server event, not by a page view.

Common questions

Why should a webhook grant access instead of the success page?
The success page only proves that a browser reached a URL after checkout. It does not prove the payment settled, and it can be interrupted or manipulated. A verified webhook is sent from the payment provider to your backend, so it is the correct point to update durable product state.
What happens if the customer pays and then closes the tab?
They should still receive what they bought. Fulfilment must not depend on the customer keeping a browser session alive. Once the payment provider confirms the event to your server, your system should record the purchase and provision the account, subscription, download, credits, or other entitlement.
What does idempotent payment provisioning mean?
It means processing the same payment event more than once must not grant duplicate access or corrupt state. Webhook delivery can be retried, and events can arrive more than once. Your backend should recognise the event or payment identity, apply the database change once, and safely ignore repeats.