Skip to content
WeZend
CPaaS

Guide: verifiser WeZend-webhook-signaturer i Express (med kode)

Et komplett, fungerende Express-endepunkt som mottar leveringswebhooks og avviser alt som ikke faktisk er fra WeZend.

WWeZend Team5. juli 2026 · 5 min lesing

WeZends webhooks er per melding: dere sender med webhook_url i selve send-requesten (se Webhooks), og dette er mottakersiden av det.

Endepunktet

const express = require("express");
const crypto = require("crypto");

const app = express();
app.use(express.raw({ type: "application/json" })); // vi trenger den rå bodyen for verifisering

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 raskt — gjør det virkelige arbeidet etterpå

  const payload = JSON.parse(rawBody);
  processDeliveryEvent(payload).catch(console.error);
});

Tre ting det er verdt å få riktig

  1. Bruk den rå bodyen til signatursjekken, ikke den parsede/reserialiserte JSON-en — reserialisering kan subtilt endre whitespace eller nøkkelrekkefølge og ødelegge HMAC-sammenligningen.
  2. Svar 2xx før dere gjør tregt arbeid. Et mislykket eller tregt svar utløser et nytt forsøk (30 sek, 5 minutter, 30 minutter) — greit ved et reelt avbrudd, sløsing ved en handler som bare er treg.
  3. Header-navnene sier fortsatt X-ZafeConnect-*, ikke X-WeZend-* — en rest fra plattformens opprinnelige navn som ennå ikke er omdøpt i backend. Match header-navnet nøyaktig som vist over; anta ikke at det følger dagens merkevare.

Hvor signeringshemmeligheten kommer fra

Finn (og roter) den under Innstillinger → Webhook-hemmelighet, støttet av GET /v1/webhook-secret og POST /v1/webhook-secret/rotate.

Én plattform. Hver kundeinteraksjon.

Erstatt lappeteppet av meldings-API-er, CDP og automatiseringsverktøy med én engasjementsplattform bygget for skala.

Ingen kredittkort · EU-datalagring · 99,99 % oppetids-SLA