Date de autentificare pentru rețele
Stocarea și înlocuirea datelor de autentificare ale unui client pentru rețele.
- În sandboxstocarea
- Încă nu este în sandboxrețelele
În cuvinte simple
Datele de autentificare pentru o rețea sunt cheia sau autorizarea care ne permite să acționăm, pentru un client, în rețeaua sau la autoritatea unei țări, de exemplu un token pentru sistemul național de facturare electronică al Poloniei (KSeF). Clientul le emite sau le autorizează, iar ele ajung în eurinvoice prin API, niciodată prin e-mail sau chat. Le păstrăm criptate și nu le mai afișăm niciodată. Sandboxul găzduit nu conține încă niciuna, așa că un canal de acolo nu trimite nimic.
Datele de autentificare pentru o rețea ne permit să acționăm pe un canal, pentru un client: un token KSeF, o autorizare ANAF, o cheie de platformă. Ajung în sistem prin acest API, niciodată prin e-mail sau chat. API-ul le păstrează și nu le returnează niciodată. Apelurile necesită o cheie cu domeniul admin, iar cheia unui client stochează date de autentificare doar pentru propriul client.
Cum este păstrată o valoare
O valoare este criptată înainte de stocare, păstrată separat de cheia care o protejează și nu mai este afișată niciodată. Datele de autentificare sunt deschise doar când serviciul ar apela canalul acelui client. Fiecare utilizare scrie un rând de audit fără valoare.
Pentru datele de autentificare al căror expires_on este la mai puțin de 30 de zile se înregistrează o alertă. Revocarea șterge valoarea și păstrează datele calendaristice.
Câmpuri
| Câmp | Semnificație |
|---|---|
client | Identificatorul clientului, același pe care îl poartă o factură: de la 1 la 64 de litere, cifre, puncte, liniuțe de subliniere sau cratime. Cheia proprie a unui client îl poate omite. |
route | DE-XRECHNUNG, PEPPOL, FR-PA, PL-KSEF sau RO-EFACTURA. |
kind | Denumește datele de autentificare și stabilește cum sunt citite, cel mult 80 de caractere (litere, cifre, puncte, liniuțe de subliniere și cratime): ksef-token pentru KSeF și anaf-oauth pentru ANAF. Pentru un canal Peppol sau francez, vă comunicăm tipul și forma valorii la începutul intrării în producție. |
issued_by | Cine le-a emis, cel mult 200 de caractere. |
issued_on | Data emiterii, YYYY-MM-DD. |
expires_on | Opțional, YYYY-MM-DD. Completați-l dacă datele de autentificare expiră. |
environment | Opțional. Trebuie să fie mediul serviciului pe care îl apelați; un sandbox stochează doar date de autentificare pentru sandbox. |
legal_entity | Opțional, cel mult 64 de caractere. Identificatorul vânzătorului pentru care acționează datele de autentificare: un cod de TVA, NIP, SIREN sau un ID de companie. Datele de autentificare fără acest câmp deservesc celelalte facturi ale clientului. |
value | Secretul, de cel mult 16.384 de caractere. Obligatoriu și nu este returnat niciodată. |
Serviciul verifică dacă o valoare poate funcționa pentru tipul ei, de exemplu dacă un token KSeF este un JSON cu nip și token. O valoare anaf-oauth este text JSON cu un cui și fie un access_token, fie un refresh_token împreună cu client_id și client_secret ale aplicației. O valoare care nu poate funcționa primește 422, credential-unusable, iar răspunsul indică forma așteptată fără să citeze valoarea.
Un răspuns conține id (cred_ și 24 de caractere hexazecimale), câmpurile de mai sus fără value, stored (true cât timp este păstrată o valoare) și revoked_at după revocare.
Un client poate avea un singur set activ de date de autentificare pentru fiecare canal, kind, mediu și entitate juridică. Procesul de lucru îl folosește pe cel mai vechi set nerevocat pentru clientul și canalul facturii.
Stocarea datelor de autentificare
POST /credentials primește câmpurile de mai sus ca JSON și răspunde 201. Cererea este credential-create.json.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-create.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-create.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-create.json'),
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2027-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}O nouă stocare a acelorași date de autentificare cât timp primele sunt active primește 409.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-create.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-create.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-create.json'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/credential-exists",
"title": "This client already has this credential",
"status": 409
}Listare și citire
GET /credentials returnează toate seturile de date de autentificare, active și revocate, ca {"data": [...]}. GET /credentials/{id} returnează unul singur și 404 pentru un ID pe care nu îl are.
curl "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials', {
headers: {
Authorization: 'Bearer <your-api-key>',
},
});
console.log(response.status);
console.log(await response.text());{
"data": [
{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2027-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}
]
}Înlocuire
POST /credentials/{id} primește o nouă valoare value și, opțional, un nou expires_on. Clientul, canalul, tipul și data emiterii rămân. Folosiți apelul după reîmprospătarea unui token. Cererea este credential-replace.json.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-replace.jsonimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-replace.json")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-replace.json'),
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2028-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}Revocare
POST /credentials/{id}/revoke șterge valoarea și completează revoked_at. Repetarea apelului nu schimbă nimic.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke" \
-H "Authorization: Bearer <your-api-key>"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke"))
.header("Authorization", "Bearer <your-api-key>")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
},
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"revoked_at": "2026-10-06T19:49:12.987Z",
"kind": "anaf-oauth",
"expires_on": "2028-09-01",
"stored": false,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}Atenție
O înregistrare revocată rămâne, pentru pista de audit. Nu poate fi înlocuită: încercarea primește 409, credential-revoked. Stocați în schimb noile date de autentificare ca o înregistrare nouă. Un set revocat nu mai împiedică stocarea din nou a aceluiași client, canal și tip.
Răspunsuri
| Cod | Semnificație |
|---|---|
200 | Lista, un set de date de autentificare, o înlocuire sau o revocare. |
201 | Stocat. |
400 | Corpul nu este JSON, un câmp obligatoriu lipsește sau este prea lung, route nu este unul dintre cele cinci canale sau o dată nu are formatul YYYY-MM-DD. |
401 | Lipsește cheia sau cheia este necunoscută. |
403 | Cheia nu are domeniul admin sau indică un alt client. |
404 | Nu există astfel de date de autentificare. |
409 | Clientul are deja aceste date de autentificare (credential-exists) sau ele au fost revocate (credential-revoked). |
413 | Corpul cererii depășește 5 MB (payload-too-large). |
422 | Valoarea nu poate funcționa pentru acest tip (credential-unusable). |
429 | Prea multe cereri pentru cheie. Așteptați numărul de secunde din Retry-After. |
503 | Serviciul nu are cheie principală cu care să sigileze o valoare (unavailable). |
De ce are nevoie fiecare canal
În sandboxdin surse oficiale, verificat pe 2 oct. 2026| Canal | Ce oferă clientul | Cine le emite | Valabilitate |
|---|---|---|---|
PL-KSEF | Un token KSeF care poate trimite facturi (InvoiceWrite) și, pentru stări, le poate citi (InvoiceRead). Permisiunile sale sunt fixate la creare, așa că o modificare necesită un token nou. Autentificarea cu un certificat KSeF nu este încă acceptată. Stocarea unor date ksef care nu sunt un ksef-token primește 422, credential-unusable. | Administratorul KSeF al clientului. | Consultați nota de mai jos. |
RO-EFACTURA | O autorizare OAuth pentru aplicația noastră înregistrată la ANAF. | O persoană cu drepturi în SPV pentru CUI-ul clientului: reprezentantul legal sau contabilul. Aceasta se autentifică în portalul ANAF cu un certificat calificat. | Tokenul de acces este valabil 90 de zile, iar tokenul de reîmprospătare 365 de zile. |
PEPPOL | Acordul pentru înregistrarea clientului ca participant Peppol și verificarea de identitate cerută de punctul de acces. | Clientul semnează acordul și trece verificarea. Noi deținem cheia punctului de acces, așa că nu există date de autentificare ale clientului de stocat. | Cheia punctului de acces este a noastră și o rotim noi. |
FR-PA | Contul clientului pe propria sa Plateforme Agréée și date de autentificare API pentru companie. | Clientul le creează pe platforma sa sau ne acordă acces. | Stabilită de platformă. Întrebați ce tip emite. |
DE-XRECHNUNG | Nimic pentru Germania ca atare. Prin e-mail, căsuța de e-mail de expediere. Prin Peppol, înregistrarea la punctul de acces. | Clientul. | Nu se aplică. |
Sfat
Setați expires_on pe baza duratelor de mai sus, astfel încât alerta de 30 de zile să se declanșeze înainte să expire un token de reîmprospătare.
Surse: procedura ANAF pentru OAuth (durata de valabilitate a tokenurilor), documentația API KSeF: tokenuri (permisiuni fixate la crearea tokenului).
Atenție
Polonia: sursele se contrazic privind durata de valabilitate a unui token KSeF. Manualul Ministerului Finanțelor (ediția din 9 feb. 2026) și pagina aplicației pentru contribuabili (modificată la 31 mar. 2026) spun că tokenurile permit autentificarea până la 31 dec. 2026. Pagina de întrebări și răspunsuri a ministerului spune că acesta a decis să păstreze tokenurile în KSeF 2.0 fără dată de sfârșit (răspunsul 39). Un tichet public (issue) din depozitul KSeF API al ministerului îi cere să lămurească diferența. Verificat pe 2 oct. 2026. Până la clarificare, așteptați-vă să reînnoiți tokenul dacă ministerul stabilește o dată de sfârșit. Autentificarea cu certificat nu este încă acceptată, așa că un token este singura cale de acces. Consultați manualul, întrebările și răspunsurile și tichetul.