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 webhook endpoints when payment status changes.Webhook endpoints can be managed from the Webhooks tab in the merchant dashboard (https://app.zafapay.com). Each endpoint has its own Webhook Secret for signature verification.
Webhook Endpoints
You can register multiple webhook endpoints to receive event notifications. Each endpoint has its own URL, secret, and optional event filter.
Webhook endpoints can be created and managed from the Webhooks tab in the merchant dashboard.
Event Types
Payload
string
Event type (e.g.,
payment.succeeded)string
Transaction ID
string
Merchant ID
string
Merchant name
string
Payment status (
succeeded, failed, canceled, refunded, chargeback)string
Payment amount (string format, e.g.,
"100.00")string
Currency code
string
Payment method (
card, depot, etc.)string
Saved card ID (
pmi_xxx format). Only included for recurring payments or when save_card was usedboolean
true for recurring (subscription) paymentsboolean
Only included as
true when the card was saved for future usestring
Merchant’s order ID (the value specified when creating the payment)
string
Product name (the value specified when creating the payment)
string
Customer ID (the value specified when creating the payment)
string
Customer’s email address (the value specified when creating the payment)
string
Customer’s phone number (the value specified when creating the payment)
string
Refunded amount (string format.
payment.refunded event only)object
Error details (
payment.failed event only)string
Card brand (
visa, mastercard, amex, jcb, etc.)string
Last 4 digits of the card number
string
Cardholder name
number
Card expiration month
number
Card expiration year
string
Card issuing country (ISO 3166-1 alpha-2 code, e.g.,
US, JP, SG). Only included when BIN lookup data is available.string
Card funding type (
credit, debit, prepaid). Only included when BIN lookup data is available.object
Metadata specified when creating the payment
string
Transaction creation timestamp (ISO 8601 format)
string
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 object is only included in payment.failed events. Use recommended_action to determine the appropriate response (retry, contact_customer, use_different_card, or none).payment.canceled (Payment Canceled)
payment.canceled fires in two cases:- Merchant void —
POST /v1/payments/{id}/voidwas called to void an authorized/captured payment before settlement. - Customer cancel during 3DS — the customer clicked “Cancel Payment” on the hosted 3DS challenge page. The checkout link becomes immediately reusable; the customer can retry with a different card using the same payment link.
GET /v1/payments/{id} and inspect the transaction’s prior state, or rely on your own state tracking.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 using the endpoint’s Webhook Secret to confirm the request was sent by ZAFA PAY.Signature Header
Verification Method
The signature is an HMAC-SHA256 hash of the request body (JSON string), using the endpoint’s Webhook Secret as the key.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
A total of 6 retries are executed over approximately 9 hours. If all retries fail, the event is moved to a Dead Letter Queue (DLQ) for manual intervention.
Best Practices
1
Always Verify Signature
Signature verification is essential to prevent unauthorized requests
2
Ensure Idempotency
The same event may be sent multiple times. Use
transaction_id as a key to prevent duplicate processing3
Return Response Quickly
Process webhooks asynchronously and return
200 immediately. Long processing times will cause timeout retries4
Log Errors
Log received payloads and processing results for debugging