Verify Kibble webhook signatures with HMAC-SHA256. Node.js and Python examples using constant-time comparison and correct raw body access.
Every webhook POST that Kibble sends includes an X-Kibble-Signature header. The value is an HMAC-SHA256 digest of the raw request body, computed using the webhook_secret that was returned when you created the invoice. Verifying this signature ensures the request came from Kibble and that the payload was not tampered with in transit.
Always verify the signature before reading or acting on webhook data. Skipping verification makes your endpoint vulnerable to spoofed requests from any party that knows your URL.
Store the webhook_secret as an environment variable alongside your other credentials. Never hard-code it in source files or commit it to version control.
# .env (server-side only — never expose to the browser)KIBBLE_WEBHOOK_SECRET=Xk9mLqR3vN8pT2wY...
If you create multiple invoices with webhooks, each invoice has its own webhook_secret. Store them mapped to their invoice_id — for example, in your database next to the invoice record — so you can look up the correct secret when a webhook arrives.
Most web frameworks parse the request body automatically, which loses the original bytes needed for verification. You must access the raw, unparsed body to compute the correct digest.
Next.js (App Router)
Express
Fastify
// app/api/webhooks/kibble/route.tsexport async function POST(req: Request) { const rawBody = await req.text(); // raw string, not parsed JSON // pass rawBody to verifyKibbleSignature(...)}
// Register express.raw() before your routerapp.use("/webhooks/kibble", express.raw({ type: "application/json" }));
// Fastify exposes req.rawBody when addContentTypeParser is usedfastify.addContentTypeParser( "application/json", { parseAs: "buffer" }, (_req, body, done) => done(null, body));
If your signature comparison fails unexpectedly, confirm you are reading the raw body as a string (UTF-8). JSON re-serialization changes whitespace and key ordering, producing a different digest.