Obsługa błędów: kody HTTP, ponawianie i solidna integracja

Kody statusu HTTP, odpowiedzi błędów i logika ponawiania w PSB API: jak zbudować solidną integrację.

Każda integracja z API prędzej czy później napotka błędy. Awaria sieci, nieosiągalny serwer, nieprawidłowo sformatowany dokument: to normalna część pracy z API. PSB API komunikuje błędy za pomocą standardowych kodów statusu HTTP i ustrukturyzowanych odpowiedzi JSON. Ponadto PSB posiada wbudowany mechanizm ponawiania, który automatycznie obsługuje tymczasowe błędy podczas dostarczania dokumentów.

W tym artykule dowiesz się, jakie kody statusu zwraca PSB, jak interpretować odpowiedzi błędów, kiedy można bezpiecznie ponowić żądanie i jak działa automatyczny mechanizm ponawiania PSB.

Kody statusu HTTP

PSB API używa standardowych kodów statusu HTTP do wskazania wyniku żądania. Kody statusu dzielą się na dwie kategorie: błędy klienta (4xx), które musisz naprawić samodzielnie, oraz błędy serwera (5xx), które możesz ponowić.

Odpowiedź sukcesu
KodZnaczenieWyjaśnienie200OKŻądanie zostało przetworzone pomyślnie201CreatedUtworzono nowy obiekt (np. hook, subscriber lub dokument/zasób)202AcceptedŻądanie zaakceptowane do przetwarzania asynchronicznego/w kolejce; sprawdź status później204No ContentŻądanie zakończone sukcesem bez treści odpowiedzi (np. przy DELETE lub aktualizacji bez treści)
Błędy klienta (4xx): nie ponawiaj

Przy błędzie 4xx problem leży w samym żądaniu. Ponowne wysłanie z tymi samymi danymi da ten sam rezultat. Napraw przyczynę przed ponowną próbą.

KodZnaczenieKiedyDziałanie400Bad RequestBłąd walidacji lub błąd składni w dokumencieSprawdź treść żądania. Odpowiedź JSON zawiera szczegóły dotyczące problemu401UnauthorizedNie wysłano tokenu, token wygasł lub jest nieprawidłowyPobierz nowy Bearer token z Identity Server403ForbiddenToken jest prawidłowy, ale akcja jest niedozwolona. Najczęściej: używasz partyId, do którego Twoje konto nie ma dostępu. Inne przyczyny: wygasły bearer token, nieprawidłowy subscription key lub endpoint niedostępny na Twoim poziomie autoryzacjiSprawdź, czy używasz właściwego partyId i czy użytkownik, który uzyskał bearer token, ma dostęp do tego partyId. W razie wątpliwości: pobierz nowy token przez Identity Server404Not FoundŻądany endpoint lub zasób nie istnieje (na przykład nieznany Document ID, hook lub PartyID). Przy wysyłce zdarza się to także w kombinacji "No valid delivery options. PartyId '...' not found in Peppol" (m.in. przy VerstuurInvoice): podany PartyId nie znajduje się (dla tego typu dokumentu) w Peppol/SMPSprawdź URL, Document ID i partyId. Przy "PartyId not found in Peppol": najpierw wykonaj lookup przez queryRecipientParty lub lookup.peppol.org dla podanego ID, następnie opcjonalnie sprawdź powiązane schematy (np. BE 0208 w porównaniu z 9925/BE:VAT, ten sam numer podstawowy) -- zmianę EndpointID zalecaj tylko przy potwierdzonym trafieniu lookup. Brak trafienia dla żadnego kandydata ID: odbiorca jest nieosiągalny na tych identyfikatorach; klient musi zapytać odbiorcę o rejestrację lub inny ID dostawy405Method Not AllowedUżyta metoda HTTP nie jest obsługiwana na tym endpościeSprawdź dokumentację API dla poprawnej metody (GET/POST/PUT/DELETE)409ConflictDokument został już przetworzony (idempotency)Nie jest wymagane żadne działanie: dokument został wcześniej pomyślnie odebrany. Zobacz idempotency413Content Too LargePlik przekracza maksymalny rozmiarZmniejsz dokument lub załączniki. Limit IDR: 15 MB415Unsupported Media TypeBrak nagłówka Content-Type lub jest nieprawidłowyUżyj poprawnego content-type, np. application/json tam gdzie wymagane422Unprocessable EntityŻądanie jest technicznie poprawne, ale treść nie może zostać przetworzona (np. nieprawidłowy UBL, błąd walidacji Peppol lub naruszona reguła biznesowa)Sprawdź strukturę dokumentu i reguły biznesowe; odpowiedź JSON zwykle zawiera szczegóły400 (zduplikowane agencje)Zduplikowany schemat identyfikatoraDwa lub więcej identyfikatorów z tym samym kodem schematu/agencji w jednym wywołaniu queryRecipientParty. Komunikat błędu: EConnect.Psb.Models.EConnectException: 'Duplicate id agencies {code} requested.' (gdzie {code} to kod agencji bez wiodącego zera, np. schemat 0208208).Podaj tylko jeden identyfikator na schemat na wywołanie. Wiele kandydatów w tym samym schemacie: wykonaj oddzielne wywołania.

API403 Access forbidden: dosłowny komunikat błędu [API403] Access forbidden. Please check PartyId authorization and make sure the Subscription-Key is valid może wystąpić między innymi przy nieudanym wysłaniu Peppol z Business Central ("delivery failed"), ale przyczyna jest ogólna dla PSB, nie specyficzna dla BC. Kolejność diagnozy:

  1. Sprawdź autoryzację PartyId: czy używasz właściwego partyId i czy powiązanie konta ma prawa do tej party?
  2. Odnów token Bearer, jeśli wygasł lub jest nieprawidłowy.
  3. Sprawdź Subscription-Key tylko wtedy, gdy ten nagłówek jest nadal wymagany (legacy/Collabrr/API31) -- nie jako domyślny pierwszy krok.

Uwaga: wzmianka o "Subscription-Key" w komunikacie błędu nie oznacza automatycznie, że klucz trzeba odnowić. Autoryzacja PartyId i problem z powiązaniem po stronie platformy są równie częstą przyczyną. Jeśli dostawa nadal się nie powodzi po prawidłowej weryfikacji tokenu i partyId, zgłoś sprawę do wsparcia eConnect, zamiast wielokrotnie rotować Subscription-Key.

Walidacja koperty SBDH (API400.USRMS1 / API400.USRMS2): te kody błędów wskazują na niezgodność między kopertą Peppol (SBDH) a samym dokumentem e-faktury. Przy USRMS1 nadawca lub odbiorca w kopercie nie zgadza się z identyfikatorami w XML faktury. Przy USRMS2 PSB nie może znaleźć rozpoznawalnego nadawcy w dokumencie. Sprawdź, czy EndpointID i PartyIdentification w Twoim UBL zgadzają się z wartościami podanymi podczas wysyłki. PSB odrzuca dokument na poziomie AS4 i zwraca błąd do wysyłającego Access Point.

Ograniczenie liczby żądań (429): można ponawiać

Wyjątek od zasady „tylko 5xx można ponawiać”: 429 Too Many Requests wskazuje na ograniczenie liczby żądań i można go ponowić. Poczekaj i uwzględnij nagłówek Retry-After przed ponownym wysłaniem żądania.

KodZnaczenieKiedyDziałanie429Too Many RequestsOgraniczenie liczby żądań: wysyłasz zbyt wiele żądań w danym okresiePoczekaj i uwzględnij nagłówek Retry-After, następnie ponów
Błędy serwera (5xx): ponawiaj

Błąd 5xx wskazuje na tymczasowy problem po stronie serwera. Samo żądanie może być poprawne. Razem z 429 są to jedyne kody statusu, przy których ponowienie ma sens.

KodZnaczenieKiedyDziałanie500Internal Server ErrorNieoczekiwany błąd serweraPonawiaj z exponential backoff502Bad GatewayNieprawidłowa odpowiedź z usługi nadrzędnej; zwykle tymczasowePonawiaj z exponential backoff503Service UnavailablePSB jest tymczasowo niedostępny (konserwacja, przeciążenie)Ponawiaj z exponential backoff504Gateway TimeoutUsługa nadrzędna nie odpowiada na czasPonawiaj z exponential backoff

Uwaga: endpoint wysyłki akceptuje maksymalnie 24 MB na żądanie, włącznie z narzutem HTTP. Ładunki przekraczające ten limit są odrzucane przez serwer WWW z HTTP 500 zamiast 413, ponieważ odrzucenie następuje przed walidacją na poziomie aplikacji. Pamiętaj o tym przy załącznikach zakodowanych w base64: dodają one około 33% do rozmiaru pliku.

API500UH podczas wdrożeń: kod błędu API500UH (Unhandled error) może wystąpić, gdy PSB wykonuje wewnętrzną aktualizację usługi (Service Fabric deployment). W wielu przypadkach dokument został już pomyślnie dostarczony do odbiorcy, ale krok potwierdzenia nie powiódł się z powodu migracji. Mechanizm ponawiania PSB automatycznie próbuje dokończyć pozostałe kroki. Jeśli otrzymasz API500UH, sprawdź za pomocą zdarzeń statusu, czy dokument został dostarczony, zanim wyślesz go ponownie.

Odczytywanie odpowiedzi błędów

Przy błędzie 4xx odpowiedź zawiera treść JSON opisującą problem. Te informacje pomagają szybko zidentyfikować przyczynę.

{
  "error": "Validation failed",
  "message": "The supplied document is not valid UBL 2.1",
  "details": [
    "cbc:InvoiceTypeCode is missing"
  ]
}

Przy błędzie 5xx odpowiedź nie zawsze jest ustrukturyzowana. Opieraj logikę ponawiania na kodzie statusu HTTP, a nie na treści body.

Strategia ponawiania dla Twojej integracji

Nie każdy błąd zasługuje na ponowienie. Zasada jest prosta: tylko kody statusu 5xx i timeouty sieciowe warto ponawiać. Przy błędach 4xx musisz zmodyfikować żądanie przed ponownym wysłaniem.

Exponential backoff

Zalecaną strategią ponawiania jest exponential backoff: zacznij od krótkiego czasu oczekiwania i podwajaj go przy każdej kolejnej próbie.

PróbaCzas oczekiwania11 sekunda22 sekundy34 sekundy48 sekund516 sekund632 sekundy7+60 sekund (maksimum)

Wskazówka: dodaj niewielki losowy rozrzut (jitter) do czasu oczekiwania. Jeśli wielu klientów ponawia żądania jednocześnie po awarii, jitter zapobiega ich jednoczesnym trafieniu na serwer.

Bezpieczne ponawianie z idempotency

Zawsze łącz logikę ponawiania z headerem X-EConnect-DocumentId. Dołączając ten sam documentId przy każdej próbie, PSB gwarantuje, że dokument nigdy nie zostanie przetworzony dwukrotnie. Jeśli PSB otrzyma documentId, który został już przetworzony, zwraca 409 Conflict jako potwierdzenie.

Zobacz Idempotency: zapobieganie podwójnym wysyłkom, aby uzyskać pełne wyjaśnienie i przykłady kodu.

Drzewo decyzyjne
Automatyczny mechanizm ponawiania PSB

Oprócz logiki ponawiania, którą implementujesz samodzielnie, PSB posiada własny mechanizm ponawiania dostarczania dokumentów. Jeśli PSB próbuje dostarczyć fakturę lub zamówienie do odbiorcy, a ta strona zwraca błąd 5xx, PSB automatycznie wznawia dostarczanie.

Dostarczanie dokumentów (faktury i zamówienia)

PSB wykonuje do 8 prób ponawiania rozłożonych na około 35 godzin. Przy każdej próbie PSB publikuje zdarzenie, dzięki czemu możesz śledzić postęp:

ZdarzenieZnaczenieInvoiceSentRetryRozpoczęto nową próbę dostarczenia fakturyInvoiceSentErrorWszystkie 8 prób nie powiodło się, faktura nie mogła zostać dostarczonaOrderSentRetryRozpoczęto nową próbę dostarczenia zamówieniaOrderSentErrorWszystkie 8 prób nie powiodło się, zamówienie nie mogło zostać dostarczone

Jeśli skonfigurowano webhook dla tych tematów, przy każdej próbie otrzymujesz powiadomienie. Po InvoiceSentError lub OrderSentError wymagane jest ręczne działanie: skontaktuj się z odbiorcą lub eskaluj przez eConnect Support.

Wskazówka: subskrybuj tematy InvoiceSentRetry i InvoiceSentError za pomocą webhooka. Dzięki temu natychmiast wykryjesz problemy z dostarczaniem i możesz działać proaktywnie.

Dostarczanie webhooków

Dla webhooków PSB stosuje oddzielny harmonogram ponawiania. Jeśli Twój endpoint webhookowy jest nieosiągalny lub nie zwraca kodu statusu 2xx, PSB ponawia dostarczanie zdarzenia.

ParametrWartośćMaksymalny czas ponawiania5 dniStrategiaExponential backoffTimeout na próbę100 sekundZdarzenie na próbęHookSentRetryZdarzenie przy ostatecznym niepowodzeniuHookSentError

PSB oczekuje odpowiedzi 2xx od Twojego endpointu w ciągu 100 sekund. Każda inna odpowiedź (lub timeout) liczy się jako nieudana próba. Dlatego przetwarzaj przychodzące webhooki jak najszybciej, potwierdź odbiór odpowiedzią 200 OK i wykonuj ciężkie przetwarzanie asynchronicznie w procesie w tle.

Uwaga: jeśli Twój endpoint jest nieosiągalny przez dłuższy czas, PSB przestaje ponawiać po 5 dniach. Pominięte zdarzenia można nadal pobrać za pomocą endpointu batch. Zobacz Batch hooks, aby uzyskać więcej informacji.

Nazwy hostów PSB do białej listy sieci

W przypadku integracji uzyskujących dostęp do PSB z chronionej sieci (zapora ogniowa, proxy, lista dozwolonych), należy zezwolić na podstawowe nazwy hostów i nazwy hostów failover. everbinding.nl to starszy domen eConnect, aktywnie używany do failover PSB.

ŚrodoswiskoGłównyFailoverProdukcjapsb.econnect.euapi.everbinding.nlAkceptacjaaccp-psb.econnect.eutestapi.everbinding.nl

Umieść wszystkie cztery nazwy hostów na białej liście na porcie 443 (HTTPS). Bez nazw hostów failover poprawne połączenie PSB może stać się nieosiągalne podczas zdarzenia awaryjnego, podczas gdy PSB sama działa.

Przegląd: można ponawiać czy nie?
Kod statusuMożna ponawiaćStrategia200 OKNie jest potrzebnePrzetworzono201 CreatedNie jest potrzebnePrzetworzono202 AcceptedNie jest potrzebneSprawdź status później204 No ContentNie jest potrzebnePrzetworzono400 Bad RequestNieNapraw żądanie401 UnauthorizedNiePobierz nowy token403 ForbiddenNieSprawdź uprawnienia404 Not FoundNieSprawdź URL/zasób405 Method Not AllowedNieSprawdź metodę HTTP409 ConflictNieDokument został już przetworzony413 Content Too LargeNieZmniejsz rozmiar pliku415 Unsupported Media TypeNiePopraw nagłówek Content-Type422 Unprocessable EntityNieSprawdź strukturę dokumentu/reguły biznesowe429 Too Many RequestsTakPoczekaj na Retry-After, exponential backoff500 Internal Server ErrorTakExponential backoff502 Bad GatewayTakExponential backoff503 Service UnavailableTakExponential backoff504 Gateway TimeoutTakExponential backoff

W skrócie Błędy klienta (4xx) wymagają Twojej uwagi: napraw problem w żądaniu. Błędy serwera (5xx) są tymczasowe i można je bezpiecznie ponawiać z exponential backoff. Zawsze używaj headera X-EConnect-DocumentId, aby zapobiec podwójnemu przetworzeniu przy ponawianiu. PSB automatycznie ponawia dostarczanie dokumentów do 8 razy w ciągu około 35 godzin, a webhooków przez okres do 5 dni.

Zobacz pełną dokumentację API