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ć.
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ę.
Ważne: PSB określa odbiorcę na podstawie
EndpointIDw dokumencie XML. Jeśli ten element jest nieobecny lub zawiera nieprawidłowy identyfikator, wysyłka kończy się niepowodzeniem ze statusemInvoiceSentError. 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.
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.
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:
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
W przypadku nieudanego dostarczenia PSB automatycznie stosuje mechanizm ponawiania:
InvoiceSentRetryInvoiceSentError przez webhookCzęste błędy przy wysyłce:
InvoiceSentError jako stan końcowy.Invalid payload — '{wartość}' nie jest prawidłowym xs:decimal na polu kwotycbc: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.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 PriceAmountcbc: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.queryRecipientPartyUwaga: 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ćCustomizationIDw dokumencie XML, jeśli napotkany zostanie ten błąd.
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.
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:
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.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.
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.
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).
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
OrderReferencena 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.
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.
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.
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