Time: about 25 minutes · Level: intermediate · You’ll build: a webhook receiver that rejects forged requests, handles retries safely, and records what it processed.
Scenario
When an invoice is paid, your system should activate the customer’s paid features. Webhooks deliver that event, but endpoints get retried, arrive out of order, and can be spoofed. This tutorial builds a receiver that handles all three.Prerequisites
- A public HTTPS endpoint, or a tunnel such as
ngrokfor local testing. - A signed-in user session to register the webhook. Webhook management requires a user session, not an API key.
- Node.js 20 or later.
1
Register the endpoint
Subscribe to the two events this tutorial handles. Replace the URL with your endpoint.Save the secret that starts with
whsec_. It’s needed to verify every delivery, and it’s shown in this response.2
Verify the signature on the raw body
Parsing the JSON before you verify changes the bytes, so verify first. Using Express:Return
401 for a bad signature and 400 for missing headers. Don’t return 200 for an unverified request.3
Process each event exactly once
Orvlin retries a delivery until it gets a
2xx, so the same event can arrive more than once. Record each event ID the first time you process it, and skip repeats.4
Test a delivery locally
Send yourself a signed request with the same method Orvlin uses. The sample below signs a body with the secret from step 1:You should get
200. Send the exact same request again: it should also return 200, and the handler should log nothing new. Change one character of the body and send it: you should get 401.5
Check deliveries and recover from failures
Orvlin records each delivery attempt. If your endpoint was down, look at the failures, fix the endpoint, and let Orvlin retry:Orvlin retries failed deliveries with increasing delays for about a day. Use the
test endpoint to check the endpoint after a fix:Production checklist
- Verify every request before you parse it.
- Compare signatures with a constant-time function.
- Reject timestamps older than a few minutes.
- Make handlers idempotent, keyed on the event
id. - Respond quickly, and do slow work from a queue.
- Rotate the secret if it leaks, then update the endpoint.
Next steps
Webhooks reference
Every event, header, and management endpoint.
Reliability
How Orvlin retries, what it guarantees, and what it doesn’t.