Webhooks
Receive real-time notifications when payments complete or fail.
Verifying webhook signatures
Every request includes an X-Vexutopia-Signature header. Verify it using your signing secret to ensure the request is from Vexutopia.
const crypto = require('crypto');
// Header format: "t=<unix_timestamp>,v1=<hmac_hex>"
const header = req.headers['x-vexutopia-signature'];
const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
const { t, v1 } = parts;
// Signing string = timestamp + "." + raw body string (before JSON.parse)
const signingString = `${t}.${rawBody}`;
const expected = crypto
.createHmac('sha256', VEXUTOPIA_WEBHOOK_SECRET)
.update(signingString)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) {
return res.status(401).end(); // reject
}
// safe to process
return res.status(200).end();