Konfiguracja i zabezpieczanie webhooków

Konfiguracja webhooków w PSB: topiki, zabezpieczenie HMAC SHA256 i IP whitelisting.

Webhooki są podstawową metodą otrzymywania powiadomień w czasie rzeczywistym z PSB. Przy każdym istotnym zdarzeniu, otrzymanej fakturze, zmianie statusu, potwierdzeniu dostarczenia, PSB wysyła żądanie HTTP POST do endpointu z danymi zdarzenia.

Jak działają webhooki w PSB?

Rejestruje się webhook ("hook") w PSB z adresem URL i topikiem. PSB wysyła następnie wszystkie zdarzenia danego topiku na podany URL. Każde zdarzenie zawiera odpowiednie dane jako payload JSON.

Tworzenie webhooka

Brak interfejsu użytkownika: obecnie nie ma możliwości konfigurowania hooka przez interfejs użytkownika platformy. Hooki konfiguruje się przez API lub przez wsparcie eConnect. Interfejs samoobsługi dla hooków jest w planie rozwoju (planowany na Q4 2026) i będzie częścią Control (Platform 2.0): użytkownicy będą wtedy mogli sami tworzyć, edytować i usuwać hooki. Do tego czasu nie jest planowany artykuł krok po kroku dotyczący ręcznej konfiguracji hooków przez API.

Rejestracja hooka przez API:

POST /api/v1/hook

Najważniejsze elementy konfiguracji:

PoleOpisurlEndpoint HTTPS, na który PSB wysyła zdarzeniatopicTyp zdarzenia, które ma być nasłuchiwane (np. InvoiceReceived)secretTajny klucz do weryfikacji podpisu HMAC

Uwaga: unikaj szybkiego usuwania i ponownego tworzenia hooków dla tego samego partyId i topiku. Z powodu race conditions w przetwarzaniu zadań może to tymczasowo skutkować brakiem aktywnego hooka, co powoduje niedostarczenie zdarzeń. Po usunięciu hooka poczekaj chwilę przed utworzeniem nowego lub użyj aktualizacji zamiast usunięcia i ponownego utworzenia.

Dodawanie topiku do istniejącego hooka

Chcesz dodać dodatkowy topik (np. InvoiceReceived) do istniejącego hooka? Zaktualizuj istniejącą konfigurację webhooka przez standardowe API /hook, tak aby pożądany topik znajdował się w tablicy topics:

{
  "topics": ["InvoiceReceived"]
}

Zaktualizuj istniejący hook zamiast go usuwać i ponownie tworzyć. Usuwanie i ponowne tworzenie powoduje race condition, w której zdarzenia mogą tymczasowo nie być dostarczane (patrz ostrzeżenie powyżej).

Brak samoobsługi dla klientów nietech nicznych. Dodanie topiku do istniejącego hooka to zadanie techniczne: osoba wykonująca je musi wiedzieć, dokąd powinien trafić webhook (URL endpointu) i rozumieć, czym jest webhook. Klient nietech niczny zazwyczaj nie może zrobić tego samodzielnie. Zaangażuj osoby z wiedzą techniczną (dział IT klienta lub wsparcie eConnect).

Najczęściej używane topiki
TopikKiedyInvoiceReceivedOtrzymano fakturę zakupowąInvoiceSentFaktura sprzedażowa została pomyślnie wysłanaInvoiceSentErrorFaktura sprzedażowa nie mogła zostać dostarczonaInvoiceSentRetryRozpoczęto próbę ponownego wysłaniaInvoiceResponseReceivedOtrzymano Invoice Response (komunikaty statusowe)OrderReceivedOtrzymano zamówienie zakupowe
Message Level Status (MLS)

MLS (Message Level Status) to następca starszego MLR i dostarcza stronie wysyłającej informacje zwrotne o odebraniu i przetworzeniu dokumentu. MLS nie jest domyślnie włączony i musi zostać skonfigurowany dla każdej party przez capability reviews w konfiguracji SMP. Po włączeniu MLS PSB obsługuje go automatycznie: jako odbierający Service Provider, PSB wysyła wiadomość MLS z powrotem do nadawcy po odebraniu i dostarczeniu.

Gdy samodzielnie wysyłasz dokumenty przez PSB, otrzymujesz informacje zwrotne MLS od strony odbierającej jako zdarzenie webhook na topicu MessageLevelStatusReceived. Jako odbierający Service Provider, gdy PSB wysyła w Twoim imieniu MLS do wysyłającego SP, następuje odrębny webhook z topikiem MessageLevelStatusSent. Użyj tego topiku, aby monitorować, czy Twoje własne wysyłane odpowiedzi MLS są prawidłowo dostarczane.

MessageLevelStatusSent nie jest potwierdzeniem wysłanej faktury. Topic dotyczy MLS, który PSB wysyła w odpowiedzi na odebrany dokument (Ty, jako odbierający SP, odsyłasz powiadomienie o statusie do pierwotnego nadawcy), a nie e-faktury, którą samodzielnie wysłałeś. Przy wielu powiadomieniach MessageLevelStatusSent w połączeniu z małą liczbą wysłanych faktur: sprawdź, czy hook nasłuchuje na wildcardzie *sent zamiast konkretnie na InvoiceSent (zob. Topiki wildcard).

Zabezpieczanie webhooków za pomocą HMAC

PSB zabezpiecza wszystkie dostarczenia webhooków za pomocą podpisów HMAC SHA256. Przy każdym żądaniu PSB wysyła header:

X-EConnect-Signature: sha256={handtekening}
Implementacja weryfikacji

Aby zweryfikować podpis:

  1. Pobrać surowy payload JSON z żądania.
  2. Obliczyć hash HMAC SHA256 za pomocą tajnego klucza (tego samego, który podano przy tworzeniu hooka).
  3. Porównać obliczony hash z wartością w headerze X-EConnect-Signature.
  4. Jeśli się zgadzają, żądanie jest autentyczne.
Zapobieganie atakom replay

Należy również sprawdzać pole sentOn w payloadzie. Jeśli ten znacznik czasu jest starszy niż 5 minut, żądanie należy odrzucić. Zapobiega to atakom replay, w których przechwycone żądanie jest odtwarzane później.

Dodatkowe opcje zabezpieczeń

Oprócz weryfikacji HMAC, PSB oferuje dodatkowe warstwy bezpieczeństwa:

  • IP whitelisting: ograniczenie przychodzących żądań do IP produkcyjnych PSB (104.40.188.59 i 104.47.148.207)
  • Uwierzytelnianie OAuth dla webhooków: PSB może uwierzytelniać się w endpoincie za pomocą danych OAuth2
  • Mutual SSL: użycie certyfikatów klienta do wzajemnego uwierzytelniania TLS
Kolejność priorytetów

Gdy skonfigurowanych jest wiele hooków, PSB określa, który hook ma być użyty, na podstawie:

  1. Hooki na poziomie PartyId mają pierwszeństwo przed hookami na poziomie environment
  2. Specyficzne topiki mają pierwszeństwo przed wildcardami
  3. Gdy wiele hooków z filtrami odpowiada temu samemu topikowi: wygrywa najdłuższy filtr (liczony w znakach) -- na przykład filtr z dodatkową klauzulą && wygrywa z krótszym filtrem bez tej klauzuli. Zapobiega to podwójnemu dostarczeniu bez konieczności wzajemnego wykluczania się filtrów.
  4. Przy równym priorytecie: hook-id jako kryterium rozstrzygające
Topiki wildcard

Oprócz konkretnych topików można także używać wzorców wildcard, aby przechwytywać wiele typów zdarzeń za pomocą jednego hooka.

WzorzecDopasowujeSend*Wszystkie topiki z prefiksem Send*sent / *SentWszystkie topiki kończące się na Sent: InvoiceSent, InvoiceResponseSent, OrderSent, MessageLevelStatusSent, HookSent*ReceivedWszystkie zdarzenia odbioru (InvoiceReceived, OrderReceived, InvoiceResponseReceived itd.)Invoice*Wszystkie zdarzenia związane z fakturami

Send* nie jest tym samym co *sent. Send* dopasowuje topiki zaczynające się od Send; ten wzorzec nie występuje w standardowych topikach PSB. Aby przechwycić wszystkie zdarzenia "sent" (InvoiceSent, MessageLevelStatusSent, HookSent itd.), użyj *sent. InvoiceSentRetry i InvoiceSentError nie kończą się na Sent, więc nie są objęte sufiksem *sent.

Rozwiązywanie problemów

Poniżej przedstawiono typowe problemy z webhookami i sposoby ich rozwiązania.

ObjawPrzyczynaRozwiązanieWebhooki nie docierająEndpoint niedostępny (limit czasu 100 sek.)Wymagane HTTPS + ważny certyfikat SSL; wyłączyć ochronę CSRF na endpoincie webhookWebhook odrzucony jako niezabezpieczonyWalidacja X-EConnect-Signature kończy się niepowodzeniemSprawdzić obliczenie HMAC SHA256: payload × secret → ciąg szesnastkowy z prefiksem sha256=Atak powtarzania zablokowanyPole sentOn starsze niż 5 minutEndpoint przetwarza zbyt wolno lub zegar jest błędnie ustawiony"No such host is known" (błąd DNS)Nazwa hosta endpointu webhook nie jest już rozwiazywalna, np. po zmianie nazwy środowiska ERP lub wygaşnięciu rekordu DNSSprawdzić i przywrócić rekord DNS domeny endpointu; następnie pobrać brakujące zdarzenia przez endpoint batchHookSentError (ostateczny błąd)PSB próbował przez 5 dni bez odpowiedzi 2xxSprawdzić logi endpointu; monitorować topic HookSentError (patrz niżej); pobrać brakujące zdarzenia przez endpoint batchEndpoint offline / powtarzający się HTTP 404 (akceptacja lub produkcja)Endpoint klienta tymczasowo wyłączony (rozwój, konserwacja) lub faktycznie niedostępnyNajpierw sprawdzić, czy przerwa jest zamierzona i tymczasowa (patrz niżej); to nie jest incydent platformy eConnectStare faktury dostarczone ponownieAPI nie zwraca 2xx przy pierwszym odbiorzeEndpoint musi zawsze zwracać 2xx, także dla przetwarzania asynchronicznegoZduplikowane przetwarzanie przy ponowieniuBrak kontroli idempotencjiUżyć nagłówka X-EConnect-Delivery (unikalne UUID) do deduplikacjiFaktura odebrana, ale nigdzie nie dociera; brak widocznych błędów webhookPSB odebrał fakturę zakupową (topic InvoiceReceived), ale na tym topicu nie jest zarejestrowany żaden hook (nigdy nie skonfigurowany lub usunięty w międzyczasie)Najpierw sprawdzić konfigurację hooka: czy InvoiceReceived znajduje się w topicach? Bez hooka na tym topicu nie pojawia się żaden HookSentError, więc brak błędów nie dowodzi, że hook jest aktywnyWiele e-maili MessageLevelStatusSent przy niewielkiej liczbie wysłanych fakturMail-hook (mailto:) lub webhook HTTP nasłuchuje na wildcardzie *sent zamiast na InvoiceSentZmienić konfigurację topiku na InvoiceSent (ta sama zmiana na mail-hooku i na webhooku HTTP); zob. Topiki wildcard
Faktura odebrana, ale nigdzie niedostarczona (brak hooka InvoiceReceived)

PSB może odebrać fakturę zakupową bez przekazania jej do strony odbierającej. Topic InvoiceReceived oznacza, że PSB odebrał fakturę; bez hooka na tym topicu nic nie trafia do endpointu.

  • Brak błędów webhook nie dowodzi, że hook działa. HookSentError istnieje tylko wtedy, gdy skonfigurowany hook nie dostarcza.
  • Hook mógł zostać usunięty w międzyczasie. Wcześniejsze udane dostarczenie do tej samej strony/endpointu dowodzi, że hook istniał, a nie że nadal tam jest. Dlatego najpierw sprawdzić aktualną konfigurację hooka, zamiast traktować to jako pierwszą konfigurację.
  • Potwierdzenie odbioru po stronie nadawcy to nie to samo co dostarczenie do oprogramowania odbiorcy.

Napraw brakujący hook, aktualizując istniejący hook zamiast go usuwać i tworzyć ponownie.

Monitorowanie i odzyskiwanie po HookSentError

PSB wysyła zdarzenia webhook (np. InvoiceReceived po otrzymaniu e-faktury) do skonfigurowanego endpointu. Jeśli ten endpoint jest niedostępny — z powodu limitu czasu, błędu SSL lub błędu DNS jak No such host is known — PSB ponawia próby z wykładniczym wycofaniem przez 5 dni (limit czasu 100 sek. na próbę). Każda próba generuje zdarzenie HookSentRetry; po 5 dniach bez odpowiedzi 2xx emitowany jest HookSentError jako status końcowy i PSB kończy ponowne próby.

Konsekwencja: otrzymana e-faktura nie zostanie dostarczona do klienta, dopóki endpoint jest niedostępny, bez wiedzy klienta. Zalecane działania:

  • Skonfigurować monitorowanie: subskrybować hook (np. mail-hook) do topicu HookSentError, aby ostateczny błąd dostarczenia był aktywnie sygnalizowany zamiast pozostać niezauważony. Rozważyć również HookSentRetry do wczesnego wykrywania.
  • Naprawić przyczynę główną: w przypadku błędu DNS sprawdzić i przywrócić rekord DNS domeny endpointu; w przypadku limitów czasu sprawić, by endpoint odpowiadał szybciej (2xx w ciągu 100 sek., ciężkie przetwarzanie asynchronicznie).
  • Odzyskać brakujące zdarzenia: zdarzenia, które nie powiodły się podczas awarii, można pobrać przez endpoint batch. Pięciodniowe okno ponowień oznacza, że terminowe usunięcie usterki w tym okresie może jeszcze uzupełnić zaległości przez regularne dostarczanie.

Pierwsza linia: przerwa po stronie klienta vs. problem techniczny (akceptacja i produkcja)

HookSentError, powtarzający się HTTP 404 lub „endpoint jest offline"/„środowisko akceptacyjne jest wyłączone" może również wynikać z tego, że klient tymczasowo wyłącza endpoint akceptacyjny lub produkcyjny (rozwój, konserwacja). To nie jest incydent platformy eConnect.

  1. Potwierdzić objaw: HookSentError, endpoint offline lub HTTP 404 na endpoincie webhook skonfigurowanym przez klienta. Często widoczne jako dokładny tekst Response status code does not indicate success: 404 (Not Found) (zwykle HttpRequestException .NET przy wychodzącym żądaniu hooka). To jest 404 z własnego endpointu klienta (wyłączony lub błędna ścieżka), a nie błąd Peppol PartyId not found przy wysyłce (404 SMP), ani 404 zasobu REST z obsługi błędów API.
  2. Zapytać, czy przerwa jest zamierzona i tymczasowa (deweloperzy/klient).
  3. Potwierdzone tymczasowe → odnotować, brak dalszych działań po stronie eConnect, dopóki endpoint nie wróci do działania. Gdy endpoint ponownie zwraca 2xx, pominięte zdarzenia można pobrać przez endpoint batch.
  4. Niezamierzone lub nieznane → postępować według standardowego runbooka HookSentError powyżej (DNS/SSL/limit czasu, logi, monitorowanie, odzyskiwanie batch).
Najlepsze praktyki
  • Zawsze używać HTTPS dla endpointu webhookowego
  • Implementować idempotentne przetwarzanie: PSB może w rzadkich przypadkach dostarczyć zdarzenie więcej niż raz
  • Szybko zwracać kod statusu 2xx: PSB traktuje każdą odpowiedź inną niż 2xx jako błąd i ponowi próbę dostarczenia zdarzenia
  • Logować wszystkie otrzymane zdarzenia do celów debugowania i audytu
  • Używać systemu kolejkowego (queue) po swojej stronie, jeśli przetwarzanie zajmuje czas: najpierw potwierdzić odbiór, potem przetwarzać
Często zadawane pytania
Jak zweryfikować przychodzący webhook za pomocą HMAC SHA256?

Należy wziąć surowe ciało JSON żądania, obliczyć hash HMAC SHA256 przy użyciu sekretu podanego podczas tworzenia hooka i porównać go z wartością w nagłówku X-EConnect-Signature (po prefiksie sha256=). Jeśli wartości się zgadzają, oznacza to, że żądanie pochodzi z PSB i nie zostało zmodyfikowane w trakcie przesyłania.

Dlaczego należy sprawdzać pole sentOn w payloadzie?

Należy sprawdzić, czy sentOn nie jest starszy niż 5 minut. Jeśli znacznik czasu jest zbyt stary, żądanie należy odrzucić. Zapobiega to atakom typu replay, w których wcześniej przechwycone żądanie jest ponownie przesyłane, nawet jeśli podpis jest technicznie poprawny.

Jak uniknąć problemów z idempotentnym przetwarzaniem i ponowieniami?

Należy zaimplementować idempotentne przetwarzanie po swojej stronie, ponieważ PSB może w rzadkich przypadkach dostarczyć zdarzenie więcej niż raz. Ponadto należy szybko zwrócić kod statusu HTTP 2xx: każda inna odpowiedź jest traktowana jako błąd i powoduje ponowienie. W przypadku złożonego przetwarzania warto najpierw potwierdzić odbiór, a następnie przetworzyć dane za pomocą kolejki.

Co oznacza HookSentError lub endpoint, który wygląda na offline w akceptacji lub produkcji?

HookSentError pojawia się po tym, jak PSB próbował przez 5 dni bez odpowiedzi 2xx. Powtarzający się HTTP 404 lub komunikat, że endpoint jest offline, często wynika z tego, że klient tymczasowo wyłącza endpoint akceptacyjny lub produkcyjny (rozwój, konserwacja) - to nie jest incydent platformy eConnect. Najpierw potwierdzić, czy przerwa jest zamierzona i tymczasowa; jeśli tak, żadne dalsze działanie nie jest potrzebne, dopóki endpoint nie stanie się ponownie dostępny. Pominięte zdarzenia można nadal pobrać przez endpoint batch w ciągu pięciodniowego okna ponowień.

Czemu otrzymuję wiele e-maili MessageLevelStatusSent, mimo że wysyłam mało faktur?

To oczekiwane zachowanie, jeśli mail-hook (mailto:) lub webhook HTTP nasłuchuje na wildcardzie *sent zamiast konkretnie na InvoiceSent. MessageLevelStatusSent nie jest potwierdzeniem samodzielnie wysłanej faktury, lecz MLS, który PSB wysyła w odpowiedzi na odebrany dokument, i podlega wzorcowi *sent razem z InvoiceSent, OrderSent i HookSent. Jeśli chcesz otrzymywać powiadomienia tylko przy wysyłaniu faktur, zmień konfigurację topiku na InvoiceSent. InvoiceSentRetry i InvoiceSentError nie kończą się na Sent, więc nie są objęte *sent.


Wolą Państwo pobierać dokumenty hurtowo? Batch hook.

Zobacz endpointy webhooków

Powiązane