Skip to content

Quickstart

In the dashboard, open a project → Notifications tab → enter a https:// callback URL → save. Copy the signing secret shown — it’s shown once.

Every request carries an X-Baiyar-Signature: t=<timestamp>,v1=<hex hmac> header. Recompute the HMAC over "<timestamp>.<raw body>" with your secret and compare:

import crypto from "node:crypto";
function verifyWebhook(rawBody, signatureHeader, secret) {
const [tPart, v1Part] = signatureHeader.split(",");
const timestamp = Number(tPart.split("=")[1]);
const signature = v1Part.split("=")[1];
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return (
expected.length === signature.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
);
}

See Verifying Webhook Signatures for the timestamp-tolerance check, a Python example, and the raw-body gotcha that breaks this if you skip it.

Use the sandbox payment simulator instead of waiting for a real payment — either the Sandbox simulation tools shown on any sandbox checkout page, or directly:

Terminal window
curl -X POST https://api.baiyar.id/sandbox/payments/{providerPaymentID}/simulate \
-H "Content-Type: application/json" \
-d '{"outcome": "paid"}'

If your webhook is configured, this delivers a real payment.paid request to your endpoint — the fastest way to confirm your handler responds 2xx and your signature check passes before a real customer depends on it.