Skip to content

Webhooks overview

How to register a webhook endpoint, choose its events and what a delivery from Baiyar looks like.


Baiyar can send signed events for payment, payment link, invoice, project, API key and webhook endpoint changes. Each event arrives as a POST request with a JSON body. The same event types are available in sandbox and live; livemode identifies the environment.

In the dashboard (Developer Tools → Webhooks → Add endpoint) or with the Merchant API (POST /v1/webhook-endpoints, scope webhooks:write).

  • The address must be public HTTPS. localhost, private addresses and plain http are refused, in the sandbox too. To test from your laptop use a tunnel.
  • An endpoint belongs to one project or to the whole merchant. A project endpoint hears that project’s events; a merchant endpoint hears every project’s and also the events of the account (webhook_endpoint.disabled).
  • You get a signing secret, whsec_…, once. Store it like a password. You can rotate it; the old secret keeps signing for 24 hours so you can change over without dropping events.
  • Up to 5 endpoints per project and 5 for the merchant, in each environment.

events is a list. Each entry is an event type (payment.succeeded), a family (payment.*, payment.attempt.*, payment_link.*) or * for everything. An empty list means everything. GET /v1/event-types lists every type with its description and scope.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
Baiyar-Signature: t=1760608800,v1=5b1f…
Baiyar-Event-Id: wev_01…
Baiyar-Event-Type: payment.succeeded
Baiyar-Delivery-Id: wdl_01…
{
"id": "wev_01k7…",
"type": "payment.succeeded",
"livemode": false,
"created": 1760608800,
"project_id": "prj_01k7…",
"data": {
"object": { "id": "pay_01k7…", "status": "paid", "amount": 10000000, "currency": "IDR" }
}
}

data.object is the same object the API returns for that resource (GET /v1/payments/{id}, GET /v1/payment-links/{id}), read when the event is built. Amounts are integers in the currency’s minor unit (10000000 is Rp100.000,00).

Answer with any 2xx within 10 seconds. Anything else, or no answer, is a failed attempt.