Skip to content

Webhook Is the Only Thing That Knows

“Webhook is the only thing that knows” is a payment architecture rule: grant paid access only from a verified provider-to-server webhook event, not from a browser redirect. The redirect is user experience; the webhook is the durable signal your backend can authenticate, record, retry, and use to change product state.

The problem is that checkout crosses an untrusted, failure-prone boundary: the customer’s browser. A success page can be skipped, refreshed, blocked, spoofed, or never reached because the tab was closed after payment. If access is granted from that page view, fulfilment depends on a fragile client-side journey rather than on the actual payment outcome. That creates both lost purchases and security holes.

The safer design treats the payment provider as the authority for payment events and your backend as the authority for product state. Your server creates the checkout session or payment intent, the browser completes the payment flow, and the provider later calls your webhook endpoint. Your server verifies the event signature, reads the event type and identifiers, updates the database idempotently, and provisions the entitlement, subscription, download, credits, or upgrade.

The trade-off is that the user interface becomes eventually consistent with payment truth. The success page may need to show a pending state while the webhook arrives, and your backend must handle retries, duplicate deliveries, out-of-order events, delayed confirmation, failures, and disputes. This adds database design and operational work, but it moves correctness to a place that can be authenticated and recovered.

Engineers meet this rule when integrating Stripe or any similar payment provider. The common mistake is assuming the success URL proves payment. It does not; it proves only that a browser was redirected. In practice, you store provider identifiers, verify webhook signatures, make fulfilment idempotent, and let customer-facing pages read the resulting database state rather than deciding access themselves.

Common questions

Why is the success URL not enough?
A success URL is controlled by browser navigation, not by your payment ledger. The customer may close the tab, lose connectivity, or have the redirect blocked. An attacker may also try to visit similar routes directly. It is useful for showing a receipt or pending screen, but it is not trustworthy enough to grant access.
What does idempotent webhook handling mean here?
It means processing the same payment event more than once must not grant the product more than once or corrupt state. Store the provider’s event or payment identifier, check whether it has already been applied, and make the database change in a way that is safe under retries and concurrent deliveries.
Should the webhook always provision immediately?
It depends on the event and the product. A simple paid download may be unlocked when the provider confirms successful payment. A subscription may require checking the subscription status, invoice state, or trial rules. The key principle is not instant fulfilment; it is that fulfilment follows verified server-side payment state.