Wystawienie faktury ustrukturyzowanej z wykorzystaniem Open API Krajowego Systemu e-Faktur (KSeF)

Proces wystawienia e-Faktury z wykorzystaniem API KSeF wcale nie jest trywialny, dlatego przygotowaliśmy poniższą instrukcję, żeby każdy kto się nie boi mógł spróbować swoich sił w tej „konkurencji”. Zresztą nie ma co przedłużać wstępu – zobaczcie sami:

1. Wyzwanie autoryzacyjne

Aby wystartować komunikację z API KSeF w pierwszej kolejności musimy wywołać AutrhorisationChallenge , czyli tzw. wyzwanie autoryzacyjne, na podstawie którego będziemy mogli ustanowić sesję. A zatem wywołujemy:

POST /online/Session/AuthorisationChallenge

Gdzie podajemy czas w formacie timestamp (np.: "timestamp": "2023-10-10T13:00:00Z") oraz typ identyfikatora ("identifierType": "onip") i jego wartość ("identifier": "<nip wystawcy faktury>")

Zwrócony zostanie znacznik czasowy oraz wartość samego wyzwania autoryzacyjnego

Faktury KSeF API - wyzwanie autoryzacyjne

2. Sesja podpisana

Następnie wywołujemy nawiązanie sesji podpisanej:

POST /online/Sesision/InitSigned

InitSessionSignedRequest – zawiera opcjonalną sekcję Encryption – każda faktura wysłana w ramach utworzonej sesji interaktywnej będzie zaszyfrowana kluczem symetrycznym wskazanym w sesji Encryption.

Uzupełniamy:

  1. kontekst w którym pracujemy, czyli atrybut <Context><Identifier> – wpisując NIP wystawcy faktury
  2. wyzwanie autoryzacyjne, czyli atrybut <Context><Challenge> – wpisujemy <wartość wyzwania zwrócona z poprzedniej operacji>
  3. znacznik czasowy, czyli atrybut <Context><Timestamp> – wpisujemy <wartość timestamp zwrócona z poprzedniej operacji> – Uwaga! znacznik ważny jest 5 minut
  4. Tak przygotowane żądanie uwierzytelniające należy podpisać korzystając z podpisu kwalifikowanego lub pieczęci elektronicznej która zawiera numer PESEL podany w kontekście
  5. Po wykonaniu podpisu do żądania dodawany jest element <ds:Signature> zawierający m.in. podpis (wartość z funkcji skrótu) oraz certyfikat X.509 który służy do weryfikacji poprawności podpisu XAdES.
  6. Tak przygotowane żądanie uwierzytelniające wysyłamy korzystając z metody POST /online/Sesision/InitSigned
  7. Brak autoryzacji, ponieważ nie możemy powiązać PESEL z tą konkretną firmą (numerem NIP firmy) z kontekstu.
  8. Żądanie uwierzytelniające musi być podpisane podpisem lub pieczęcią elektroniczną z numerem NIP – po to aby możliwe było powiązanie (potwierdzenie) podanego numeru NIP w kontekście.
  9. Jeśli wykorzystamy podpis/pieczęć z NIP to wtedy w odpowiedzi dostaniemy:
    1. Numer referencyjny sesji referenceNumber„- bardzo ważny atrybut służy do sprawdzenia statusu sesji oraz pobrania UPO.
    2. Token sesji – atrybut sessionToken : { "token", "context" …. }

Faktury KSeF API - nawiązanie sesji

Uwaga! Mając token sesji – każde kolejne zapytanie powinno być autoryzowane tym tokenem

3. Nadanie uprawnień do wysyłania żądań do KSeF

Nadanie uprawnień (czyli komu i co nadajemy) dla konkretnego numeru PESEL, czyli osobie która w ramach firmy będzie mogła np. wystawiać i odczytywać faktury:

Faktury KSeF API - żądanie nadania uprawnień

POST /online/Credentials/Grant

Faktury KSeF API - wywołanie nawiązania sesji

Faktury KSeF API - odpowiedź nawiązania sesji

Proces nadawania uprawnień jest asynchroniczny i może chwilę potrwać. Ale za pomocą wartości zwróconego atrybutu elementReferenceNumber możemy dowiedzieć się jaki jest status – w tym przypadku – nadania uprawnień.

3a. Sprawdzenie statusu nadania uprawnień

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

Faktury KSeF API - sprawdzenie statusu nadania uprawnień

  • Status Proces został zarejestrowany (processingCode:100) oznacza że dopiero rozpoczęło się procesowanie nadania uprawnień.
  • Status Proces uprawnień zakończony (processingCode:200) oznacza że uprawnienia zostały nadane

4. Żądanie uwierzytelniające

Teraz mając nadane uprawnienia dla PESEL możemy jeszcze raz wysłać podpisane żądanie uwierzytelniające podpisane kwalifikowanym (z PESEL):

POST /online/Sesision/InitSigned

W odpowiedzi powinniśmy otrzymać:

Faktury KSeF API - wysłanie podpisanego żądania uwierzytelniającego

Ważny jest token sesyjny (token), który umożliwia wykonywanie takich operacji jak wystawianie i odbiór faktur. Oczywiście jest o też zupełnie inna sesja (inna wartość dla referenceNumber).

5. Wygenerowanie tokena autoryzacyjnego

Poniżej przykłada żądania, które należy wysłać do metody GenerateToken.

POST /online/Credentials/GenerateToken

Faktury KSeF API - przykład żądania wygenerowania tokenu autoryzacyjnego

Wywołanie i odpowiedź:

Faktury KSeF API - wysłanie żądania wygenerowania tokenu autoryzacyjnego

Uwaga! Token autoryzacyjny (authorisationToken) jest zwracany i możliwy do pobrania tylko raz po wywołaniu metody GenerateToken, później nie jest już możliwy do uzyskania.

Ten token autoryzacyjny można już wpisać w aplikacji.

Z uwagi na processingCode:100 musimy sprawdzić kiedy zakończy się proces generowania tokenu…. I dopiero wtedy (jak będzie processingCode:200) token będzie gotowy do użycia.

5a. Sprawdzenie statusu generowania tokenu

W celu sprawdzenia statusu generowania tokenu, musimy wysłać wartość atrybutu elementReferenceNumber z odpowiedzi uzyskanej w kroku 5 wysłać na adres metody:

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

6. Nawiązanie sesji umożliwiającej wysłanie e-Faktury

Jeśli mamy token autoryzacyjny to teraz należy nawiązać nim sesję w celu wykonania czynności takich jak wysłanie lub odbieranie faktur.

  1. Generujemy wyzwanie autoryzacyjne w tym samym kontekście: POST /online/Session/AuthorisationChallenge
  2. Przygotowujemy żądanie InitSessionTokenRequest, gdzie wypełniamy atrybuty: timestamp (z wyzwania autoryzacyjnego), challenge (również z wyzwania autoryzacyjnego), identifier (zgodny z kontekstem) oraz token – zgodnie z dokumentacją jest to Base64():

KSeF - kodowanie żądania

Uwaga! Taka przygotowanego żądania nie musimy już podpisywać – to jest różnica między nawiązaniem sesji z wykorzystaniem podpisu, a sesją z wykorzystaniem tokenu autoryzacyjnego.

KSeF API - odpowiedź zawierająca token sesyjny

W odpowiedzi dostajemy token sesyjny: w atrybucie sessionToken > token

Uwaga! Z tym tokenem możemy dopiero wystawiać/odbierać faktury!!!

7. Wysłanie e-Faktury do KSeF

PUT /online/Invoice/Send

Wartość w atrybucie faktury <Podmiot1><DaneIdentyfikacyjne><NIP> musi być taka sama jak w wartość z kontekstu zadeklarowana w wyzwaniu autoryzacyjnym. Wyjątkiem jest np. samofakturowanie, wtedy w tym polu może pojawić się inny NIP, ale trzeba mieć uprawnienia nadane do samofakturowania (a w danych odbiorcy musi być NIP zgodny z zadeklarowanym w wyzwaniu autoryzacyjnym).

Przykład żądania:

Faktury KSeF API - przykład żądania wystawienia e-Faktury

  1. Autoryzujemy sesję z wykorzystaniem tokena sesyjnego
  2. Jeśli jest aktywna sesja to wywołujemy PUT /online/Invoice/Send i przekazujemy żądnie zawierające: skrót z faktury (hashSHA), rozmiar (fileSize) oraz samą fakturę (invoiceBody)
  3. W odpowiedzi otrzymujemy informację, że proces odebrania przesłanej faktury wystartował:

Faktury KSeF API - wysłanie żądanie wystawienia efaktury ustrukturyzowanej i odbiór odpowiedzi

Uwaga! Atrybut referenceNumber, czyli numer referencyjny sesji należy odłożyć ponieważ po nim będziemy mogli sprawdzić i pobrać UPO.

7a. Sprawdzenie statusu odebrania przez KSeF wysłanej przez nas faktury

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

KSeF API - sprawdzenie statusu otrzymania wysłanej efaktury przez Krajowy System e-Faktur

Jeśli faktura została zaakceptowana (status 200), to ważny jest atrybut ksefReferenceNumber, który jednoznacznie identyfikuje fakturę. Atrybut acquisitionTimestamp określi datę i czas kiedy dokładnie faktura została przyjęta do systemu KSeF.

Tak to już wszystko i możemy cieszyć się z wystawienia pierwszej e-faktury w KSeF.

Niniejszy wpis powstał na podstawie Webinarium przeprowadzonego w dniu 25.11.2022r. przez przedstawicieli Ministerstwa Finansów.

Aktualizacja 01.05.2024 – Z uwagi na udostępnienie dedykowanego interfejsu KSEF REST API w serwisie nip24.pl zachęcamy do zapoznania się z jego dokumentacją.

pl_PLPolski