Veebihaagide vastuvõtmine
Veebihaak teavitab teie süsteemi Sursas toimunud muudatusest kohe, kui see juhtub: kaart avaldati, kontrolliti või
arhiveeriti, küsimus jäi vastuseta. Sursa saadab sündmusega HTTPS-päringu POST aadressile, mille registreerite. See
juhend loob vastuvõtja, mis töötab õigesti ka korduskatsete, muutunud järjekorra ja duplikaatide korral.
Mida iga sündmus tähendab ja sisaldab, vaadake juhendist Veebihaagide ülevaade ja API teatmiku sündmuste kataloogist.
1. Registreerige veebihaak
Administraator registreerib veebihaagid Sursas jaotises Administration → Integrations → Webhooks and API (haldus →
integratsioonid → veebihaagid ja API) või päringuga POST /v1/webhooks võtmega,
millel on roll admin ja ulatus webhooks:manage:
curl -X POST https://api.sursa.com/v1/webhooks \
-H "Authorization: Bearer $SURSA_ADMIN_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/sursa",
"description": "Sync verified cards to the help center",
"events": ["card.published", "card.updated", "card.verified", "card.archived"]
}'Vastus sisaldab väljal secret allkirjastamise saladust, mis algab eesliitega whsec_. Seda näidatakse üks kord.
Hoidke seda koos oma vastuvõtjaga, näiteks keskkonnamuutujas SURSA_WEBHOOK_SECRET.
Aadress peab kasutama protokolli https ja lahenduma avalikeks IP-aadressideks: privaat-, tagasisilmuse ja muude
reserveeritud võrkude aadressid lükatakse tagasi nii registreerimisel kui ka iga edastuse korral. Oma arvutis
arendamiseks tehke oma kohalik vastuvõtja kättesaadavaks tunneldusteenuse kaudu, mis annab sellele avaliku
HTTPS-aadressi.
Saatke testsündmus igal ajal päringuga POST /v1/webhooks/{webhook_id}/test.
Vastus näitab, mida teie vastuvõtja vastas.
2. Milline näeb välja edastus
POST /sursa HTTP/1.1
Host: hooks.example.com
Content-Type: application/json
webhook-id: evt_0123456789abcdef0123456789abcdef
webhook-timestamp: 1791194400
webhook-signature: v1,l1LLl/aEl4dQq7Geb383KbyNeZgs7VZpiw6iuoJgunI=
X-KB-Signature: t=1791194400,v1=82aa6b27378d89d7d880d17c3fe96268598443ae0e64d059c0c41e94e5d3ffbe
X-KB-Event-Id: evt_0123456789abcdef0123456789abcdef
X-KB-Event: card.verified
X-KB-Delivery: 99812
X-KB-Attempt: 1
X-KB-Sequence: 1042
{"id":"evt_0123456789abcdef0123456789abcdef","type":"card.verified","created_at":"2026-10-05T10:00:00Z","org_id":1,"api_version":"1.60.0","sequence":1042,"object":{"type":"card","id":"c1"},"payload":"full","data":{"card":{"id":"c1"}},"test":false}
| Päis | Tähendus |
|---|---|
webhook-id | Sündmuse ID. Iga korduskatse puhul sama. Kasutage seda duplikaatide kõrvaldamiseks. |
webhook-timestamp | Millal see katse allkirjastati, Unixi sekundites. |
webhook-signature | Allkiri vormingus Standard Webhooks. |
X-KB-Signature | Sama edastus, allkirjastatud Sursa varasemas vormingus. |
X-KB-Event | Sündmusetüüp. |
X-KB-Attempt | Katse number, alates 1-st. |
X-KB-Sequence | Selle edastuse koht veebihaagi edastuste järjekorras. |
Päiste nimed on tõstutundetud; teie raamistik võib näidata neid kujul X-Kb-Signature või x-kb-signature.
Keha on sündmus. Selle data sõltub tüübist. Veebihaak, mille sisu režiim on thin, saab sündmuse ilma väljata
data; lugege objekt selle asemel oma võtmega API kaudu.
3. Kontrollige allkirja
Kontrollige iga edastuse allkirja enne, kui edastust usaldate. Mõlemad vormingud allkirjastavad keha täpsed baidid, seega lugege toores keha enne mis tahes JSON-i parsimist: JSON-i uuesti serialiseerimine muudab baite ja rikub kontrolli.
| Vorming | Allkirjastatud string | Võti | Allkiri |
|---|---|---|---|
Standard Webhooks (webhook-signature) | <webhook-id>.<webhook-timestamp>.<body> | Saladuse osa pärast eesliidet whsec_, base64-dekodeeritud | v1, + HMAC-SHA256 base64-kujul |
Varasem vorming (X-KB-Signature) | <t>.<body> | Kogu saladuse string tekstina | v1= + HMAC-SHA256 kuueteistkümnendkujul |
Piisab neist ühe kontrollimisest. Eelistage päist Standard Webhooks: sama kontroll on saadaval paljudes valmisteekides.
Saladuse uuendamise ajal sisaldab iga päis iga kehtiva saladuse kohta ühte allkirja (päises webhook-signature
tühikutega eraldatud, päises X-KB-Signature korduvate osadena v1=). Edastus on kehtiv, kui mõni neist sobib.
Lükake tagasi ka ajatempel, mis erineb teie kellast rohkem kui 5 minutit. See ei lase kellelgi salvestatud edastust hiljem uuesti esitada.
# Check a saved delivery by hand: body.json holds the raw body, the values come from its headers.
SECRET="whsec_…"; WEBHOOK_ID="evt_…"; TIMESTAMP="1791194400"
# Standard Webhooks: compare with the value after "v1," in webhook-signature
KEY=$(printf '%s' "${SECRET#whsec_}" | tr '_-' '/+')
while [ $(( ${#KEY} % 4 )) -ne 0 ]; do KEY="$KEY="; done
KEY_HEX=$(printf '%s' "$KEY" | openssl base64 -d -A | xxd -p | tr -d '\n')
{ printf '%s.%s.' "$WEBHOOK_ID" "$TIMESTAMP"; cat body.json; } \
| openssl dgst -sha256 -mac HMAC -macopt "hexkey:$KEY_HEX" -binary | openssl base64 -A
# Earlier format: compare with the value after "v1=" in X-KB-Signature
{ printf '%s.' "$TIMESTAMP"; cat body.json; } | openssl dgst -sha256 -hmac "$SECRET" -r | cut -d' ' -f1Testige allkirja kontrollimise koodi
Käivitage oma kood nende väärtustega enne, kui ühendate selle päris edastustega. Kui kell on seatud ajatemplile, peavad mõlemad kontrollid õnnestuma ning peavad ebaõnnestuma, kui keha üks bait muutub.
| Sisend | Väärtus |
|---|---|
| Saladus | whsec_test_secret_0123456789abcdef |
webhook-id | evt_0123456789abcdef0123456789abcdef |
webhook-timestamp ja t | 1791194400 |
| Keha | {"id":"evt_0123456789abcdef0123456789abcdef","type":"card.verified","created_at":"2026-10-05T10:00:00Z","org_id":1,"data":{"card":{"id":"c1"}}} |
webhook-signature | v1,+xxWSXH6weQJ/MVg4+N78a1Dj4y/AQ4p94+PRNzpECg= |
X-KB-Signature | t=1791194400,v1=ce26a19cb63cd3ae620217bf7688e1df1044fa7d59d9ae148d215f0292b768dc |
4. Vastake kiiresti, tehke töö hiljem
Sursa ootab teie vastust kuni 10 sekundit. Iga olek 2xx tähendab, et edastus õnnestus; kõik muu, sealhulgas
ümbersuunamine, ajalõpp või suletud ühendus, tähendab, et edastus ebaõnnestus ja seda proovitakse uuesti.
Seega peaks vastuvõtja ainult kontrollima, sündmuse salvestama ja vastama. Tehke tegelik töö hiljem, oma järjekorrast.
// Node.js 20+, no framework. verifyStandard and verifyLegacy come from step 3.
import http from "node:http";
const SECRET = process.env.SURSA_WEBHOOK_SECRET;
http
.createServer(async (req, res) => {
const parts = [];
for await (const part of req) parts.push(part);
const body = Buffer.concat(parts); // the raw bytes, before any JSON parsing
const valid = req.headers["webhook-signature"]
? verifyStandard(SECRET, req.headers, body)
: verifyLegacy(SECRET, req.headers["x-kb-signature"], body);
if (!valid) {
res.writeHead(400).end();
return;
}
const event = JSON.parse(body);
await saveEventOnce(event); // insert into your table or queue, keyed by event.id; ignore a duplicate
res.writeHead(204).end();
})
.listen(3000);Vastake 2xx alles siis, kui sündmus on turvaliselt salvestatud. Kui vastate enne ja teie protsess jookseb seejärel
kokku, on sündmus teie jaoks kadunud, sest Sursa on selle juba edastatuks lugenud.
5. Korduskatsed
Ebaõnnestunud edastust proovitakse uuesti üha pikemate vahedega: umbes 1 minuti, 5 minuti, 30 minuti, 2 tunni, 5 tunni, 10 tunni, 24 tunni ja 24 tunni järel, kokku üheksa katset peaaegu kolme päeva jooksul. Iga paus varieerub kuni 20% võrra, et paljude veebihaakide korduskatsed ei saabuks samal hetkel.
- Vastus
429või503päisegaRetry-Afterlükkab järgmise katse vähemalt selle ajani, kuid mitte rohkem kui 24 tundi edasi. Kasutage seda, kui teie süsteem on üle koormatud või hoolduses. - Vastus
410 Gonekeelab veebihaagi: saatke see ainult siis, kui te ei soovi sellele aadressile enam edastusi. - Pärast 10 järjestikust ebaõnnestunud katset veebihaak peatatakse ja organisatsiooni administraatoreid
teavitatakse. Sündmused kogunevad edasi ja kui veebihaagi töö jätkatakse haldusliideses või päringuga
POST /v1/webhooks/{webhook_id}/resume, edastatakse need järjekorras. - Pärast viimast katset märgitakse edastus olekuga
exhausted. Saate selle käsitsi uuesti saata.
Veebihaagi edastused koos iga katse, teie vastuse koodi ja ajastusega loetleb päring
GET /v1/webhooks/{webhook_id}/deliveries, samuti näeb neid
haldusliideses. POST /v1/webhooks/{webhook_id}/deliveries/{delivery_id}/redeliver
saadab ühe edastuse uuesti. Uuesti edastamisel on sama webhook-id.
6. Järjekord ja duplikaadid
- Järjekord. Ühe veebihaagi edastused toimuvad rangelt üksteise järel väärtuse
sequencejärjekorras. Kuni ühte edastust proovitakse uuesti, ootavad hilisemad. Erinevad veebihaagid üksteist ei oota. - Duplikaadid. Sama sündmus võib saabuda rohkem kui üks kord, näiteks kui teie vastus läks tagasiteel kaotsi.
Salvestage iga töödeldud sündmuse
webhook-id(see on ka keha väliid) ja jätke vahele sündmus, mida olete juba näinud. - Mõelge olekutes. Sama objekti muudatuste puhul võrrelge väärtust
created_atvõisequencesellega, mille olete salvestanud, ja eirake sündmust, mis on vanem kui teie olemasolev olek. Kahtluse korral lugege praegune objekt API kaudu: sündmus ütleb teile, et midagi muutus, API ütleb, mis see praegu on.
7. Viige andmed vastavusse sündmuste lindiga
Iga sündmust säilitatakse 30 päeva ka sündmuste lindis, olenemata sellest, kas mõni veebihaak oli selle tellinud.
Kui teie vastuvõtja ei töötanud kauem, kui korduskatsed katavad, või soovite kontrollida, et midagi ei jäänud vahele,
lugege linti võtmega, millel on roll admin ja ulatus webhooks:manage:
curl -G https://api.sursa.com/v1/webhook-events \
-H "Authorization: Bearer $SURSA_API_KEY" \
--data-urlencode "type=card.*" \
--data-urlencode "created_since=2026-10-20T00:00:00Z" \
--data-urlencode "limit=200"Lindis oleval sündmusel on sama id ja kuju mis edastuses, ilma edastuse väljadeta sequence, payload ja test.
Kuna teie vastuvõtja jätab juba nähtud sündmused vahele, võite vastavusse viimist käivitada nii tihti, kui soovite,
näiteks kord tunnis.
GET /v1/webhook-events/{event_id} loeb ühe sündmuse selle ID järgi.
8. Uuendage saladust
POST /v1/webhooks/{webhook_id}/rotate-secret väljastab uue saladuse ja
jätab eelmise kattuvusajaks kehtima: vaikimisi 24 tundi, kuni 7 päeva. Kattuvusaja jooksul allkirjastatakse iga
edastus mõlema saladusega.
- Uuendage saladust ja salvestage uus saladus oma vastuvõtjas vana kõrvale.
- Aktsepteerige edastus, kui see läbib kontrolli kummagi saladusega.
- Pärast kattuvusaega eemaldage vana saladus.
Kui vana saladus on lekkinud, lõpetage kattuvusaeg kohe päringuga
POST /v1/webhooks/{webhook_id}/revoke-previous-secret või
uuendage saladust väärtusega "overlap_hours": 0.
Kontroll-loend
- Kontrollige toorest keha kasutades üht allkirjadest ja kontrollige ajatemplit.
- Salvestage sündmus võtmega
webhook-id, seejärel vastake 10 sekundi jooksul olekuga2xx. - Jätke vahele duplikaadid ja vananenud sündmused; kui see on oluline, lugege praegune objekt API kaudu.
- Vastake
429või503päisegaRetry-After, kui vajate, et Sursa saatmist aeglustaks; ärge kunagi vastake410kogemata. - Jätke vahele tundmatud sündmusetüübid ja väljad.
- Viige andmed regulaarselt vastavusse sündmuste lindiga.