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

Webhook-uri

Endpoint-uri REST pentru gestionarea abonamentelor webhook — creare, listare, actualizare, ștergere, rotire chei de semnare, livrări de test și inspecția istoricului de livrări.

Webhook-uri

API-ul de webhook-uri îți permite să abonezi un endpoint HTTPS extern la evenimentele care se întâmplă în e-bon — bonuri create, comenzi finalizate, dispozitive online/offline, rapoarte generate etc. Toate endpoint-urile din acest grup sunt sub /api/v1/org/webhooks și sunt administrative: gestionează abonamentul, nu payload-urile livrate. Odată ce există un abonament, e-bon trimite fiecare eveniment care se potrivește către URL-ul tău cu o semnătură HMAC-SHA256 în antetul X-E-Bon-Signature.

Spre deosebire de majoritatea referințelor API, rutele de administrare a webhook-urilor nu se autentifică prin cheie API. Stau în spatele middleware-ului JWT din Portal (jwtAuth) și mai cer ca utilizatorul apelant să aibă rolul de Owner sau Admin pe organizație. Nu există nicio permisiune de cheie API care să dea acces la administrarea webhook-urilor — generează un token de sesiune din Portal (POST /api/v1/auth/login) și folosește-l ca Authorization: Bearer <jwt>. Vezi Autentificare › Autentificare JWT.

Plicul de eroare, limitele de rată și convențiile de paginare sunt documentate o singură dată pe Prezentarea API-ului; pe această pagină listăm doar codurile de eroare specifice fiecărui endpoint.

Tipuri de evenimente

Abonamentele listează unul sau mai multe tipuri de evenimente din acest set fix:

EvenimentSe emite când…
receipt.createdUn bon a fost persistat prin POST /receipts.
receipt.failedSalvarea unui bon a eșuat.
command.completedO comandă fiscală s-a încheiat cu succes pe AMEF.
command.failedO comandă fiscală a fost respinsă de AMEF.
command.timeoutO comandă fiscală nu a primit răspuns în fereastra de timeout.
device.onlineConexiunea WebSocket a unui dispozitiv s-a ridicat.
device.offlineConexiunea WebSocket a unui dispozitiv a căzut.
report.generatedUn raport X / Z / JE / MF a fost stocat.
webhook.testTrimis doar de endpoint-ul Trimite o livrare de test de mai jos.

GET /api/v1/org/webhooks

Listează toate abonamentele webhook ale organizației. Cheile de semnare nu sunt returnate niciodată de acest endpoint — cheia brută se afișează doar la creare și la rotire.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Răspuns (200 OK)

{
  "webhooks": [
    {
      "id": "wh_abc123",
      "orgId": "acme_corp",
      "url": "https://hooks.example.com/e-bon",
      "description": "Integrare contabilitate",
      "events": ["receipt.created", "report.generated"],
      "enabled": true,
      "failureCount": 0,
      "lastDeliveryAt": "2026-04-09T08:09:55.000Z",
      "lastDeliveryStatus": "success",
      "createdAt": "2026-03-01T12:00:00.000Z",
      "updatedAt": "2026-04-09T08:09:55.000Z",
      "createdBy": "user_xyz"
    }
  ]
}

Exemplu

curl https://api.e-bon.ro/api/v1/org/webhooks \
  -H "Authorization: Bearer <portal-jwt>"

Coduri de eroare

  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.

Catalogul HTTP complet este pe Prezentare API › Catalogul codurilor de eroare HTTP.

POST /api/v1/org/webhooks

Creează un abonament webhook nou. Cheia de semnare brută este returnată o singură dată în câmpul secret al răspunsului — stocheaz-o imediat în managerul tău de secrete. Nu există niciun endpoint care să returneze cheia din nou.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Corpul cererii

CâmpTipObligatoriuNote
urlstringdaTrebuie să fie un URL HTTPS valid (serverul respinge orice URL care nu începe cu https://).
descriptionstringnuEtichetă liberă, ≤ 500 caractere.
eventsstringdaCel puțin un tip de eveniment din tabelul de mai sus.
enabledbooleannuImplicit true. Setează false ca să creezi un abonament care nu primește încă livrări.

Răspuns (201 Created)

{
  "webhook": {
    "id": "wh_abc123",
    "orgId": "acme_corp",
    "url": "https://hooks.example.com/e-bon",
    "description": "Integrare contabilitate",
    "events": ["receipt.created", "report.generated"],
    "enabled": true,
    "failureCount": 0,
    "createdAt": "2026-04-09T08:10:00.000Z",
    "createdBy": "user_xyz",
    "secret": "whsec_8f3a9d…"
  }
}

Exemplu

curl -X POST https://api.e-bon.ro/api/v1/org/webhooks \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/e-bon",
    "description": "Integrare contabilitate",
    "events": ["receipt.created", "report.generated"]
  }'

Coduri de eroare

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea Zod (URL non-HTTPS, events lipsă/gol, description peste 500 caractere, tip de eveniment necunoscut).
  • UNAUTHORIZED (401) — JWT lipsă sau invalid.
  • FORBIDDEN (403) — apelantul nu are rol de Owner sau Admin.

GET /api/v1/org/webhooks/{id}

Returnează un singur abonament webhook după ID. Cheia nu este returnată niciodată.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Parametri cale

ParametruTipNote
idstringID-ul abonamentului webhook.

Răspuns (200 OK)

{
  "webhook": {
    "id": "wh_abc123",
    "orgId": "acme_corp",
    "url": "https://hooks.example.com/e-bon",
    "description": "Integrare contabilitate",
    "events": ["receipt.created", "report.generated"],
    "enabled": true,
    "failureCount": 0,
    "createdAt": "2026-03-01T12:00:00.000Z"
  }
}

Exemplu

curl https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
  -H "Authorization: Bearer <portal-jwt>"

Coduri de eroare

PATCH /api/v1/org/webhooks/{id}

Actualizează unul sau mai multe câmpuri pe un webhook existent. Trebuie furnizat cel puțin un câmp. Reactivarea unui webhook dezactivat anterior (enabled: true) resetează și failureCount la 0.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Corpul cererii

CâmpTipNote
urlstringDacă e furnizat, trebuie să fie HTTPS.
descriptionstring≤ 500 caractere.
eventsstringCel puțin un tip de eveniment din tabelul de mai sus.
enabledbooleanPornește/oprește livrările.

Răspuns (200 OK)

Aceeași formă ca la GET /api/v1/org/webhooks/{id} — înregistrarea actualizată, fără cheie.

Exemplu

curl -X PATCH https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
  -H "Authorization: Bearer <portal-jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "events": ["receipt.created"], "enabled": true }'

Coduri de eroare

  • VALIDATION_ERROR (400) — corpul nu a trecut validarea Zod sau e gol (niciun câmp de actualizat).
  • NOT_FOUND (404) — nu există un webhook cu acel ID în organizația ta.
  • UNAUTHORIZED / FORBIDDEN — vezi Autentificare › Erori de autentificare.

DELETE /api/v1/org/webhooks/{id}

Șterge definitiv un abonament webhook și toate înregistrările de livrare stocate în subcolecția lui deliveries. Returnează 204 No Content la succes.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Exemplu

curl -X DELETE https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123 \
  -H "Authorization: Bearer <portal-jwt>"

Coduri de eroare

POST /api/v1/org/webhooks/{id}/rotate-secret

Generează o cheie de semnare nouă pentru webhook și o înlocuiește pe cea anterioară. Cheia nouă este returnată o singură dată în răspuns — stocheaz-o înainte ca cererea să se închidă.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Răspuns (200 OK)

{
  "secret": "whsec_VALOARE_NOUA…"
}

Exemplu

curl -X POST https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/rotate-secret \
  -H "Authorization: Bearer <portal-jwt>"
Rotirea este imediată. Orice livrare în curs semnată cu cheia veche va valida în continuare la consumator până la cut-over — coordonează schimbul de cheie cu serviciul care verifică semnăturile.

Coduri de eroare

POST /api/v1/org/webhooks/{id}/test

Trimite o livrare de test sincronă cu tipul de eveniment webhook.test către URL-ul webhook-ului. Returnează înregistrarea de livrare creată (cu statusul HTTP încercat, fragmentul de corp al răspunsului și orice mesaj de eroare) ca să poți depana endpoint-ul fără să aștepți un eveniment real.

  • Autentificare: JWT din Portal, rol Owner sau Admin.
  • Efect lateral: persistă o înregistrare de livrare sub webhooks/{id}/deliveries.

Răspuns (200 OK)

{
  "delivery": {
    "id": "del_test_abc",
    "webhookId": "wh_abc123",
    "orgId": "acme_corp",
    "eventType": "webhook.test",
    "payload": {
      "id": "evt_…",
      "type": "webhook.test",
      "createdAt": "2026-04-09T08:10:00.000Z",
      "orgId": "acme_corp",
      "data": { "test": true, "message": "This is a test event from e-bon." }
    },
    "status": "success",
    "attempt": 1,
    "httpStatus": 200,
    "createdAt": "2026-04-09T08:10:00.000Z",
    "attemptedAt": "2026-04-09T08:10:00.500Z"
  }
}

Exemplu

curl -X POST https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/test \
  -H "Authorization: Bearer <portal-jwt>"

Coduri de eroare

GET /api/v1/org/webhooks/{id}/deliveries

Returnează încercările de livrare recente pentru webhook, cele mai noi primele. Fiecare livrare include payload-ul trimis, contorul de încercări, statusul HTTP returnat de endpoint-ul tău, fragmentul de corp al răspunsului și orice mesaj de eroare capturat de retry-sweeper.

  • Autentificare: JWT din Portal, rol Owner sau Admin.

Parametri query

ParametruTipImplicitNote
limitinteger50Mărime pagină, 1200.
statusstringUna dintre pending, success, failed.

Răspuns (200 OK)

{
  "deliveries": [
    {
      "id": "del_abc123",
      "webhookId": "wh_abc123",
      "orgId": "acme_corp",
      "eventType": "receipt.created",
      "payload": { "id": "evt_…", "type": "receipt.created" },
      "status": "success",
      "attempt": 1,
      "httpStatus": 200,
      "createdAt": "2026-04-09T08:09:55.000Z",
      "attemptedAt": "2026-04-09T08:09:55.300Z"
    }
  ]
}

Exemplu

curl "https://api.e-bon.ro/api/v1/org/webhooks/wh_abc123/deliveries?status=failed&limit=20" \
  -H "Authorization: Bearer <portal-jwt>"

Coduri de eroare

  • VALIDATION_ERROR (400) — query invalid (limit > 200, valoare status necunoscută).
  • NOT_FOUND (404) — nu există un webhook cu acel ID în organizația ta.
  • UNAUTHORIZED / FORBIDDEN — vezi Autentificare › Erori de autentificare.

Vezi și