What is a webhook and why is it everywhere
Published on 2026-09-12 by frfrand
En lugar de preguntar cada cinco minutos, el otro servicio te avisa. Cómo funciona, por qué siempre hay que verificar la firma, y los tres detalles que rompen integraciones en producción.

Without webhooks, the only way to find out about something happening in another service is to ask: every minute, every five minutes, every hour. That's called polling and it has two obvious problems: you waste calls to listen to "nothing happened," and you find out late.
A webhook reverses the direction. You register an address of yours, and when something happens, the other service sends you an HTTP request.
It's the same as leaving your phone number instead of calling every half hour to ask if there's news.
How it looks in concrete terms
You register a URL. When the event occurs, something like this arrives:
POST /webhooks/pagos HTTP/1.1 X-Signature: sha256=8f3a... Content-Type: application/json
{"evento":"pago.aprobado","id":"pay_123","monto":4500}
Your server receives that, verifies that it's legitimate, does what's appropriate, and responds 200.
Verifying the signature is not optional
That address is public: anyone who knows it can send data to it. Without verification, anyone could tell your system "this payment was approved."
That's why serious services sign each shipment with a shared secret. Your job is to recalculate that signature on the received body and compare it.
Three details that are often overlooked:
- You must sign over the raw body, not over the JSON already parsed and re-serialized. One space difference and the signature does not match.
- The comparison must be constant-time, not a simple equality, to avoid leaking information through response time.
- Many services include a timestamp: it is advisable to reject old submissions, so no one can resend a captured one.
The three details that break integrations
1. Respond quickly. The sender waits a few seconds and, if you do not respond, considers it failed and retries. If your handler takes thirty seconds processing, you will receive the same event several times.
The correct way: validate, save the event in a queue, respond 200, and process later. The webhook confirms receipt, not the work.
2. Events repeat. Due to retries, network failures, manual resends. Your handler must be idempotent: receiving "payment approved" twice cannot charge twice.
The usual way is to save the event identifier and discard duplicates.
3. Order is not guaranteed. You may receive "order updated" before "order created". If your logic assumes sequence, it will fail in strange and intermittent ways. When order matters, you must rely on timestamps or current state, not on arrival order.
How to test them
The classic problem: the service needs a public address and you are developing on your machine.
Two paths: a tunnel that temporarily publishes your local port, or saving the events that arrive at a test environment and replaying them locally. The second is more boring and much more reliable for debugging.
And the tip that saves the most time: almost all services keep the delivery history with the body sent, the response code, and the response. Before touching code, check that history. Half the time the problem is right there in plain sight: a 404 due to a mistyped route, or a 500 that says exactly what failed.
Where they appear
Almost everywhere: GitHub when you push, payment platforms when a charge is approved, WhatsApp when a message arrives, forms when someone submits them.
In ArduMaker it is the mechanism that triggers deployments: GitHub notifies, the server validates the signature and executes the build.