Issuing a structured invoice using the Open API of the National e-Invoice System (KSeF)
The process of issuing an e-Invoice using the KSeF API is not trivial at all, so we have prepared the instructions below so that anyone who is not afraid can try their hand at this "competition". Anyway, there's no point in extending the introduction - see for yourself:
1. Authorization challenge
To start communication with the KSeF API, we first need to call AutrhorisationChallenge
, i.e. the so-called authorization challenge based on which we will be able to establish a session. So we invoke:
POST /online/Session/AuthorisationChallenge
Where we enter the time in timestamp format (e.g.: "timestamp": "2023-10-10T13:00:00Z"
) and identifier type ("identifierType": "onip"
) and its value ("identifier": "<nip wystawcy faktury>"
)
The timestamp and the value of the authorization challenge itself will be returned
2. Session signed
Then we invoke the establishment of a signed session:
POST /online/Sesision/InitSigned
InitSessionSignedRequest
– contains an optional section Encryption
– each invoice sent as part of the created interactive session will be encrypted with the symmetric key indicated in the session Encryption
.
We add:
- the context in which we work, i.e. attribute
<Context><Identifier>
– by entering the invoice issuer's Tax Identification Number - authorization challenge, i.e. attribute
<Context><Challenge>
– we enter - timestamp, i.e. attribute
<Context><Timestamp>
– we enter – Attention! the tag is valid for 5 minutes - The authentication request prepared in this way should be signed using a qualified signature or an electronic seal that contains a number PESEL number given in context
- Once the signature is completed, an element is added to the request
<ds:Signature>
containing, among others, signature (value from the hash function) and an X.509 certificate which is used to verify the correctness of the XAdES signature. - We send the authentication request prepared in this way using the method
POST /online/Sesision/InitSigned
- No authorization, because we cannot link the PESEL number to this specific company (company's Tax Identification Number) from the context.
- The authentication request must be signed with a signature or electronic seal with the NIP number - so that it is possible to link (confirm) the provided NIP number in the context.
- If we use the signature/stamp with the NIP, then in response we will get:
- Session reference number
referenceNumber
"- a very important attribute is used to check the session status and download UPO. - Session token – attribute
sessionToken : { "token", "context" …. }
- Session reference number
Attention! Having a session token - each subsequent query should be authorized with this token
3. Granting permission to send requests to KSeF
Granting authorizations (i.e. to whom and what we grant) for a specific PESEL number, i.e. to a person who within the company will be able to, for example, issue and read invoices:
POST /online/Credentials/Grant
The process of granting permissions is asynchronous and may take a while. But using the value of the returned attribute elementReferenceNumber
we can find out what the status is - in this case - of granting permissions.
3a. Checking the status of granting permissions
GET /online/Credentials/Status/{CredentialsElementReferenceNumber}
- Status
Proces został zarejestrowany
(processingCode:100) means that the process of granting permissions has just started. - Status
Proces uprawnień zakończony
(processingCode:200) means that permissions have been granted
4. Authentication request
Now, having been granted PESEL permissions, we can once again send a signed authentication request with a qualified signature (with PESEL):
POST /online/Sesision/InitSigned
In response we should receive:
He is important session token (token), which allows you to perform operations such as issuing and receiving invoices. Of course, there is also a completely different session (different value for referenceNumber
).
5. Generating an authorization token
Below are examples of requests that should be sent to the method GenerateToken
.
POST /online/Credentials/GenerateToken
Call and response:
Attention! Authorization token (authorisationToken
) is returned and available for download only once after calling the method GenerateToken
, later it is no longer obtainable.
This authorization token can now be entered in the application.
Due to processingCode:100
we need to check when the token generation process will end…. And only then (when it will be processingCode:200
) the token will be ready to use.
5a. Checking the token generation status
In order to check the token generation status, we need to send the attribute value elementReferenceNumber
from the answer obtained in step 5 send to the method address:
GET /online/Credentials/Status/{CredentialsElementReferenceNumber}
6. Establishing a session enabling sending e-Invoices
If we have an authorization token, now we need to establish a session with it in order to perform activities such as sending or receiving invoices.
- We generate an authorization challenge in the same context:
POST /online/Session/AuthorisationChallenge
- We are preparing the request
InitSessionTokenRequest
, where we fill in the attributes:timestamp
(from authorization challenge),challenge
(also from an authorization challenge),identifier
(consistent with the context) andtoken
– according to the documentation it isBase64()
:
Attention! We no longer have to sign such a prepared request - this is the difference between establishing a session using a signature and a session using an authorization token.
In response we get session token: in the attribute sessionToken > token
Attention! With this token we can only issue/receive invoices!!!
7. Sending the e-Invoice to KSeF
PUT /online/Invoice/Send
Value in the invoice attribute <Podmiot1><DaneIdentyfikacyjne><NIP>
must be the same as the context value declared in the authorization challenge. The exception is, for example, self-invoicing, in which case a different NIP may appear in this field, but you must have the authorization to self-invoice (and the recipient's data must be consistent with the NIP declared in the authorization challenge).
Request example:
- We authorize the session using a session token
- If there is an active session, we invoke it
PUT /online/Invoice/Send
and send the request containing: invoice abbreviation (hashSHA
), size (fileSize
) and the invoice itself (invoiceBody
) - In response, we receive information that the process of collecting the sent invoice has started:
Attention! Attribute referenceNumber
, i.e. the session reference number should be put aside because after it we will be able to check and download the UPO.
7a. Checking the status of receipt of the invoice we sent by KSeF
GET /online/Credentials/Status/{CredentialsElementReferenceNumber}
If the invoice has been accepted (status 200), this attribute is important ksefReferenceNumber
, which uniquely identifies the invoice. Attribute acquisitionTimestamp
will specify the date and time when exactly the invoice was accepted into the KSeF system.
Yes, that's it and we can be happy about issuing the first e-invoice in KSeF.
This entry was based on Webinar conducted on November 25, 2022. by representatives of the Ministry of Finance.