Wysyłanie faktury przez API

Wysyłanie faktury przez endpoint SalesInvoice: upload w dowolnym obsługiwanym formacie, automatyczna transformacja, routing i śledzenie statusu.

Wysyłanie e-faktury przez API PSB to najczęściej używany endpoint. Wysyła się dokument XML do API w formacie generowanym przez własne oprogramowanie, a PSB zajmuje się walidacją, automatyczną transformacją na format oczekiwany przez odbiorcę, routingiem i dostarczeniem przez odpowiednią sieć.

Endpoint
POST /api/v1/{partyId}/salesInvoice/send

{partyId} w URL to identyfikator Peppol organizacji wysyłającej (dostawcy). Żądanie zawiera dokument XML jako body (content-type application/xml). PSB automatycznie wykrywa format dokumentu i waliduje go. Można dostarczać w dowolnym obsługiwanym formacie: UBL 2.1, NLCIUS, BIS Billing V3, PINT, CII, XRechnung, Factur-X, FatturaPA, ebInterface, Svefaktura, DICO, SETU i inne. PSB automatycznie transformuje dokument na format oczekiwany przez odbiorcę.

Podstawowy przepływ
  1. Upload: wysyłka dokumentu XML do endpointu
  2. Walidacja: PSB waliduje dokument względem schematu XSD i reguł biznesowych
  3. Routing: PSB wyszukuje przez SML/SMP, jak dotrzeć do odbiorcy
  4. Dostarczenie: dokument jest dostarczany odpowiednim kanałem (Peppol, e-mail lub inna sieć)
  5. Aktualizacja statusu: otrzymanie powiadomienia webhook ze statusem dostarczenia

Ważne: PSB określa odbiorcę na podstawie EndpointID w dokumencie XML. Jeśli ten element jest nieobecny lub zawiera nieprawidłowy identyfikator, wysyłka kończy się niepowodzeniem ze statusem InvoiceSentError. Należy upewnić się, że system źródłowy prawidłowo wypełnia EndpointID. Więcej o identyfikatorach i routingu w artykule o identyfikatorach Peppol.

Idempotency: zapobieganie podwójnym uploadom

PSB obsługuje idempotency za pośrednictwem headera żądania X-EConnect-DocumentId. Wysyłając z każdym żądaniem uploadu unikalny UUID, zapobiega się podwójnemu przetworzeniu:

X-EConnect-DocumentId: 550e8400-e29b-41d4-a716-446655440000

Jeśli ten sam documentId zostanie wysłany ponownie, API zwraca 409 Conflict, a nadawca wie, że dokument został już przetworzony.

Ważne: Należy zawsze używać UUID/GUID jako documentId. Nigdy nie należy używać numeru faktury, ponieważ powoduje to problemy przy próbie ponownego wysłania skorygowanej wersji tej samej faktury.

Sprawdzanie routingu

Przed wysłaniem faktury można sprawdzić za pomocą queryRecipientParty, czy i jak odbiorca jest osiągalny:

POST /api/v1/{partyId}/salesInvoice/queryRecipientParty

W ciele żądania przekazuje się listę identyfikatorów, na przykład ["0106:12345678"], lub obiekt z partyIds i metaAttributes. Opcjonalne parametry zapytania to ?preferredDocumentTypeId i ?includeOptions.

Odpowiedź zawiera informacje o:

  • Czy odbiorca jest zarejestrowany w Peppol
  • Jakie typy dokumentów odbiorca może przyjmować
  • Przez który Access Point odbiorca jest osiągalny
  • Jakiego kanału PSB użyje do dostarczenia

Dla zaawansowanych zapytań obejmujących URL Access Pointa oraz certyfikat AP dostępna jest oddzielna trasa:

GET /api/v1/peppol/deliveryOption?partyIds={id}&documentFamily=Invoice&isCredit=false
Obsługa błędów

W przypadku nieudanego dostarczenia PSB automatycznie stosuje mechanizm ponawiania:

  • Maksymalnie 8 prób rozłożonych na ok. 35 godzin
  • Tylko przy błędach serwera 5xx (tymczasowe błędy po stronie odbiorcy)
  • Przy każdej próbie publikowane jest zdarzenie InvoiceSentRetry
  • W przypadku ostatecznego niepowodzenia otrzymuje się zdarzenie InvoiceSentError przez webhook

Częste błędy przy wysyłce:

BłądPrzyczynaRozwiązanieBłąd walidacji (4xx)Dokument nie jest zgodny ze standardemNależy sprawdzić dokument za pomocą Validate API. Uwaga: błędy 4xx nie są ponawiane; dokument pozostaje w InvoiceSentError jako stan końcowy.Invalid payload — '{wartość}' nie jest prawidłowym xs:decimal na polu kwotySystem źródłowy serializuje kwotę (na przykład cbc:TaxInclusiveAmount, cbc:PriceAmount, cbc:LineExtensionAmount) w notacji naukowej, takiej jak -1.336061E6 zamiast -1336061.00. Pola kwot UBL są typu xs:decimal, a typ XML Schema nie dopuszcza notacji wykładniczej; dopuszczalna jest tylko stała notacja dziesiętna z maksymalnie 2 miejscami po przecinku. Występuje typowo dla dużych lub ujemnych kwot serializowanych wewnętrznie jako double.Należy dostosować system źródłowy, aby kwoty były zapisywane jako zwykłe liczby dziesiętne (bez notacji E, bez separatorów tysięcy). Zgłosić problem dostawcy oprogramowania wysyłającego; eConnect nie może tego skorygować, ponieważ wartość znajduje się w dostarczonym XML.The string '' is not a valid Decimal value w polu PriceAmountPole kwoty (np. cbc:PriceAmount) zawiera pusty ciąg znaków ("") zamiast liczby dziesiętnej na jednej lub kilku pozycjach faktury. xs:decimal nie dopuszcza pustego ciągu znaków jako wartości leksykalnej. Inna przyczyna niż notacja naukowa, ta sama klasa wzorca błędu.Nie do skorygowania automatycznie przez eConnect. Należy dostosować system źródłowy, aby żadne pole kwoty nie pozostawało puste; przesłać ponownie fakturę z prawidłową kwotą dziesiętną na wszystkich pozycjach.Odbiorca nie znalezionyIdentyfikator nie jest zarejestrowany w PeppolNależy sprawdzić za pomocą queryRecipientParty409 ConflictDokument o tym documentId został już przetworzonyNie jest wymagana żadna akcja, dokument został już wysłanyHTTP 500 przy dużym payloadzieŻądanie przekracza limit 24 MB serwera WWW (łącznie z narzutem)Należy zmniejszyć osadzone załączniki PDF; uwzględnić ok. 33% narzutu base64

Uwaga: SI-UBL 1.2 (Simpler Invoicing 1.2) nie jest dozwolony w sieci Peppol od 1 stycznia 2024. Faktury w tym formacie skutkują błędem InvoiceSentError. Należy używać NLCIUS (SI-UBL 2.0) lub Peppol BIS Billing V3. Należy sprawdzić CustomizationID w dokumencie XML, jeśli napotkany zostanie ten błąd.

Odpowiedź

Pomyślny upload zwraca 200 OK z identyfikatorem dokumentu w PSB. Tego identyfikatora należy używać do śledzenia statusu dokumentu przez API lub webhooki.

Brak DELETE na salesInvoice: stan końcowy po błędzie 4xx

W przeciwieństwie do purchaseInvoice endpoint salesInvoice nie ma DELETE. Jest to świadomy wybór, ponieważ wysłana lub odrzucona faktura sprzedaży stanowi zdarzenie istotne z punktu widzenia audytu: dokument pozostaje możliwy do prześledzenia w ścieżce audytu, nawet po nieudanej wysyłce.

Klienci czasem pytają, czy odrzuconą fakturę sprzedaży można zatrzymać lub usunąć, na przykład po tym, jak już skredytowali ją wewnętrznie. Odpowiedź brzmi:

  • Błąd walidacji (4xx, na przykład Invalid payload): PSB umieszcza dokument w stanie końcowym InvoiceSentError. Nie jest wykonywane żadne ponowienie (ponawiane są tylko błędy 5xx). Dokument nie zostaje pomimo to dostarczony do odbiorcy. Na PSB nie jest wymagane żadne działanie; dokument znajduje się w stanie końcowym i jest przechowywany 90 dni do celów audytu.
  • Brak potrzeby endpointu DELETE: ponieważ dokument nie jest już aktywny i nie jest ponawiany, nie trzeba go jawnie usuwać, aby zatrzymać wysyłkę.
  • Wysłanie korekty przez nowy dokument: jeśli pierwotna faktura była błędna i została już (częściowo) dostarczona, należy użyć noty kredytowej lub faktury korygującej zgodnie ze standardowym przepływem księgowym. Pierwotny documentId pozostaje jako referencja w ścieżce audytu.

Ta różnica w cyklu życia między salesInvoice (bez DELETE) a purchaseInvoice (z DELETE) wynika z roli: faktura wychodząca to działanie handlowe zarejestrowane przez wysyłającego, które musi być prawnie możliwe do prześledzenia; faktura przychodząca może zostać usunięta z systemu odbiorcy po pomyślnym pobraniu.

ViDA i raportowanie CTC

Przy wysyłaniu faktury PSB obsługuje również raportowanie fiskalne. W ramach dyrektywy ViDA (VAT in the Digital Age) PSB automatycznie generuje DRR (Digital Reporting Requirement) na podstawie danych z faktury i przesyła go do właściwego urzędu skarbowego. Jako integrator nie trzeba wykonywać żadnych dodatkowych działań: DRR jest generowany na podstawie tej samej faktury wysyłanej przez standardowy endpoint. Komunikaty statusowe i komunikaty raportowania CTC są wliczone w cenę dokumentu.

Opcje zaawansowane
Wymuszanie kanału

Domyślnie PSB automatycznie wybiera najlepszy kanał. Za pomocą parametru zapytania ?channel={hookId} można wymusić konkretny kanał dostarczenia (np. określoną sieć lub fallback e-mail).

Wysyłanie załączników

Załączniki (PDF, obrazy) mogą być osadzone w dokumencie UBL jako AdditionalDocumentReference w formacie base64. PSB prawidłowo przetwarza osadzone załączniki i dostarcza je wraz z fakturą.

Uwaga: Endpoint wysyłki akceptuje maksymalnie 24 MB na żądanie (łącznie z narzutem HTTP). Przy załącznikach zakodowanych w base64 payload rośnie o ok. 33%, więc plik PDF o rozmiarze 18 MB skutkuje żądaniem o rozmiarze ok. 24 MB. Payloady przekraczające limit są odrzucane przez serwer WWW z HTTP 500 (nie 413), zanim nastąpi walidacja na poziomie aplikacji. Należy zmniejszyć duże załączniki lub wysłać je osobnym kanałem.

Wskazówka: Aktualny standard Peppol BIS Billing 3.0 obsługuje maksymalnie jeden OrderReference na fakturę. Jeśli faktura dotyczy wielu zamówień, należy wysłać wiele faktur.

Wskazówka: Niektórzy odbiorcy zgłaszają błędy dla faktur z prefiksem przestrzeni nazw XML (np. <urn:Invoice> zamiast <Invoice>). Obie formy są technicznie poprawnym XML zgodnie ze specyfikacją W3C. Jeśli odbiorca podaje to jako powód odrzucenia, nie jest to uzasadniona odmowa w sieci Peppol. Odbiorca musi używać parsera XML, który prawidłowo obsługuje zarówno prefiksowane, jak i domyślne przestrzenie nazw.

Często zadawane pytania
W jakim formacie dostarczyć fakturę?

Można dostarczać w dowolnym formacie obsługiwanym przez PSB: UBL 2.1, NLCIUS, BIS Billing V3, PINT, CII, XRechnung, Factur-X, FatturaPA, ebInterface, Svefaktura, DICO, SETU i inne. Dokument XML należy przesłać jako body do POST /api/v1/{partyId}/salesInvoice/send z Content-Type: application/xml. PSB automatycznie wykrywa format, waliduje go i transformuje na format oczekiwany przez odbiorcę. Odbiorca jest określany na podstawie EndpointID w XML.

Jak zapobiec podwójnemu wysłaniu i co oznacza 409 Conflict?

Przy każdym uploadzie należy dołączyć nagłówek X-EConnect-DocumentId z unikalnym UUID. Jeśli to samo documentId zostanie powtórzone, API odpowie 409 Conflict, potwierdzając, że dokument został już przetworzony. Nie należy nigdy używać numeru faktury jako documentId, ponieważ przy ponownym wysłaniu poprawionej wersji potrzebny jest nowy identyfikator.

Jak śledzić status dostarczenia i co się dzieje przy tymczasowych błędach?

Po pomyślnym uploadzie API zwraca identyfikator dokumentu w PSB, którego można używać do śledzenia statusu przez API lub webhooki. Przy tymczasowych błędach 5xx po stronie odbiorcy PSB publikuje zdarzenie InvoiceSentRetry dla każdej próby i ponawia do 8 razy w ciągu ok. 35 godzin; przy definitywnym niepowodzeniu otrzymają Państwo zdarzenie InvoiceSentError.


Chcą Państwo najpierw sprawdzić, czy dokument jest prawidłowy? Należy użyć Validate API.

Wypróbuj w API