Skip to content
WeZend
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

  1. 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.
  2. 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.
  3. Header-navnene siger stadig X-ZafeConnect-*, ikke X-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.

Én platform. Hver eneste kundeinteraktion.

Erstat dit kludetæppe af messaging-API'er, CDP og automatiseringsværktøjer med én engagement-platform bygget til skala.

Intet kreditkort · EU-datalagring · 99,99 % oppetids-SLA