Webhooks
Breeze uses webhooks to notify your server about important payment events โ such as when a payment succeeds, fails, or expires. Webhooks allow your backend to update order statuses and trigger post-payment logic automatically.
๐ Event Format
Each webhook is sent as a POST request to your configured webhook URL, with a JSON payload in the following format:
{
"type": "PAYMENT_SUCCEEDED",
"data": {
"pageId": "pay_abc123xyz",
"status": "PAID",
"clientReferenceId": "order-<your-unique-id>",
"customer": {
"id": "cus_abc123xyz",
"referenceId": "<your-customer-id>",
"email": "[email protected]"
},
"currency": "USD",
"amount": 100,
"payinDetails": {
"amount": 100,
"currency": "USD",
"type": "CARD",
"scheme": "AMEX",
"last4": "0602",
"cardType": "CREDIT",
"bin": "377910",
"issuer": "DBS BANK LTD"
},
// ...
},
"signature": "afZiTJ..."
}
{
"type": "PAYMENT_EXPIRED",
"data": {
"pageId": "pay_abc123xyz",
"status": "EXPIRED",
"clientReferenceId": "order-<your-unique-id>",
"customer": {
"id": "cus_abc123xyz",
"referenceId": "<your-customer-id>",
"email": "[email protected]"
},
"currency": "USD",
"amount": 100,
// ...
},
"signature": "afZiTJ..."
}
{
"type": "PAYMENT_CREATED",
"data": {
"pageId": "pay_abc123xyz",
"status": "UNPAID",
"clientReferenceId": "order-<your-unique-id>",
"customer": {
"id": "cus_abc123xyz",
"referenceId": "<your-customer-id>",
"email": "[email protected]"
},
"currency": "USD",
"amount": 100,
// ...
},
"signature": "afZiTJ..."
}
{
"type": "KYC_DATA_REQUIRED",
"data": {
"email": "[email protected]"
},
"signature": "afZiTJ..."
}
- type: The type of event (PAYMENT_SUCCEEDED, PAYMENT_EXPIRED, etc.)
- data: The full payload with transaction details
- signature: A hash used for validating the webhook authenticity
โ
Supported Events
Event Type | Description |
---|---|
PAYMENT_CREATED* | Payment was created, but not yet completed |
PAYMENT_SUCCEEDED | Payment was successfully completed |
PAYMENT_EXPIRED | Payment was not completed in time |
KYC_DATA_REQUIRED | KYC data required from merchant |
OFFRAMP_STATUS_UPDATE | Customer offramp status was updated |
PAYMENT_CREATED event is only enabled by default for merchants onboarded after 25 Aug 2025.
๐ Webhook Security
1. Signature Validation (Recommended)
To verify the webhook is sent by Breeze and not a third party:
- Compute the HMAC-SHA256 of the raw request body using your Webhook Secret.
- Compare it with the signature field in the payload.
Weโll provide a code snippet in the language of your choice in the Webhook Reference section.
2. Static IP Whitelist (Optional)
For additional security, you can restrict webhook requests to only come from Breezeโs static IPs. Contact us at [email protected] to get the current list.
๐ Retry Policy
- If your server returns a non-2xx status, Breeze will retry the webhook up to 10 times over a 60-minute window.
- Delays between retries increase exponentially (e.g., 2s, 5s, 10sโฆ).
- Once a 2xx response is received, we stop retrying.
๐ Idempotency
Webhook handlers should always be idempotent, meaning:
- If you receive the same event multiple times (due to retries), your system should handle it gracefully.
- Use pageId or clientReferenceId to check if youโve already processed the event.
๐ Best Practices
- Log all incoming webhooks for debugging and audit trails.
- Always return 200 OK after successful processing.
- Do not rely solely on client-side redirects to determine payment success.
- Make your webhook handler robust against duplicate events and transient failures.
Updated 12 days ago