Overview
Webhooks allow you to receive real-time notifications for payment events such as completion, failure, and refunds. ZAFA PAY sends HTTP POST requests to your registered URL when payment status changes.The Webhook Secret can be found in the “Merchant Settings” section of the merchant dashboard (https://app.zafapay.com).
Event Types
| Event | Description |
|---|---|
payment.succeeded | Payment completed successfully |
payment.failed | Payment failed |
payment.canceled | Payment canceled |
payment.refunded | Refund completed |
payment.chargeback | Chargeback occurred |
Payload
Event type (e.g.,
payment.succeeded)Transaction ID
Merchant ID
Merchant name
Payment status (
succeeded, failed, canceled, refunded, chargeback)Payment amount (string format, e.g.,
"100.00")Currency code
Payment method (
card, depot, etc.)Saved card ID (
pmi_xxx format). Only included for recurring payments or when save_card was usedtrue for recurring (subscription) paymentsOnly included as
true when the card was saved for future useMerchant’s order ID (the value specified when creating the payment)
Product name (the value specified when creating the payment)
Customer ID (the value specified when creating the payment)
Customer’s email address (the value specified when creating the payment)
Customer’s phone number (the value specified when creating the payment)
Refunded amount (string format.
payment.refunded event only)Error message (
payment.failed event only)Card brand (
visa, mastercard, amex, jcb, etc.)Last 4 digits of the card number
Cardholder name
Card expiration month
Card expiration year
Metadata specified when creating the payment
Transaction creation timestamp (ISO 8601 format)
Webhook sent timestamp (ISO 8601 format)
Payload Examples
payment.succeeded (Payment Successful)
payment_method_idis only included whensave_cardwas used or for recurring paymentssave_cardis only included astruewhen the card was saved in the initial paymentis_recurringistruefor recurring payments
payment.failed (Payment Failed)
The
error field is only included in payment.failed events.payment.refunded (Refund Completed)
The
amount_refunded field is only included in payment.refunded events. For partial refunds, it shows the refunded amount.payment.chargeback (Chargeback Occurred)
Signature Verification
Webhook requests include a signature header. Verify this signature to confirm the request was sent by ZAFA PAY.Signature Header
| Environment | Header Name |
|---|---|
| Sandbox | X-Zafapay-Signature-Sandbox |
| Production | X-Zafapay-Signature |
Verification Method
The signature is an HMAC-SHA256 hash of the request body (JSON string).Node.js
Response
Return HTTP status code2xx when the webhook is successfully received.
Retry
ZAFA PAY automatically retries webhooks in the following cases:- HTTP status code other than
2xxis returned - Connection timeout occurs (10 seconds)
Retry Schedule
| Attempt | Delay After Failure |
|---|---|
| 1st | Immediate |
| 2nd | 1 minute later |
| 3rd | 5 minutes later |
| 4th | 30 minutes later |
| 5th | 2 hours later |
| 6th | 6 hours later |
Best Practices
Ensure Idempotency
The same event may be sent multiple times. Use
transaction_id as a key to prevent duplicate processingReturn Response Quickly
Process webhooks asynchronously and return
200 immediately. Long processing times will cause timeout retries