CPaaS
Guide: verifiera WeZend-webhook-signaturer i Express (med kod)
En komplett, fungerande Express-endpoint som tar emot leveranswebhooks och avvisar allt som inte verkligen kommer från WeZend.
WWeZend Team5 juli 2026 · 5 min läsning
WeZends webhooks är per meddelande: ni skickar med webhook_url i själva send-requesten (se Webhooks), och det här är mottagarsidan av det.
Endpointen
const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.raw({ type: "application/json" })); // vi behöver den råa bodyn för verifiering
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); // svara snabbt — gör det riktiga arbetet efteråt
const payload = JSON.parse(rawBody);
processDeliveryEvent(payload).catch(console.error);
});
Tre saker värda att få rätt
- Använd den råa bodyn för signaturkontrollen, inte den parsade/omserialiserade JSON:en — omserialisering kan subtilt ändra whitespace eller nyckelordning och förstöra HMAC-jämförelsen.
- Svara
2xxinnan ni gör långsamt arbete. Ett misslyckat eller långsamt svar utlöser ett omförsök (30 sek, 5 minuter, 30 minuter) — bra vid ett verkligt avbrott, slöseri vid en handler som bara är långsam. - Header-namnen säger fortfarande
X-ZafeConnect-*, inteX-WeZend-*— en rest från plattformens ursprungliga namn som ännu inte döpts om i backend. Matcha header-namnet exakt som visas ovan; anta inte att det följer nuvarande varumärke.
Var signeringshemligheten kommer från
Hitta (och rotera) den under Inställningar → Webhook-hemlighet, backad av GET /v1/webhook-secret och POST /v1/webhook-secret/rotate.