Webhooks
Webhooks push event notifications to your server as payments move through their lifecycle. ZendFi signs every webhook delivery with HMAC-SHA256 so you can verify authenticity, and retries failed deliveries with exponential backoff.How It Works
Webhook Configuration
Set your webhook URL in the ZendFi Dashboard or duringzendfi init with the CLI. Every webhook registered under your merchant account receives all event types.
Event Types
All events your webhook endpoint can receive:Payment Events
Refund Events
Dispute Events
Payment Intent Events
Settlement Events
Withdrawal Events
Sub-Account Lifecycle Events
Subscription Events
Installment Events
Payment Link Events
Invoice Events
Webhook Payload Structure
Every webhook delivery is an HTTP POST with a JSON body:Payload Fields
The event type (see table above).
Payment data. Present for payment, payment link, installment, and subscription events.Key fields:
id, merchant_id, amount_usd, status, transaction_signature, customer_wallet, payment_token, mode, description, metadata, splits, created_at, expires_at.Settlement data. Present for
SettlementCompleted and SettlementFailed.Key fields: id, payment_id, merchant_id, amount_usd, settlement_token, settlement_amount, transaction_signature, merchant_wallet, status.Withdrawal data. Present for withdrawal events.Key fields:
id, merchant_id, sub_account_id, delegation_token_id, automation_token_id, signing_grant_id, auth_mode, to_address, from_address, amount, token, transaction_signature, status, is_bank_withdrawal, offramp_order_id, paj_order_id, bank_account_number, bank_name.Sub-account lifecycle payload. Present for
SubAccountCreated, SubAccountDelegationTokenMinted, SubAccountFrozen, and SubAccountClosed.Key fields: id, external_id, merchant_id, label, wallet_address, created_at, reference_id, metadata.Refund data. Present for
RefundInitiated, RefundCompleted, RefundFailed.Key fields: id, payment_id, merchant_id, amount_usd, status, reason, initiated_by, transaction_signature, customer_wallet, customer_email, created_at, completed_at.Dispute data. Present for
DisputeOpened, DisputeResponded, DisputeResolved.Key fields: id, payment_id, refund_id, merchant_id, customer_email, customer_wallet, dispute_type, status, description, opened_at, resolved_at.Fraud data. Present for fraud events.Key fields:
payment_id, merchant_id, fraud_score, blocked, flags.ISO 8601 timestamp of when the event was generated.
Signature Verification
Every webhook includes ax-zendfi-signature header with the format:
- Create the signed payload:
{timestamp}.{json_body} - Compute HMAC-SHA256 using your webhook secret
- Compare the hex-encoded result to the
v1=value
Verification Examples
Using the SDK
The SDK provides built-in verification:- Express
- Next.js
Delivery and Retries
ZendFi uses exponential backoff for failed webhook deliveries:
After all retry attempts are exhausted, the webhook is marked as
exhausted and moved to the dead letter queue. You will receive an email alert if you have notifications enabled.
Webhook Statuses
List Webhook Events
Retry a Webhook
Webhook event ID.
Verify Webhook Configuration
The raw webhook payload body.
The signature string to verify (
t=...,v1=...).Response
Best Practices
Always verify signatures
Always verify signatures
Never trust webhook payloads without verifying the HMAC signature. This prevents spoofed events from triggering actions in your system.
Return 200 quickly
Return 200 quickly
Process webhook data asynchronously. Return a 200 response immediately and handle the business logic in a background job. ZendFi interprets slow responses as failures.
Handle duplicate deliveries
Handle duplicate deliveries
Webhooks may be delivered more than once. Use the
payment.id or event ID for idempotency checks before processing.Use raw body for verification
Use raw body for verification
Parse the JSON body only after verifying the signature against the raw string. Parsing and re-serializing can change whitespace and break the signature check.