GH GambleHub

Webhooks və hadisələrin idempotentliyi

TL; DR

Yaxşı vebhuk (HMAC/mTLS) imzalanmış, ümumiləşdirilə bilən və idempotent hadisədir, alıcıdan eksponensial backoff və duplikasiya ilə at-least-once modelinə uyğun olaraq çatdırılır. Zərf ('event _ id', 'type', 'ts', 'version', 'attempt', 'signature'), vaxt pəncərəsi (≤ 5 dəq), cavab kodları, retralar, DLQ və status-end-point haqqında razılaşın.


1) Rolları və çatdırılma modeli

Göndərici (siz/provayder): hadisəni formalaşdırır, imzalayır, 2xx-ə çatdırmağa çalışır, 3xx/4xx/5xx-də retrait (açıq «qəbul etməyin» istisna olmaqla), DLQ aparır, API replay verir.
Alıcı (partnyor/xidmətiniz): imza/vaxt pəncərəsini yoxlayır, dedup və idempotent emal edir, düzgün kodla cavab verir ,/status və/ack replay 'event _ id' ilə təmin edir.

Zəmanət: at-least-once. Alıcı dublikatları emal edə və nizam dəyişdirə bilməlidir.


2) Hadisə zərfi (envelope)

json
{
"event_id": "01HF7H9J9Q3E7DYT5Y6K3ZFD6M",
"type": "payout.processed",
"version": "2025-01-01",
"ts": "2025-11-03T12:34:56.789Z",
"attempt": 1,
"producer": "payments",
"tenant": "acme",
"data": {
"payout_id": "p_123",
"status": "processed",
"amount_minor": 10000,
"currency": "EUR"
}
}

Məcburi sahələr: 'event _ id', 'type', 'version', 'ts', 'attempt'.
Təkamül qaydaları: sahələr əlavə edin; Tiplərin silinməsi/dəyişdirilməsi - yalnız yeni 'version' ilə.


3) Təhlükəsizlik: imzalar və bağlama

3. 1 HMAC imzası (default tövsiyə olunur)

Başlıqlar:

X-Signature: v1=base64(hmac_sha256(<secret>, <canonical>))
X-Timestamp: 2025-11-03T12:34:56Z
X-Event-Id: 01HF7...
Kanonik sətir:

<timestamp>\n<method>\n<path>\n<sha256(body)>
Alıcıda yoxlama:
  • abs(now − `X-Timestamp`) ≤ 300s
  • 'X-Event-Id' əvvəllər işlənməyib (dedup)
  • 'X-Signature' üst-üstə düşür (time-təhlükəsiz müqayisə ilə)

3. 2 əlavə. tədbirlər

mTLS yüksək həssas webhook üçün.
IP/ASN allow-list.
DPoP (opsiyonel) üçün sender-constrained, əgər vebhuk geri zəngləri başlatır.


4) İdempotentlik və duplikasiya

4. 1 Hadisənin idempotantlığı

Eyni 'event _ id' hadisəsi vəziyyəti yenidən dəyişməməlidir. Alıcı:
  • 'event _ id' -ni TTL ≥ 24-72 saat ərzində idempotent keşdə (KV/Redis/DB) saxlayır;
  • təkrar geri qaytarılması üçün emal nəticəsini (uğur/səhv, artefaktlar) saxlayır.

4. 2 Komandaların idempotentliyi (əks çağırışlar)

Əgər vebhuk müştərini API-ni çəkməyə məcbur edirsə (məsələn, «payout təsdiq et»), həmin REST çağırışında 'Idempotency-Key' istifadə edin, nəticəni xidmət tərəfində saxlayın (exactly-once outcome).

KV modeli (minimum):

key: idempotency:event:01HF7...
val: { status: "ok", processed_at: "...", handler_version: "..." }
TTL: 3d

5) Retrai və backoff

Tövsiyə olunan qrafik (jitter ilə eksponensial):
  • '5s, 15s, 30s, 1m, 2m, 5m, 10m, 30m, 1h, 3h, 6h, 12h, 24h' (N günə qədər gündəlik)
Kodlar üzrə həllər:
  • 2xx - uğur, retrajları dayandırın.
4xx:
  • '400/ 401/403/404/422' - imza/formatı tamam olarsa (müştəri səhvi) geri qaytarılmır.
  • '429' - 'Retry-After' və ya backoff retraimi.
  • 5xx/şəbəkə - retraim.

Göndəricinin başlıqları: «User-Agent», «X-Webhook-Producer», «X-Attempt».


6) Alıcı tərəfində emal

Psevdopaypline:
pseudo verify_signature()
if abs(now - X-Timestamp) > 300s: return 401

if seen(event_id):
return 200 // идемпотентный ответ

begin transaction if seen(event_id): commit; return 200 handle(data)       // доменная логика mark_seen(event_id)    // запись в KV/DB commit return 200

Tranzaksiyalılıq: «seen» etiketi uğursuzluq zamanı ikiqat emal edilməməsi üçün əməliyyat effekti ilə (və ya nəticəni təyin etdikdən sonra) atomik olaraq qoyulmalıdır.


7) Sifariş və snapshot zəmanətləri

Sifariş təmin edilmir. 'ts' və domen 'seq '/' version' in 'data' istifadə edin.
Uzun lag/itkilər üçün - göndəricidən/replay və alıcıdan/resync əlavə edin (vaxt/ID pəncərəsindən snapshot və delta əldə edin).


8) Status, replay və DLQ

8. 1 Göndərən nöqtələri

'POST/webhooks/replay' - 'event _ id' və ya vaxt pəncərəsi ilə.
'GET/webhooks/events/: id' - ilkin paketi və cəhd tarixçəsini göstərmək.
DLQ: «ölü» hadisələr (retraj limiti tükənib) → ayrı saxlama, alertlər.

8. 2 Alıcının son nöqtələri

`GET /webhooks/status/:event_id` — `seen=true/false`, `processed_at`, `handler_version`.
'POST/webhooks/ack' - (isteğe bağlı) DLQ əl emalı təsdiq.


9) Səhv müqavilələri (alıcının cavabı)

http
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
Retry-After: 120
X-Trace-Id: 4e3f...

{
"error": "invalid_state",
"error_description": "payout not found",
"trace_id": "4e3f..."
}

Tövsiyələr: həmişə aydın kodu və mümkünsə, 'Retry-After'. Ətraflı təhlükəsizlik detallarını geri qaytarmayın.


10) Monitorinq və SLO

Metriklər (göndərici):
  • delivery p50/p95, success rate, retray/hadisə, drop-rate DLQ, share 2xx/4xx/5xx, 2xx qədər gecikmə pəncərəsi.
Metriklər (alıcı):
  • verify fail rate (imza/vaxt), dup-rate, latency handler p95, 5xx.
SLO göstərişlər:
  • Çatdırılma: ≥ 99. Hadisələrin 9% -i 2xx <3 c p95 alır (ilk uğurlu cəhddən sonra).
  • Kriptoproverləmə: imzanın təsdiqlənməsi ≤ 2-5 ms p95.
  • Dedup: 0 təkrarlanan effektlər (domen səviyyəsində exactly-once outcome).

11) Məlumatların təhlükəsizliyi və məxfiliyi

Vebhuk bədənində PAN/PII ötürməyin; səlahiyyətli API detalları üçün identifikatorları və sonrakı pull istifadə edin.
Yuvalarda həssas sahələri maskalayın; TTL ilə hadisələrin cəsədlərini yalnız minimum saxlayın.
DLQ və replay anbarlarını şifrələyin.


12) Version və uyğunluq

'version' (zərf) və yolda versiyası: '/webhooks/v1/payments '.
Yeni sahələr - isteğe bağlıdır; silinir - yalnız 'Sunset' dövründən sonra.
machine-readable changelog-da dəyişiklikləri sənədləşdirin (avtomatik yoxlama üçün).


13) Test-cases (UAT çek siyahısı)

  • Eyni 'event _ id' → bir effekt və '200' təkrarlanan çatdırılması.
  • İmza: düzgün açar, səhv açar, köhnə açar (rotasiya), pəncərə xaricində 'X-Timestamp'.
  • Backoff: Alıcı '429' s 'Retry-After' → düzgün fasilə verir.
  • Sifariş: hadisələr '... processed' əvvəl gəlir '... created' → düzgün emal/gözləmə.
  • və 'mark _ seen' → atom/təkrarlama effekti arasında alıcının DB uğursuzluğu.
  • DLQ və əl replay → uğurlu çatdırılma.
  • Kütləvi «fırtına» (provayder paket göndərir) → itkisiz, limitlər kritik boğmaq deyil.

14) Mini snippet

Göndərənin imzası (psevdo):
pseudo body = json(event)
canonical = ts + "\n" + "POST" + "\n" + path + "\n" + sha256(body)
sig = base64(hmac_sha256(secret, canonical))
headers = {"X-Timestamp": ts, "X-Event-Id": event.event_id, "X-Signature": "v1="+sig}
POST(url, body, headers)
Alıcının yoxlanılması və dedupu (psevdo):
pseudo assert abs(now - X-Timestamp) <= 300 assert timingSafeEqual(hmac(secret, canonical), sig)

if kv.exists("idemp:"+event_id): return 200

begin tx if kv.exists("idemp:"+event_id): commit; return 200 handle(event.data)        // доменная логика kv.set("idemp:"+event_id, "ok", ttl=259200)
commit return 200

15) Tez-tez səhvlər

No deadup → təkrar effektlər (ikiqat refands/payauts).
Vaxt tuşu/pəncərə olmadan imza → replay üçün zəiflik.
Bütün tərəfdaşlarda bir HMAC sirri saxlamaq.
Cavablar '200' nəticəni düzəltmədən əvvəl → crash zamanı hadisələrin itkisi.
Cavab/log təhlükəsizlik detallarının «yuyulması».
DLQ/replay olmaması - insidentlərin həlli mümkün deyil.


16) Tətbiq şparqalı

Təhlükəsizlik: HMAC v1 + 'X-Timestamp' + 'X-Event-Id', pəncərə ≤ 5 dəq; mTLS/IP allow-list lazım.
Конверт: `event_id`, `type`, `version`, `ts`, `attempt`, `data`.
Çatdırılma: at-least-once, jitter ilə backoff, 'Retry-After', DLQ + replay API.
İdempotentlik: KV-keş 24-72 saat, + 'mark _ seen' effektinin atomik fiksasiyası.
Müşahidə: çatdırılma metrləri, imzalar, dublikatlar; track 'trace _ id'.
Sənədləşmə: versiya, cavab kodları, nümunələr, UAT çek siyahısı.


Xülasə

Davamlı webhucks üç balina üzərində qurulur: imzalanmış zərf, at-least-once çatdırılması və idempotent emalı. Müqaviləni rəsmiləşdirin, HMAC/mTLS və vaxt pəncərəsini açın, retraları + DLQ və replikaları həyata keçirin, idempotent etiketlərini saxlayın və effektləri atomik olaraq düzəldin. Sonra hadisələr şəbəkə uğursuzluqları, yükün zirvələri və nadir «taleyin dublikatları» zamanı da etibarlı olaraq qalır.

Contact

Bizimlə əlaqə

Hər hansı sualınız və ya dəstək ehtiyacınız varsa — bizimlə əlaqə saxlayın.Həmişə köməyə hazırıq!

İnteqrasiyaya başla

Email — məcburidir. Telegram və ya WhatsApp — istəyə bağlıdır.

Adınız istəyə bağlı
Email istəyə bağlı
Mövzu istəyə bağlı
Mesaj istəyə bağlı
Telegram istəyə bağlı
@
Əgər Telegram daxil etsəniz — Email ilə yanaşı orada da cavab verəcəyik.
WhatsApp istəyə bağlı
Format: ölkə kodu + nömrə (məsələn, +994XXXXXXXXX).

Düyməyə basmaqla məlumatların işlənməsinə razılıq vermiş olursunuz.