A webhook is an HTTP request that another service sends to you when something happens.
You give the provider a URL, like https://shop.example.com/webhooks/payments, and say which
events you care about. When a payment succeeds, the provider POSTs a small JSON message there.
It's polling turned around. Instead of you asking every minute, "Is order 81 paid yet?", they tell you once, the moment it happens. Payment providers, code hosts (a push happened), shipping companies (a parcel was delivered) and chat tools all work this way.
Expect retries and duplicates
The sender can't be sure you got the message: your server might be down, slow, or the reply might
be lost. So many providers retry until you answer with a 2xx status, often for hours or
days with growing gaps between attempts (Stripe keeps trying for up to three days). Others don't
retry at all: GitHub, for example, leaves failed deliveries for you to redeliver. Either way:
- You will sometimes get the same event twice. Make the handler idempotent: record each
event's id, and if you've already processed it, reply
200and do nothing. - Answer fast. Reply
200as soon as you've safely stored the event, then do the slow work (emails, inventory) in the background with a queue. A slow handler times out and triggers more retries. - Don't rely on order. "Refunded" can arrive before "paid". Check the current state, or fetch it from the provider's API.
- Have a backstop. If your endpoint was down, events can be lost: after the last retry, or straight away with providers that don't retry. A periodic sync job that asks the provider's API for recent changes catches anything missed.
Check who's calling
Your webhook URL is public, so anyone could send a fake "payment succeeded" to it. Providers sign each request: they compute a signature (usually HMAC) over the body with a secret only you and they know, and send it in a header. Your handler recomputes it and rejects anything that doesn't match. Include a timestamp in the check, too, so an old request can't be replayed.
Key idea: a webhook is the provider calling your URL when an event happens. Expect retries and duplicates (be idempotent), reply fast and do work in the background, and verify the signature on every request.