e-bon
e-bon.ro
SDK TypeScript

Pornire rapidă

Un parcurs pas cu pas — instalează @e-bon/sdk, obține o cheie API, instanțiază EBonClient, listează aparatele, emite un bon și tratează erorile fiscale.

Pornire rapidă

Această pagină te duce de la un proiect gol la o integrare e-bon funcțională, care îți listează aparatele fiscale și emite un bon pe unul dintre ele. Timp total: aproximativ zece minute, odată ce ai o cheie API la îndemână.

Verifică cerințele

  • O organizație e-bon pe planul Pro sau mai sus (planul Free blochează crearea cheilor API — vezi Prezentare generală API › Restricții pe planuri).
  • Rolul de Owner sau Admin pe acea organizație.
  • Cel puțin un aparat fiscal revendicat de o instanță a aplicației mobile E-BON, ca să existe unde să se tipărească bonurile.
  • Node 22+ (sau Deno / Bun / un browser modern) — SDK-ul se bazează pe fetch și WebSocket native.

Instalează SDK-ul

Adaugă @e-bon/sdk în proiectul tău. Pachetul este astăzi privat în registry-ul e-bon; odată publicat, este o singură dependență:

pnpm add @e-bon/sdk

SDK-ul vine din start cu declarații TypeScript. Nu este nevoie de un pachet însoțitor @types/*.

Generează o cheie API

Cheile API se creează din Portalul e-bon, la Chei API. Autentifică-te la https://app.e-bon.ro, deschide Chei API din meniul lateral, apasă Creează cheie API, dă-i o etichetă și alege cel mai mic set de permisiuni de care integrarea ta are nevoie efectiv.

Portalul afișează secretul complet o singură dată, într-un modal de dezvăluire unică. Copiază-l în depozitul tău de secrete (1Password, Vault, furnizorul tău de CI, o variabilă de mediu) înainte să închizi modalul.

Tratează cheia ca pe o parolă. Formatul complet este ebon_live_<orgId>_<32-hex>, iar serverul verifică prefixul strict. Vezi Autentificare pentru catalogul de permisiuni și fluxul de rotație.

Instanțiază EBonClient

Citește secretul din mediu și pasează-l o singură dată constructorului:

import { EBonClient } from '@e-bon/sdk';

const apiKey = process.env.EBON_API_KEY;
if (!apiKey) {
  throw new Error('EBON_API_KEY nu este setat');
}

export const client = new EBonClient({
  baseUrl: 'https://api.e-bon.ro',
  apiKey,
});

Poți păstra acest client ca singleton la nivel de modul — este sigur de partajat între cereri. SDK-ul nu administrează el însuși un pool de conexiuni; se bazează pe keep-alive HTTP nativ al runtime-ului.

Listează aparatele

Primul tur util este listarea aparatelor din organizația ta. client.devices.list() returnează un Device[]:

import type { Device } from '@e-bon/sdk';

const devices: Device[] = await client.devices.list();

for (const device of devices) {
  console.log(`${device.id} · ${device.name} · status=${device.status}`);
}

Poți filtra lista după status sau locationId prin interfața tipată ListDevicesQuery:

const onlineDevices = await client.devices.list({ status: 'online' });

Emite un bon

Bonurile se creează cu client.receipts.create(), care primește un CreateReceiptBody. Forma obligatorie — produse, plăți, total, defalcare TVA și operatorul care a încasat — vine direct din @e-bon/sdk:

import type { CreateReceiptBody } from '@e-bon/sdk';

const body: CreateReceiptBody = {
  deviceId: 'dev_abc123',
  type: 'sale',
  items: [
    {
      description: 'Espresso',
      quantity: 1,
      unitPrice: 12.0,
      vatRate: 9,
      total: 12.0,
    },
  ],
  payments: [{ method: 'cash', amount: 12.0 }],
  total: 12.0,
  vatBreakdown: [{ vatRate: 9, base: 11.01, vat: 0.99 }],
  operatorId: 'op_001',
};

const receipt = await client.receipts.create(body);
console.log('bon stocat', receipt.id);

Atenție: client.receipts.create() stochează un bon; el singur nu antrenează imprimanta. Ca să trimiți o comandă de tipărire fiscală și să fie executată pe AMEF, folosește client.commands.send():

const command = await client.commands.send({
  deviceId: 'dev_abc123',
  type: 'print_receipt',
  payload: body,
});

console.log(`comanda ${command.id} status=${command.status}`);

Comenzile sunt asincrone. Apelul returnează imediat cu status: "pending", iar tu fie faci polling pe client.commands.get(id), fie te abonezi la evenimentele command.completed / command.failed — vezi Evenimente.

Tratează erorile

Fiecare eșec este una din două clase de excepție. Înfășoară-ți apelurile fiscale în consecință:

import { EBonApiError, FiscalError } from '@e-bon/sdk';

try {
  await client.commands.send({
    deviceId: 'dev_abc123',
    type: 'print_receipt',
    payload: body,
  });
} catch (err) {
  if (err instanceof FiscalError) {
    // Eșec la imprimantă. err.code este un ErrorCode (E100…E901).
    if (err.retryable) {
      // Sigur de retrimis cu același Idempotency-Key.
    } else {
      // Necesită acțiune din partea operatorului (hârtie, memorie fiscală plină, …).
    }
    return;
  }

  if (err instanceof EBonApiError) {
    // Eșec la nivel HTTP. Ramifică pe err.status / err.code.
    if (err.status === 429 && err.retryAfter) {
      await sleep(err.retryAfter * 1000);
      return;
    }
    throw err;
  }

  throw err;
}

Modelul complet de eroare — inclusiv re-exportul RETRYABLE_ERRORS și helper-ul isRetryable — este documentat pe pagina Erori.

Unde mergi mai departe

  • Evenimente — ascultă pentru receipt.created, command.completed și restul, în loc să faci polling.
  • Erori — modelul complet de retry pentru FiscalError.
  • API › Bonuri și API › Comenzi — referința la nivel de protocol pentru cele două endpoint-uri folosite mai sus.