GH GambleHub

Webhooks和事件的平均水平

TL;DR

良好的webhook是簽名(HMAC/mTLS),總結和偶發事件,是通過指數回程和收件人重復數據消除的at-least-once模型提供的。商定信封(「event_id」,「type」,「ts」,「version」,「attempt」,「signature」),時間窗口(≤5分鐘),響應代碼,撤回,DLQ和狀態終止。


1)角色和交付模式

發件人(您是/提供商):形成事件、簽名、嘗試傳送至2xxx、在3xx/4xx/5xx時轉發(顯式的「不接受」除外)、運行DLQ,並給出replay API。
收件人(合作夥伴/您的服務):檢查簽名/臨時窗口,進行去勢和偶數處理,以正確的代碼響應,提供/status 和/ack replay到「event_id」。

保修:at-least-once.收件人必須能夠處理重復和順序更改。


2)事件信封(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"
}
}

必填字段:「event_id」,「type」,「version」,「ts」,「attempt」。
進化規則:添加字段;刪除/更改類型-僅使用新的「版本」。


3)安全: 簽名和綁定

3.1個HMAC簽名(默認推薦)

標題:

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

<timestamp>\n<method>\n<path>\n<sha256(body)>
與收件人核對:
  • abs(now − `X-Timestamp`) ≤ 300s
  • 「X-Ivent-Id」以前未處理(dedup)
  • 「X-Signature」匹配(與超時安全比較)

3.2 Dop。措施

IP/ASN allow-list.

mTLS用於高度敏感的webhook。
如果webhook觸發回調,則用於sender-constrained的DPoP(可選)。


4)相似性和重復數據消除

4.1事件的冪等性

具有相同「event_id」的事件不應再次更改狀態。收件人:
  • 將「event_id」存儲在TTL ≥ 24-72小時的等效腰包(KV/Redis/DB)中;
  • 保留處理結果(成功/錯誤,工件)以重新返回。

4.2指令的冪等(回調)

如果webhook導致客戶端使用API(例如「確認付款」),請在REST調用卷上使用「Idempotency-Key」,將結果存儲在服務端(exactly-once outcome)。

KV模型(最低):

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

5)Retrai和backoff

推薦的圖形(帶有抖動的指數圖):
  • 5 s、15 s、30 s、1 m、2 m、5 m、10 m、30 m、1 h、3 h、6 h、12 h、24 h"(更遠的是每日到N天)
代碼解決方案:
  • 2 xx是成功的,停止回程。
  • 4xx:

「400/ 401/403/404/422」-如果簽名/格式為ok(客戶端錯誤),則不重復。
「429」是「Retry-After」或backoff的復制品。
5 x/network-retraim。

發件人標題:「User-Agent」,「X-Webhook-Producer」,「X-Attempt」。


6)收件人一方的處理

偽工作表:
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

事務性:「seen」標簽必須原子化,並具有操作效果(或在提交結果後),以避免在發生故障時進行雙重處理。


7)秩序保證和狙擊

該命令沒有得到保證。使用「ts」和「seq」/「version」域中的「data」進行相關性對賬。
對於長滯後/損失-從發件人添加/replay 和/resync到收件人(通過時間/ID窗口獲取快照和三角洲)。


8)狀態、replay和DLQ

8.1發件人的Endpoint

「POST/webhooks/replay」-通過「event_id」列表或時間窗口。
「GET/webhooks/events/:id」-顯示源軟件包和嘗試歷史記錄。
DLQ:「死」事件(retrais限制用盡)→單獨的存儲,alerta。

8.2收件人的終結

`GET /webhooks/status/:event_id` — `seen=true/false`, `processed_at`, `handler_version`.

「POST/webhooks/ack」-(可選)從DLQ確認手動處理。


9)錯誤合同(收件人的回應)

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..."
}

建議:始終返回清晰的代碼,如果可以,「Retry-After」。請勿返回詳細的安全細節。


10)監控和SLO

度量(發送者):
  • delivery p50/p95, success rate, retrai/事件, drop-rate DLQ, share 2xx/4xx/5xx,延遲窗口高達2xx。
度量(收件人):
  • verify fail rate(簽名/時間),dup-rate, latency handler p95, 5xx。
SLO地標:
  • 交付:≥ 99。9%的事件獲得2xx <3 c p95(在首次成功嘗試之後)。
  • 加密反駁:簽名驗證≤ 2-5 ms p95。
  • Dedoop: 0重復效果(在域級別上只出現一個結果)。

11)數據安全和隱私

不要在webhook體內傳播PAN/PII;通過授權的API在部件後面使用ID和後續拉動。
在日誌中掩蓋敏感字段;使用TTL將事件主體保持在最低限度。
加密DLQ存儲和繼電器。


12)轉化與兼容性

「版本」(信封)和路徑中的版本:「/webhooks/v1/payments」。
新字段-可選;刪除-僅在「日落」期之後。
記錄對machine-readable changelog(用於自動反駁)的更改。


13)測試案例(UAT支票單)

  • 重新交付相同的'event_id' →一個效果和'200'復制。
  • 標題:正確的鑰匙,不正確的鑰匙,舊鑰匙(輪換),「X-Timestamp」窗外。
  • Backoff:收件人給出'429'的'Retry-After' →正確的暫停。
  • 順序:「……處理」事件早於「……created」 →正確處理/等待。
  • 收件人的DB在效果和「mark_seen」之間發生故障→原子/重復。
  • DLQ和手動復制→成功交付。
  • 大規模的「風暴」(包裹縫合提供者)→沒有損失,限制不會扼殺關鍵。

14)迷你嗅探

發送者簽名(偽簽名):
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)
收件人的檢查和遺忘(偽的):
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)經常出錯

沒有重復數據消除→重復效果(雙重重復/重復)。
沒有時間軸/窗口的簽名→了replay漏洞。
為所有合作夥伴存儲一個HMAC密碼。
在確定結果之前的「200」答案→崩潰事件丟失。
將安全細節「沖洗」到響應/logi中。
缺少DLQ/反射-事件無法解決。


16)施帕加爾卡實施

Конверт: `event_id`, `type`, `version`, `ts`, `attempt`, `data`.

安全:HMAC v1+「X-Timestamp」+「X-Ivent-Id」,窗口≤ 5分鐘;根據需要,mTLS/IP allow-list。
交付:上空,背靠背,「Retry-After」、DLQ+replay API。
相似性:KV-kesh 24-72小時,效應原子固定+'mark_seen'。
可觀察性:交付,簽名,重復指標;「trace_id」跟蹤。
文件:版本,響應代碼,示例,UAT支票清單。


二.總結

持久的Webhooks建在三條鯨魚上:簽名信封,近距離交付和偶數處理。正式化合同,啟用HMAC/mTLS和時間窗口,實現retrais+DLQ和恢復,存儲等效標簽,並捕獲原子效應。然後,即使網絡故障,負載峰值和罕見的「命運重復」,事件仍保持可靠。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。