Skip to main content

Header format

Every webhook delivery includes a signature header:
X-Ledger-Signature: t=<unix_seconds>,v1=<hex_hmac_sha256>

Verification steps

1

Extract the timestamp and signature

Parse the t (timestamp) and v1 (signature) values from the header.
2

Compute the expected signature

const crypto = require('crypto');

const payload = `${timestamp}.${rawBody}`;
const expected = crypto
  .createHmac('sha256', signingSecret)
  .update(payload)
  .digest('hex');
3

Compare signatures

Use a constant-time comparison to check that your computed signature matches v1.
const isValid = crypto.timingSafeEqual(
  Buffer.from(expected, 'hex'),
  Buffer.from(v1, 'hex')
);

Replay protection

Optionally check that t is within an acceptable window (e.g. 5 minutes) to prevent replay attacks.