Webhooks
Configure a webhook endpoint from Settings → Developers
to receive real-time notifications instead of polling the API.
Event catalog
| Event | Fires when |
|---|---|
| payment.created | A new payment (or payment link) was created. |
| payment.completed | A payment was successfully captured. |
| payment.expired | A payment link expired before being paid. |
| payment.cancelled | A pending payment was cancelled. |
| refund.created | A refund request was submitted. |
| refund.completed | A refund finished processing and funds returned to the customer. |
| payout.requested | A payout was requested and is awaiting approval. |
| payout.approved | A payout was approved and queued for dispatch. |
| payout.completed | A payout settled to your bank account. |
| payout.failed | A payout attempt failed. |
| payout.rejected | A payout request was rejected. |
| kyb.status_changed | Your business verification status changed. |
| apikey.revoked | An API key was revoked (rotation or manual action). |
Payload shape
{
"type": "payment.completed",
"data": {
"id": "pay_8f2a1c",
"reference": "BINK-8F2A1C",
"status": "PAID",
"amountMinor": "5000",
"currency": "EGP"
}
}Verifying the signature
Every delivery is signed with HMAC-SHA256 and sent as the X-Binkpay-Signature header, in the form t=<timestamp>,v1=<hmac-hex>. The event type is also sent as X-Binkpay-Event. Compute the HMAC over {timestamp}.{raw body} using your webhook secret and compare it to v1.
import crypto from 'crypto';
function verifySignature(rawBody, header, secret) { const [tPart, v1Part] = header.split( ',');
const timestamp = tPart.split( '=')[ 1];
const signature = v1Part.split( '=')[ 1];
const expected = crypto
.createHmac( 'sha256', secret)
.update( `${timestamp}.${rawBody}`)
.digest( 'hex');
return crypto.timingSafeEqual(Buffer. from(expected), Buffer. from(signature));
}Retry policy
Failed deliveries (non-2xx response, timeout, or connection error) are retried with exponential backoff. After the retry budget is exhausted, the delivery is marked DEAD and visible in your webhook delivery log for manual retry.
If every retry fails, the delivery is marked DEAD and stays visible in your webhook delivery log for manual redelivery.
| Parameter | Type | Required | Description |
|---|---|---|---|
| X-Binkpay-Signature | header | Required | t=<unix ts>,v1=<hmac-sha256 hex> |
| X-Binkpay-Event | header | Required | The event type, e.g. payment.completed. |
Always respond fast
Acknowledge the delivery with a 2xx status within a few seconds, then process the event asynchronously — slow handlers are indistinguishable from failures and will be retried.
Was this page helpful?
