TL;DR
Webhook to „odwrócone” wywołanie API: zamiast pytać serwis „czy coś się stało?”, serwis sam wysyła HTTP POST na Twój URL, gdy zdarzenie nastąpi. Dzięki temu nie musisz pollować i oszczędzasz zasoby. Idealne do płatności, notyfikacji, synchronizacji.
Dla kogo to jest
- Deweloperów integrujących zewnętrzne API (płatności, CRM, sklepy)
- Architektów systemów event-driven
- Osób budujących automatyzacje (np. Zapier, n8n, własny backend)
Fraza (SEO)
webhook co to, webhooks api, integracja webhook, event callback api
Webhook vs polling
| Polling | Webhook |
|---|---|
| Ty co X sekund pytasz: „są nowe dane?” | Serwis wysyła do Ciebie request, gdy coś się stanie |
| Więcej requestów, opóźnienia | Mniej requestów, niemal natychmiastowa reakcja |
| Prostsze po stronie serwisu | Wymaga endpointu po Twojej stronie |
Webhook = callback URL, który podajesz serwisowi. Gdy zdarzenie (np. płatność, zmiana statusu) – serwis robi POST na ten URL z payloadem.
Kiedy używać webhooków?
- ✅ Płatności (Stripe, Przelewy24 – „płatność potwierdzona”)
- ✅ Zmiany w zewnętrznym systemie (zamówienie, lead, ticket)
- ✅ Powiadomienia (email delivered, SMS sent)
- ✅ Synchronizacja (katalog produktów, ceny)
- ❌ Gdy nie masz publicznego URL (localhost) – w dev używa się tuneli (ngrok, cloudflared)
Jak to wygląda od strony odbiorcy?
1. Rejestracja URL
W panelu API (np. Stripe) podajesz: https://twoja-domena.pl/api/webhooks/stripe.
2. Odbieranie requestu
Serwis wysyła POST z body (JSON) i często nagłówkiem z sygnaturą (np. Stripe-Signature).
3. Weryfikacja
Zawsze weryfikuj sygnaturę (HMAC), żeby nikt nie podszył się pod serwis:
// Przykład: Stripe
const sig = req.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET);
4. Idempotencja
Ten sam event może przyjść 2× (retry). Używaj event.id (lub podobnego) i zapisuj przetworzone ID – przy duplikacie zwróć 200 i nic nie rób.
5. Odpowiedź 2xx szybko
Odpowiedz 200 w ciągu kilku sekund. Ciężkie przetwarzanie zrób w tle (kolejka, job). Serwis będzie retry’ował przy timeout lub 4xx/5xx.
Best practices
- HTTPS – obowiązkowo
- Signature verification – bez wyjątków
- Idempotency – obsługa retry
- Logowanie – raw body do logów (do debugowania), bez wrażliwych danych w plain text
- Timeout – serwis zwykle daje 5–30 s; jeśli dłużej – zwróć 200 i przetwórz asynchronicznie
FAQ
Co jeśli mój endpoint jest chwilowo niedostępny?
Serwis zwykle robi retry (np. z exponential backoff). Po kilku niepowodzeniach często jest panel „failed deliveries” lub logi po stronie serwisu.
Czy mogę użyć webhooków na localhost?
Nie bezpośrednio. Użyj tunelu: ngrok, cloudflared, localtunnel – wystawią publiczny URL na Twoje localhost.
Webhook a WebSocket?
Webhook = jeden request na jedno zdarzenie (stateless). WebSocket = stałe połączenie, strumień zdarzeń. Webhooks są prostsze do integracji z zewnętrznymi dostawcami.