CPaaS
Guide: verificér WeZend-webhook-signaturer i Express (med kode)
Et komplet, virkende Express-endpoint der modtager leveringswebhooks og afviser alt, der ikke reelt er fra WeZend.
WWeZend Team5. juli 2026 · 5 min. læsning
WeZends webhooks er pr. besked: I sender webhook_url med i selve send-requesten (se Webhooks), og dette er modtager-siden af det.
Endpointet
const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.raw({ type: "application/json" })); // vi skal bruge den rå body til verificering
app.post("/hooks/wezend", (req, res) => {
const signature = req.get("X-ZafeConnect-Signature");
const timestamp = req.get("X-ZafeConnect-Timestamp");
const rawBody = req.body.toString("utf8");
const expected = crypto
.createHmac("sha256", process.env.WEZEND_WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const isValid =
signature &&
expected.length === signature.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!isValid) return res.status(401).send("invalid signature");
res.sendStatus(200); // svar hurtigt — gør det rigtige arbejde bagefter
const payload = JSON.parse(rawBody);
processDeliveryEvent(payload).catch(console.error);
});
Tre ting, det er værd at få rigtige
- Brug den rå body til signatur-tjekket, ikke den parsede/genserialiserede JSON — genserialisering kan subtilt ændre whitespace eller nøgle-rækkefølge og ødelægge HMAC-sammenligningen.
- Svar
2xx, før I laver langsomt arbejde. Et fejlet eller langsomt svar udløser et genforsøg (30 sek, 5 minutter, 30 minutter) — fint ved et reelt nedbrud, spild af tid ved en handler, der blot er langsom. - Header-navnene siger stadig
X-ZafeConnect-*, ikkeX-WeZend-*— en rest fra platformens oprindelige navn, der endnu ikke er omdøbt i backend'en. Match header-navnet præcis som vist ovenfor; antag ikke, at det følger det nuværende brand.
Hvor signeringshemmeligheden kommer fra
Find (og rotér) den i Indstillinger → Webhook-hemmelighed, understøttet af GET /v1/webhook-secret og POST /v1/webhook-secret/rotate.