e-bon
e-bon.ro
Depanare

Eșecuri de livrare a webhook-urilor și auto-dezactivare

Cum interpretezi `lastError`, programul de retry pe 5 încercări, auto-dezactivarea după 20 de eșecuri și cum reactivezi un webhook în siguranță.

Când endpoint-ul tău nu mai primește evenimente webhook, întrebarea e mereu: a încetat e-bon să mai trimită sau a continuat să trimită dar endpoint-ul tău a început să eșueze? Această rețetă urmează întreg ciclul de eșec și auto-dezactivare ca să poți face diferența și să recuperezi.

Un webhook auto-dezactivat de platformă are enabled: false pe abonament. Până nu îl reactivezi prin PATCH /api/v1/org/webhooks/{id}, nu se mai trimite niciun eveniment nou — nici măcar webhook.test. Reîncercările deja în curs continuă până își epuizează încercările.

Cum funcționează livrarea și reîncercările

  • Timeout pe încercare — fiecare încercare de livrare are 10 secunde să întoarcă un răspuns 2xx. După aceea, cererea e abandonată și numărată ca eșec.
  • Backoff de retry — încercările eșuate sunt reluate pe un program fix: 1 min → 5 min → 30 min → 2 h → 12 h.
  • Număr maxim de încercări — 5 încercări în total. După a 5-a eșuată, livrarea trece la failed și nu mai e reîncercată niciodată.
  • Prag de auto-dezactivare — după 20 de livrări consecutive eșuate pe același webhook, abonamentul e setat automat pe enabled: false.
  • Captură de răspuns — până la 500 de caractere din corpul răspunsului endpoint-ului tău sunt stocate pe fiecare înregistrare de livrare ca să poți depana ce a întors serverul tău.
  • Procesare periodică a reîncercărilor — reîncercările în așteptare sunt preluate la fiecare 30 de secunde, deci o reîncercare programată se declanșează în ~30 s de la nextRetryAt.

Cauze probabile

  • Endpoint-ul răspunde non-2xx — orice altceva în afară de 200299 se numără ca eșec. Redirect-urile 301/302 nu sunt urmate.
  • Endpoint-ul depășește 10 sAbortController-ul pe încercare taie cererea chiar dacă handler-ul tău răspunde în cele din urmă.
  • Erori de hostname / TLS / DNSfetch respinge înainte să sosească răspunsul; mesajul ajunge în delivery.error.
  • Abonament auto-dezactivatfailureCount a ajuns la 20 și procesorul a oprit trimiterea evenimentelor noi către acest abonament.

Cum verifici

Răsfoiește istoricul de livrări pentru webhook-ul afectat:

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

O livrare eșuată arată așa:

{
  "id": "del_abc123",
  "status": "failed",
  "attempt": 5,
  "httpStatus": 502,
  "responseBody": "Bad Gateway",
  "error": "http 502",
  "attemptedAt": "2026-04-23T20:09:55.000Z"
}

Verifică webhook-ul părinte ca să vezi dacă a fost auto-dezactivat:

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

Caută "enabled": false și un failureCount mare (≥ 20).

Remediere

Repară endpoint-ul de bază

Asigură-te că endpoint-ul tău întoarce un 2xx în 10 secunde pentru orice payload pe care e-bon îl trimite. Confirmă întâi, apoi pune munca grea pe o coadă — corpul a fost capturat în responseBody (până la 500 de caractere), deci poți reproduce local.

Trimite o livrare de test

Odată ce endpoint-ul e sănătos, trimite un eveniment de test cu webhook-ul în starea curentă:

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

Vei primi un eveniment webhook.test. Confirmă că ajunge și că endpoint-ul tău întoarce 2xx. (Dacă webhook-ul e deja auto-dezactivat, endpoint-ul de test va respinge cu 409 CONFLICT până îl reactivezi — vezi pasul următor.)

Reactivează abonamentul

Dacă webhook-ul a fost auto-dezactivat, pune-l înapoi pe activ. Asta resetează și failureCount-ul pe partea de server la următoarea livrare reușită:

curl -X PATCH https://api.e-bon.ro/api/v1/org/webhooks/{webhookId} \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

Reia fereastra ratată doar dacă chiar ai nevoie

e-bon nu reia automat evenimentele care au fost trimise cât timp endpoint-ul tău era jos — au rămas pending, au fost reîncercate până la marca de 12 ore, apoi au trecut la failed. Dacă ai nevoie să recuperezi datele, interoghează resursa relevantă (de ex. GET /api/v1/receipts?since=…) și reconciliază cu starea ta.

Referință completă pe payload-uri: Evenimente webhook. CRUD pe abonament, rotație de secrete și endpoint-uri de istoric livrări: API Webhook-uri.

Tot blocat?

Deschide un caz de suport la support@e-bon.ro sau e-bon.ro/contact cu webhookId-ul, un deliveryId recent eșuat, responseBody-ul capturat și hostname-ul endpoint-ului tău, ca suportul să poată corela log-urile de trimitere.