e-bon
e-bon.ro
Referință API

Rapoarte

Endpoint-uri de rapoarte live de pe dispozitiv — citește memoria fiscală (istoric Z) și jurnalul electronic, tipărește rapoarte X/Z/periodice și exportă arhiva lunară ANAF, direct de pe AMEF.

Rapoarte

API-ul de Rapoarte citește rapoartele live de pe dispozitivul fiscal. Nu există un model de rapoarte stocate: memoria fiscală (MF) și jurnalul electronic (JE) ale AMEF-ului sunt înregistrarea legală, așa că fiecare endpoint de mai jos trimite o comandă către dispozitiv prin controllerul său și returnează sincron răspunsul dispozitivului. Toate rutele se află sub /api/v1/devices/{deviceId}/reports.

Fiecare endpoint necesită scope-ul reports și acceptă fie o cheie API (x-api-key / Authorization: Bearer …), fie un JWT de Portal. Vezi Autentificare › Alegerea scope-urilor.

Deoarece rapoartele se citesc live, dispozitivul trebuie să fie online (aplicația controller conectată). În caz contrar, endpoint-urile returnează 503 cu un cod de conectivitate (E600/E601/E602) — vezi Erori.
Intervalele mari pot dura: citirile de jurnal electronic și exporturile ANAF rulează până la ~3 minute înainte de timeout pe server. Dimensionează corespunzător timeout-urile clientului (SDK-ul oficial o face deja).

Descoperirea capabilităților

GET /api/v1/devices/{deviceId}/reports/capabilities

Citește ce operațiuni de raportare suportă driverul dispozitivului. Condiționează UI-ul pe aceste flag-uri — nu orice AMEF suportă orice operațiune.

Răspuns (200 OK)

{
  "capabilities": {
    "canReadMfStructured": true,
    "canReadEjStructured": true,
    "canExportANAFByDate": true,
    "canExportANAFByZRange": false,
    "supportsAnafStorageRamDisk": true,
    "supportsAnafStorageSdCard": false,
    "supportsPeriodicByDate": true,
    "supportsPeriodicByZNumber": true
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:00.000Z"
}

GET /api/v1/devices/{deviceId}/reports/telemetry

Citește telemetria contoarelor din memoria fiscală și jurnalul electronic (utilizare, capacitate, flag-uri de umplere).

Răspuns (200 OK)

{
  "mfInfo": {
    "fiscalizationDate": "2025-01-10T00:00:00",
    "lastClosedZ": 412,
    "zUsed": 412,
    "zCapacity": 2500,
    "nearFull": false,
    "full": false
  },
  "ejInfo": {
    "counterUnit": "lines",
    "used": 182400,
    "remaining": 817600,
    "capacity": 1000000,
    "nearFull": false,
    "full": false
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:00.000Z"
}

mfInfo.fiscalizationDate este null cât timp dispozitivul nu este fiscalizat (încă nu există o dată de fiscalizare) sau când firmware-ul nu poate raporta data.

ejInfo este doar atât de numeric pe cât permite protocolul dispozitivului. counterUnit spune ce numără used: 'lines' (Custom: jurnalul este un buffer de linii, deci remaining/capacity sunt valori reale), 'documents' (Datecs: jurnalul este o colecție de documente, used este contorul global de documente, iar remaining/capacity sunt null pentru că firmware-ul nu raportează o capacitate numerică a jurnalului) sau 'none' (Tremol: fără contor de utilizare pe fir, used rămâne 0). Pe orice protocol, semnalele corecte de umplere sunt flag-urile nearFull/full.

Selectarea intervalului

Citirile MF/EJ și tipărirea periodică acceptă fie un interval de date calendaristice, fie un interval de numere Z (ambele inclusive):

ParametruTipNote
fromDatestringYYYY-MM-DD, împreună cu toDate.
toDatestringYYYY-MM-DD, împreună cu fromDate.
fromZinteger>= 1, împreună cu toZ.
toZinteger>= fromZ, împreună cu fromZ.

Memoria fiscală (istoric Z)

GET /api/v1/devices/{deviceId}/reports/mf

Citește rândurile de închidere Z din memoria fiscală a dispozitivului pentru intervalul dat. Aceasta este sursa istoricului Z — raportul Z este o operațiune destructivă de sfârșit de zi, nu o interogare; înregistrarea sa istorică trăiește în memoria fiscală.

curl "https://api.e-bon.ro/api/v1/devices/dev_pos_01/reports/mf?fromDate=2026-06-01&toDate=2026-06-30" \
  -H "x-api-key: $EBON_API_KEY"

Răspuns (200 OK)

{
  "mf": {
    "entries": [
      { "date": "2026-06-01T20:01:12", "zNumber": 401, "grossTotalCents": 1284500 }
    ],
    "fromDate": "2026-06-01T00:00:00",
    "toDate": "2026-06-30T23:59:59",
    "fromZ": 401,
    "toZ": 430
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:00.000Z"
}

Jurnalul electronic

GET /api/v1/devices/{deviceId}/reports/ej

Citește blocurile de text verbatim ale jurnalului electronic, câte un bloc pentru fiecare închidere Z din interval.

Răspuns (200 OK)

{
  "ej": {
    "blocks": [
      { "zNumber": 401, "lines": ["BON FISCAL", "1 x Espresso   9.00", "TOTAL   9.00"] }
    ],
    "fromDate": "2026-06-01T00:00:00",
    "toDate": "2026-06-01T23:59:59",
    "fromZ": 401,
    "toZ": 401,
    "totalLines": 3
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:00.000Z"
}

Tipărirea rapoartelor

POST /api/v1/devices/{deviceId}/reports/x

Produce un raport X (totaluri curente zilnice, non-destructiv) pe imprimanta dispozitivului. Returnează sumarul raportat de dispozitiv; totalurile structurate depind de suportul driverului.

Răspuns (200 OK)

{
  "report": {
    "reportType": "x",
    "deviceId": "dev_pos_01",
    "totals": { "sales": 0, "refunds": 0, "net": 0 },
    "vatBreakdown": [],
    "receiptCount": 0,
    "timestamp": "2026-07-13T10:00:00.000Z"
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:01.000Z"
}

POST /api/v1/devices/{deviceId}/reports/z

Rulează un raport Z (închiderea zilei fiscale) pe dispozitiv. Destructiv: resetează contoarele zilnice și avansează memoria fiscală. Același format de răspuns ca tipărirea X. Un dispozitiv care necesită Z înaintea altor vânzări raportează E303 la celelalte operațiuni — vezi Erori.

POST /api/v1/devices/{deviceId}/reports/periodic

Tipărește un raport periodic din memoria fiscală pe hârtia dispozitivului pentru intervalul dat (body JSON, vezi Selectarea intervalului).

curl -X POST "https://api.e-bon.ro/api/v1/devices/dev_pos_01/reports/periodic" \
  -H "x-api-key: $EBON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "fromDate": "2026-06-01", "toDate": "2026-06-30" }'

Răspuns (200 OK)

{ "success": true, "deviceId": "dev_pos_01", "timestamp": "2026-07-13T10:00:00.000Z" }

Exportul arhivei ANAF

POST /api/v1/devices/{deviceId}/reports/anaf-export

Exportă arhiva lunară ANAF a dispozitivului (ZIP-ul semnat produs de AMEF pentru autoritatea fiscală) pentru intervalul dat. Body-ul acceptă câmpurile de interval plus un storageTarget opțional ("ramdisk" sau "sdcard") pe dispozitivele care oferă ambele opțiuni de stocare.

Dispozitivul construiește arhiva asincron — lunile aglomerate pot dura legitim minute întregi. Cererea așteaptă întreaga construcție + transfer; câmpul opțional timeoutMs din body setează termenul limită pe dispozitiv (întregul export, limitat la 30 s – 30 min, implicit 10 min), iar gateway-ul așteaptă peste acest termen. Preferă să mărești timeoutMs în loc să abandonezi și să reîncerci: imprimanta continuă construcția oricum, iar o reîncercare o reconstruiește de la zero.

Arhiva este returnată codificată base64; decodeaz-o și salveaz-o ca .zip.

curl -X POST "https://api.e-bon.ro/api/v1/devices/dev_pos_01/reports/anaf-export" \
  -H "x-api-key: $EBON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "fromDate": "2026-06-01", "toDate": "2026-06-30" }'

Răspuns (200 OK)

{
  "export": {
    "filename": "pkcs7export.zip",
    "base64": "UEsDBBQAAAAI…",
    "sizeBytes": 482133
  },
  "deviceId": "dev_pos_01",
  "timestamp": "2026-07-13T10:00:00.000Z"
}

Coduri de eroare

StatusCodSemnificație
400VALIDATION_ERRORInterval sau body lipsă/invalid.
404NOT_FOUNDDispozitivul nu există în organizație.
422E2xx/E3xxDispozitivul a refuzat operațiunea (ex. E303 — Z necesar).
503E600/E601/E602Fără controller / controller offline / transport local căzut.
500INTERNAL_ERRORDispozitivul a răspuns fără payload-ul așteptat.