e-bon
e-bon.ro
SDK TypeScript

Configurează transportul HTTP

Configurează autentificarea, timeout-urile, gestionarea erorilor, cheile de idempotență și rotația credențialelor când folosești clientul HTTP @e-bon/sdk.

Configurează transportul HTTP

Fiecare apel SDK — client.receipts, client.devices, client.commands și restul — trimite cererile printr-un singur transport HTTP partajat. Această pagină îți arată cum să-l configurezi: alegi metoda de autentificare, setezi timeout-urile, gestionezi erorile, reîncerci în siguranță cu chei de idempotență și roteşti credențialele la runtime.

Alege o metodă de autentificare

SDK-ul suportă două metode de autentificare. Transmite fie o cheie API, fie un jeton bearer când construiești clientul.

Folosește o cheie API

Cheile API sunt cea mai simplă opțiune pentru integrări server-la-server.

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

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

SDK-ul trimite cheia în antetul X-API-Key la fiecare cerere.

Folosește un jeton bearer

Folosește un jeton JWT bearer când ai nevoie de credențiale cu durată scurtă sau de autentificare per utilizator.

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

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

SDK-ul trimite jetonul în Authorization: Bearer <jeton> la fiecare cerere.

Dacă transmiți atât apiKey, cât și token, jetonul câștigă — cheia API este ignorată. Acest lucru contează când migrezi un client de durată lungă de la autentificare cu cheie API la autentificare JWT.

Setează timeout-urile

Cererile au implicit un timeout de 30 de secunde. Suprascrie timeout-ul la nivel de client când îl construiești:

const client = new EBonClient({
  baseUrl: 'https://api.e-bon.ro',
  apiKey: process.env.EBON_API_KEY,
  timeout: 10_000, // 10 secunde pentru fiecare cerere
});

Când o cerere depășește timeout-ul, SDK-ul anulează fetch-ul subiacent și aruncă EBonApiError cu code === 'TIMEOUT' și status === 0.

Gestionează erorile

Fiecare eroare aruncată de SDK este o instanță de EBonApiError. Ramifică pe err.status (codul de stare HTTP) pentru a decide ce faci — este câmpul cel mai fiabil pentru toate tipurile de erori.

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

try {
  const receipt = await client.receipts.create(body);
} catch (err) {
  if (err instanceof EBonApiError) {
    switch (err.status) {
      case 0:
        // Eroare de rețea sau timeout — se poate reîncerca în siguranță
        console.error('Problemă de rețea:', err.message);
        break;
      case 401:
        // Credențiale lipsă sau expirate — reîmprospătează și reîncearcă
        await refreshCredentials();
        break;
      case 422:
        // Validarea a eșuat — inspectează err.details
        console.error('Erori de validare:', err.details);
        break;
      case 429:
        // Limită de rată atinsă — așteaptă err.retryAfter secunde
        await sleep((err.retryAfter ?? 1) * 1000);
        break;
      default:
        throw err;
    }
  }
}

Coduri de stare frecvente

StareSemnificațieAcțiune recomandată
0Eroare de rețea sau timeoutReîncearcă cu backoff
401NeautentificatReîmprospătează credențialele
404Resursa nu a fost găsităAfișează utilizatorului
422Validare eșuatăInspectează err.details
429Limită de rată atinsăAșteaptă err.retryAfter secunde
500599Eroare de serverReîncearcă cu backoff
Pentru erorile de limită de rată, SDK-ul populează err.retryAfter din antetul de răspuns Retry-After (în secunde). Pentru toate celelalte erori, retryAfter este undefined.

Reîncearcă în siguranță cu chei de idempotență

Apelurile POST și PATCH pot produce duplicate dacă le reîncerci după o eroare de rețea. Trimite același antet Idempotency-Key la fiecare reîncercare, iar API-ul returnează răspunsul stocat în cache într-o fereastră de 24 de ore — vezi referința Idempotență pentru contractul complet.

Învelește apelurile de scriere într-un mic helper care injectează antetul și reîncearcă la erori tranzitorii:

import { EBonClient, EBonApiError, type CreateReceiptBody, type Receipt } from '@e-bon/sdk';
import { randomUUID } from 'node:crypto';

async function createReceiptIdempotent(
  client: EBonClient,
  body: CreateReceiptBody,
): Promise<Receipt> {
  const idempotencyKey = randomUUID();
  let attempt = 0;

  while (true) {
    try {
      return await client.receipts.create(body, {
        headers: { 'Idempotency-Key': idempotencyKey },
      });
    } catch (err) {
      attempt++;
      const transient =
        err instanceof EBonApiError &&
        (err.status === 0 || err.status >= 500);

      if (transient && attempt < 3) {
        await sleep(2 ** attempt * 250);
        continue;
      }
      throw err;
    }
  }
}
Generează întotdeauna o cheie de idempotență proaspătă pentru fiecare operație logică (un bon = o cheie) și reutilizeaz-o la reîncercările aceleiași operații. Nu reutiliza niciodată o cheie pentru un alt corp de cerere — API-ul returnează răspunsul original din cache indiferent de ce trimiți.

Roteşte credențialele la runtime

Pentru clienții cu durată lungă, reîmprospătează jetonul bearer fără să reconstruiești clientul:

client.setToken(newAccessToken);

Următoarea cerere preia noua valoare. Cererile aflate deja în desfășurare păstrează credențialele pe care le-au capturat la pornire — setToken nu le anulează și nu le re-aplică.

Un șablon tipic de reîmprospătare la 401:

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

async function withRefresh<T>(call: () => Promise<T>): Promise<T> {
  try {
    return await call();
  } catch (err) {
    if (err instanceof EBonApiError && err.status === 401) {
      const fresh = await refreshAccessToken();
      client.setToken(fresh);
      return await call();
    }
    throw err;
  }
}

const receipt = await withRefresh(() => client.receipts.get(id));
Folosește acest șablon într-un singur wrapper partajat în jurul fiecărui apel SDK, astfel încât o reîmprospătare a jetonului dintr-o resursă să beneficieze următorul apel către orice altă resursă — toate folosesc același transport.

Unde mergi mai departe

  • Prezentare generală SDK — forma de înalt nivel a EBonClient și accesoarele de resurse.
  • Erori — forma completă EBonApiError și șablonul recomandat de reîncercare.
  • Evenimente — livrarea evenimentelor în timp real prin WebSocket.
  • Idempotență — regulile la nivel de protocol pentru reutilizarea Idempotency-Key și cache-ul de 24 de ore.
  • Limite de rată — semantica Retry-After pentru răspunsurile 429.
  • Erori API — catalogul complet al codurilor HTTP.