Coduri de eroare
Coduri de eroare
Când API-ul e-bon respinge o cerere, returnează un statut HTTP non-2xx și un corp JSON cu un câmp stabil error.code. Această pagină listează fiecare cod pe care îl poți primi, ce înseamnă și cum recuperezi.
Folosește-o când vrei să:
- Identifici un
error.codenecunoscut returnat de API. - Decizi dacă o cerere eșuată poate fi reîncercată în siguranță.
- Construiești tratarea erorilor afișate utilizatorilor în POS, aplicația mobilă sau sistemul de back-office.
Înțelege plicul de eroare
Fiecare răspuns de eroare folosește aceeași formă JSON:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "path": "body.amount", "message": "Expected number, received string" }
]
}
}
code— un identificator stabil din lista de mai jos. Ramifică logica clientului tău pe această valoare, nu pe mesajul lizibil.message— o descriere scurtă în limba engleză, destinată jurnalelor și tichetelor de suport. Tradu-l sau rescrie-l înainte să-l afișezi utilizatorilor finali.details— opțional. Întotdeauna prezent pentruVALIDATION_ERRORca un tablou de perechi{ path, message }. Poate apărea peBAD_REQUEST,CONFLICTșiUNPROCESSABLE_ENTITYcu date specifice rutei.
{ "code", "message", "status" } la nivelul de top, nu este împachetat în { "error": { ... } }. Vezi Reîncearcă cererile limitate.Tratează erorile de autentificare
UNAUTHORIZED — 401
Primești acest cod când cererea nu are un credențial valid — antetul Authorization: Bearer <token> sau x-api-key lipsește, este malformat, are o semnătură invalidă sau tokenul a expirat.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid Authorization header. Expected: Bearer <token>"
}
}
Cum tratezi:
- Pentru clienții JWT, reîmprospătează tokenul de acces prin
POST /api/v1/auth/refreshși reîncearcă cererea o dată. - Pentru clienții cu cheie API, verifică în pagina de chei API din portal că cheia există și este activă. Rotește cheia dacă a fost dezactivată.
- După reîmprospătare sau rotire reușită, cererea originală poate fi reîncercată în siguranță.
FORBIDDEN — 403
Credențialul este valid, dar nu are permisiune pentru acțiunea cerută — utilizatorul JWT nu are rolul necesar, sau cheia API nu are scope-urile necesare.
{
"error": {
"code": "FORBIDDEN",
"message": "Insufficient role. Required: admin or owner"
}
}
Cum tratezi:
- Nu reîncerca cu același credențial — va eșua la fel.
- Pentru clienții JWT, autentifică-te ca un utilizator cu rolul necesar.
- Pentru chei API, generează o cheie nouă cu scope-urile necesare din portal. Vezi API autentificare pentru lista completă de scope-uri.
Corectează erorile de validare
VALIDATION_ERROR — 400
Corpul cererii, query string-ul sau antetele nu corespund schemei pentru endpoint. Tabloul details listează întotdeauna fiecare câmp invalid și motivul respingerii.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "path": "body.items.0.quantity", "message": "Expected number, received string" },
{ "path": "body.paymentType", "message": "Invalid enum value." }
]
}
}
Cum tratezi:
- Parcurge
details[*].pathpentru a localiza fiecare câmp invalid din cererea ta. - Afișează mesajele de la nivel de câmp lângă input-urile corespunzătoare din interfața ta.
- După corectarea fiecărui câmp, cererea poate fi reîncercată în siguranță.
O variantă obișnuită: un antet Idempotency-Key invalid (trebuie să aibă 1–128 de caractere — litere, cifre, - și _) returnează VALIDATION_ERROR cu valoarea problematică în details. Vezi Idempotență și reîncercări.
BAD_REQUEST — 400
Corpul este corect structural, dar încalcă o regulă semantică pe care validarea de schemă nu o poate exprima — de exemplu, două câmpuri reciproc exclusive trimise împreună.
{
"error": {
"code": "BAD_REQUEST",
"message": "Cannot specify both 'startTime' and 'cursor'."
}
}
Cum tratezi: Citește message, ajustează cererea și reîncearcă.
Rezolvă erorile de resurse
NOT_FOUND — 404
ID-ul resursei din cerere nu există (sau nu este vizibil pentru credențialul curent).
{
"error": {
"code": "NOT_FOUND",
"message": "Device dev_abc123 not found."
}
}
Cum tratezi: Verifică ID-ul resursei. Nu reîncerca cu același ID — listează colecția părinte pentru a descoperi unul valid.
CONFLICT — 409
Cererea intră în coliziune cu starea curentă a resursei. Cauze frecvente:
- Replay al unei chei de idempotență cu un corp diferit.
- Un dispozitiv (AMEF) deja revendicat de altă organizație.
- Un câmp unic (email, slug, cod) deja folosit.
{
"error": {
"code": "CONFLICT",
"message": "Device dev_abc123 is already claimed by another organization."
}
}
Cum tratezi: Citește message pentru a identifica conflictul specific. Reîncercarea fără rezolvarea stării de bază va eșua din nou — eliberează resursa, schimbă câmpul duplicat sau generează o cheie de idempotență nouă, după caz.
UNPROCESSABLE_ENTITY — 422
Corpul se parsează corect, dar încalcă o regulă de business — de exemplu, totalurile pe linii ale unui bon fiscal nu se adună la totalul declarat, sau o restituire mai mare decât tranzacția originală.
{
"error": {
"code": "UNPROCESSABLE_ENTITY",
"message": "Receipt total does not match the sum of line items.",
"details": { "expected": 119.0, "received": 120.0 }
}
}
Cum tratezi: Folosește message și details pentru a corecta încălcarea regulii de business, apoi retrimite cererea.
Reîncearcă cererile limitate
RATE_LIMIT_EXCEEDED — 429
Ai depășit bugetul de cereri per cheie (sau per IP). Răspunsul include un antet Retry-After în secunde.
HTTP/1.1 429 Too Many Requests
Retry-After: 47
Content-Type: application/json
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests, please try again later.",
"status": 429
}
Cum tratezi:
- Așteaptă numărul de secunde din
Retry-Afterînainte să reîncerci. - Adaugă jitter când mai mulți clienți partajează o cheie, ca să eviți rafalele sincronizate.
- Pentru debit susținut peste limita curentă, contactează suportul pentru a ridica bugetul per cheie în loc să reîncerci prin limită.
{ "error": { ... } }. Citește code de la nivelul de top doar pentru acest statut.Tratează limitele de plan
TIER_LIMIT_EXCEEDED — 403
O cotă a planului de abonament este epuizată — de obicei plafonul lunar de bonuri fiscale pe planul curent.
{
"error": {
"code": "TIER_LIMIT_EXCEEDED",
"message": "Monthly receipt quota exceeded for the Starter plan."
}
}
Cum tratezi:
- Afișează un mesaj clar de upgrade către proprietarul contului.
- Trimite-l la Facturare și abonamente pentru a schimba planul.
- Cotele se resetează la începutul fiecărei perioade de facturare — operațiunile reiau automat odată ce noua perioadă începe.
Recuperează după erori de server
INTERNAL_ERROR — 500
A apărut o problemă pe partea e-bon care nu este clasificată ca o eroare mai specifică.
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred"
}
}
Cum tratezi:
- Capturează antetul de răspuns
X-Request-Id— identifică cererea eșuată în jurnalele noastre. - Reîncearcă cu backoff exponențial și jitter (nu reîncerca strâns).
- Dacă eroarea persistă, deschide un tichet de suport și include valoarea
X-Request-Id. Vezi Trasarea cererilor și jurnalizare.
SERVICE_UNAVAILABLE — 503
O dependență din aval este temporar indisponibilă. Cazul cel mai frecvent este un dispozitiv fiscal (AMEF) care este offline sau nu are un controller asignat. Indisponibilitățile de stocare cloud (de exemplu pentru încărcările de logo) apar tot aici.
{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Device is offline or has no controller assigned"
}
}
Cum tratezi:
- Verifică starea conexiunii dispozitivului în portal sau prin API-ul Devices.
- Reîncearcă cu backoff exponențial și jitter — răspunsurile 503 nu includ un antet
Retry-After. - Informează operatorul dacă dispozitivul rămâne offline ca să-l poată reporni sau reconecta.
Mapează statutul HTTP la cod de eroare
Folosește acest tabel când scrii reguli de proxy, WAF sau observabilitate. Ramifică pe error.code (nu pe statut) când două coduri partajează același statut.
| Statut HTTP | Coduri care îl folosesc |
|---|---|
| 400 | VALIDATION_ERROR, BAD_REQUEST |
| 401 | UNAUTHORIZED |
| 403 | FORBIDDEN, TIER_LIMIT_EXCEEDED |
| 404 | NOT_FOUND |
| 409 | CONFLICT |
| 422 | UNPROCESSABLE_ENTITY |
| 429 | RATE_LIMIT_EXCEEDED |
| 500 | INTERNAL_ERROR |
| 503 | SERVICE_UNAVAILABLE |
Pași următori
- API autentificare — endpoint-urile care emit și reîmprospătează JWT-uri.
- Arhitectura autentificării — modelul JWT și cheie API din spatele răspunsurilor 401 și 403.
- Idempotență și reîncercări — regulile
Idempotency-Keyși semantica reîncercării. - Trasarea cererilor și jurnalizare — antetul
X-Request-Idde citat în tichetele de suport. - Facturare și abonamente — cotele per plan din spatele
TIER_LIMIT_EXCEEDED. - Erori SDK — ierarhia de clase
ApiErrordin partea de client care împachetează același plic. - Glosar — terminologia folosită în documentație.
Stările pe care le vezi în bonuri, dispozitive și webhook-uri
Referință pentru fiecare valoare de stare pe care e-bon o întoarce în răspunsurile API, în plicurile de webhook și în portal — ce înseamnă și când o vezi.
Locații
Gestionează fiecare magazin, restaurant sau birou într-un singur loc — adaugă locații, atribuie dispozitive, compară performanța și acordă fiecărui responsabil acces potrivit din Portalul e-bon.