Przegląd

Webhooki

Webhooki automatycznie informują Twój serwer o zmianach stanu faktury, dzięki czemu nie musisz cyklicznie sprawdzać jej statusu. Gdy wystąpi obsługiwane zdarzenie, system tworzy powiadomienie i wysyła je do wszystkich aktywnych endpointów webhooków w organizacji, które subskrybują dany typ zdarzenia.

Historię prób i wyniki wysyłki sprawdzisz w Rejestrach doręczeń.

Jak działa doręczanie

Dla każdego zdarzenia system tworzy osobne doręczenie do każdego aktywnego endpointu webhooka, który subskrybuje dany typ zdarzenia. Doręczanie odbywa się asynchronicznie, a problemy z jednym endpointem nie blokują wysyłki do pozostałych organizacji.

Przed każdą próbą system ponownie sprawdza adres endpointu. Jeśli endpoint został wyłączony lub usunięty, doręczenie otrzymuje status endpoint_disabled i żądanie nie jest wysyłane. Jeśli adres zostanie uznany za niebezpieczny, próba kończy się statusem failed, również bez wykonania żądania HTTP.

Nieudane doręczenia mogą być ponawiane, dlatego to samo zdarzenie może zostać wysłane więcej niż raz. Odbiorca powinien deduplikować zdarzenia na podstawie event.id.

Format żądania

Każde doręczenie to żądanie HTTP POST z Content-Type: application/json. Treścią jest surowy JSON zdarzenia Event. Każdemu żądaniu towarzyszą trzy nagłówki:

Nagłówki żądania webhooka
Ksef-Event-Id: evt_V3sGDb5VXxLxzGzvYVw0PwKsef-Timestamp: 2026-06-01T10:18:30ZKsef-Signature: v1=<lowercase-hex-hmac>

Ksef-Event-Id odzwierciedla id zdarzenia, Ksef-Timestamp to znacznik czasu podpisu, a Ksef-Signature niesie podpis HMAC opisany poniżej.

Nagłówek Ksef-Signature

Pozwala zweryfikować, że webhook pochodzi z emfakt i jego treść nie została zmieniona. Podpis jest obliczany algorytmem HMAC-SHA256 na podstawie ciągu:

Text
Ksef-Timestamp + "." + surowa treść żądania

Do obliczenia podpisu używany jest sekret endpointu whsec_.... Wartość nagłówka ma format:

Text
v1=<podpis HMAC zapisany małymi znakami szesnastkowymi>

Podczas weryfikacji treść żądania powinna zostać użyta dokładnie w takiej postaci, w jakiej została odebrana. Nie powinna być parsowana ani nie serializowana ponownie, ponieważ nawet niewielka zmiana treści spowoduje niezgodność podpisu.

Do porównania podpisu z nagłówkiem użyj funkcji o stałym czasie działania (na przykład crypto.timingSafeEqual) zamiast zwykłego porównania ciągów.

Weryfikacja podpisu (przykład)
import crypto from 'node:crypto'// rawBody musi być dokładnymi otrzymanymi bajtami, przed parsowaniem JSON.function isValidSignature(rawBody, headers, signingSecret) {  const timestamp = headers['ksef-timestamp']  const received = headers['ksef-signature'] // "v1=<lowercase-hex-hmac>"  const expected =    'v1=' +    crypto      .createHmac('sha256', signingSecret)      .update(`${timestamp}.${rawBody}`)      .digest('hex')  const a = Buffer.from(received)  const b = Buffer.from(expected)  return a.length === b.length && crypto.timingSafeEqual(a, b)}

Ponowienia doręczeń

Doręczanie nie podąża za przekierowaniami, każdą odpowiedź 3xx traktujemy jako nieudane doręczenie, bo podpisanego payloadu nie wolno przekazywać do nieoczekiwanego hosta. Błędy przejściowe typu 429, 5xx, timeout, awaria połączenia lub nieoczekiwany błąd po stronie wysyłającego powodują zaplanowanie kolejnej próby z prostym backoffem. Błędy nieponawialne typu 3xx albo 4xx inne niż 429 kończą doręczenie niepowodzeniem. Czas kolejnych prób nie jest gwarantowany żadnym harmonogram.

Ponowienia mogą tworzyć duplikaty doręczeń, dlatego zawsze deduplikuj po event.id natomiast nigdy po identyfikatorze doręczenia.

Nie ma publicznego endpointu do listowania zdarzeń ani API do odtwarzania zdarzeń czy testowej wysyłki webhooka. Jedyne sposoby obserwowania doręczeń to Twój własny endpoint oraz oczyszczone Rejestry doręczeń.