Websites · Glossary
What is a Stripe webhook?
A Stripe webhook is an HTTPS request Stripe sends to an address on your site whenever something happens in your account, such as a completed checkout, a refund or a failed subscription payment. Each request carries an event in JSON and a Stripe-Signature header, so your site can confirm the message came from Stripe before it marks an order paid.
A webhook is how a site learns the truth about a payment. The customer's browser can close, lose signal or be faked, but Stripe's signed event arrives either way, and the site acts on that.
Nuwan Madhusanka · Co-founder
4 min read · Published
| Event | When Stripe sends it | What the site usually does |
|---|---|---|
| checkout.session.completed | A customer finishes a Checkout Session | Mark the order paid, or wait for async payment if it is not yet paid |
| checkout.session.async_payment_succeeded | A delayed payment method clears | Mark the order paid and start fulfilment |
| charge.refunded | A charge is refunded in full or part | Mark the order refunded and adjust stock |
| customer.subscription.updated | A subscription changes plan or status | Update the member's tier or access |
| invoice.payment_failed | A subscription renewal fails | Flag the member and prompt them to update their card |
What a webhook is
A webhook turns the usual direction of an API around. Instead of your site asking Stripe for news, Stripe calls your site. You register an endpoint, an HTTPS address on your server or function, and choose which event types to receive. When one happens, Stripe sends a POST request with a JSON event object describing it. Stripe signs each request with a secret only you and Stripe know, the endpoint's signing secret starting whsec_, and puts the signature in the Stripe-Signature header.
How a site handles one
The endpoint reads the raw request body, verifies the signature with the signing secret and rejects anything that fails, which stops anyone faking a paid order by calling the address themselves. It then reads the event type and acts: for checkout.session.completed it looks up the order by the session's id or metadata and marks it paid. It returns a 2xx status quickly, before slow work such as emails, because Stripe treats slow or failed responses as undelivered. In live mode Stripe retries failed deliveries with backoff for up to three days, so the handler must be idempotent: processing the same event twice must not ship two parcels.
When it matters
Any site that takes money online needs one. The page a customer lands on after paying is not proof of payment; the customer might close the tab first, or a delayed payment method such as a bank debit might clear days later. Subscriptions need webhooks even more, because renewals, failed payments and cancellations happen while nobody is on the site. Refunds made in the Stripe dashboard also only reach the site's order records through a webhook.
Common mistakes
Marking orders paid from the success page's URL instead of the webhook. Parsing the JSON before verifying the signature, so the raw body no longer matches and every check fails. Skipping verification altogether. Doing slow work before responding, so Stripe times out and retries. Not handling duplicates. Listening for every event type when four or five are needed. Using the test mode signing secret in live mode. And forgetting that events can arrive out of order, so a refund might be processed before the payment it refers to.
Where it shows up in OneCraft
OneCraft sites take payments through a payments broker: Stripe Checkout as a direct charge on the owner's own connected Stripe account, for one off orders, subscriptions from a plans table and the Stripe billing portal. Prices are read from the site's own database, never from the browser, and a webhook marks each order paid or refunded. Stripe is connected in account Settings, Payments. The platform fee is 2% on Starter, 1% on Pro and 0.5% on Pro+, with Stripe's fees on top, and the free plan cannot take payments.
Questions people ask
What is the difference between a webhook and an API call?
An API call is your site asking Stripe for something, such as creating a Checkout Session. A webhook is Stripe telling your site that something happened, without being asked. Most payment flows use both: an API call to start the payment and a webhook to learn the outcome.
How do I test Stripe webhooks?
Use test mode and the Stripe CLI, which can forward events to a local address and trigger sample events such as checkout.session.completed. The dashboard's event destination page shows every delivery attempt, its response code and the request body, which helps when an endpoint returns errors.
What happens if my webhook endpoint is down?
Stripe keeps the event and retries delivery. In live mode it retries with increasing gaps for up to three days, and you can resend events manually from the dashboard. Orders made during an outage stay unpaid on your site until a delivery succeeds, so watch for failed deliveries.
Is the signing secret the same as my API key?
No. The secret API key lets your server call Stripe. The webhook signing secret, starting whsec_, only verifies that incoming requests came from Stripe, and each endpoint has its own. Keep both on the server, never in browser code, and rotate them if they are ever exposed.
Do I need a webhook if I use Stripe Payment Links?
Only if your site needs to react to payments, such as marking orders paid or granting access. Payment Links work without any code, and Stripe emails receipts, but your site will not know someone paid unless it receives the event or you check the dashboard by hand.
Make one with websites
The button opens the generator with this use case already described. Change the wording to match your own.
Create a website with OneCraftRelated questions
- What is Stripe Checkout?What is Stripe Checkout? Stripe's prebuilt payment page created per purchase, how a Checkout Session works, and how it compares with Payment Links.
- What is a platform fee on Stripe Connect?What is a platform fee on Stripe Connect? The share a platform keeps from a connected account's payment, and who pays Stripe's fees on each kind of charge.
- What is a billing portal?What is a billing portal? A hosted page where a subscriber updates their card, changes plan, downloads invoices or cancels, without emailing the business.
- What is an admin role?What is an admin role? A role that grants management rights on a site or app, enforced by the database rather than the menu, with member and admin compared.
Written and checked by the OneCraft team. Last checked .