Webhooks & Redirects
Webhooks & Redirects
Real-time notifications, signature verification, IP whitelisting, retries, and timeouts for both APIs
Both the Payments API and the Disbursement API support asynchronous, real-time notification via a callback_webhook_url, in addition to (or instead of) polling Get Transactions.
Webhook notifications — also known as real-time payment notifications or callbacks — are automated messages sent to your server when a payment or disbursement event occurs. They let you instantly update your system (e.g., credit a user’s account) without polling or manual intervention.
When an event is processed, a POST request with a JSON payload is sent to your specified callback_webhook_url, so your backend can handle the result immediately and reliably.
The mechanics below (signature algorithm, data format, IP addresses, payload shape, and status values) differ between the two APIs. Don’t reuse Payments API webhook-verification code for Disbursement API webhooks, or vice versa.
Redirects (Payments API only)
Generate Transaction additionally accepts two optional browser-redirect fields, which have no Disbursement API equivalent since a disbursement has no customer browser involved:
The redirect URLs are a browser-side experience — they only fire if the customer’s browser is still open on the payment page. The webhook is a server-side notification that fires regardless of what the customer’s browser is doing, which makes it the more reliable mechanism for updating your system’s records.
Example Webhook Payloads
Payments API
Disbursement API
Note the payload is flatter at the top level (data.amount, data.reference_no, data.status, data.signature) with a nested data.transaction object carrying the full transaction detail.
Possible Status Values
Both APIs use the same three status values: pending, cancelled, and completed.
Payments API
Disbursement API
Always use these values to determine how your system should respond to an update — don’t infer status from HTTP response codes alone.
Webhook Signature Verification
To ensure that incoming webhook notifications are truly from your payment provider and not a malicious third party, both APIs sign the payload with a signature — a cryptographic hash that acts as a tamper-proof seal. Even if someone intercepts the webhook, they cannot fake a valid signature without access to the secret key.
The two APIs use different HMAC algorithms and different data formats to compute the signature. Verify against the correct one for the webhook you received.
Payments API
Disbursement API
Uses HMAC-SHA256.
- Data format:
amount + "@" + reference_noExample:100@EPLKZT2OH319WBEF - Signature key: provided by your payment facilitator. For sandbox/staging (
test-merchantcredentials), use the Signature Key from the Create Token section:9XAgVZzU4WhqrXA6jEvMtkF85j8wKZZhQ5RE2hsDPwa5rjPT7RpCmJceu8jNt4Wy - HMAC output: hexadecimal string
JavaScript
PHP
Python
Java
IP Whitelisting
IP whitelisting limits incoming requests to only those from approved, trusted sources, reducing the risk of spoofed webhooks or unauthorized actions. This works in tandem with HMAC signature verification — together, they ensure the webhook is both authentic and coming from the correct origin.
Do not process any webhook request unless the HMAC signature is verified and the request originates from one of the whitelisted IP addresses below. Checking only one of the two can lead to spoofed or fraudulent transactions being processed.
Payments API
Disbursement API
Sandbox/Staging: 43.198.4.7
Production:
18.166.179.10918.166.252.124
Both APIs share the same sandbox/staging IP (43.198.4.7), but each has its own, distinct pair of production IPs. Whitelist the correct set for the API you’re integrating.
Webhook Retry Mechanism
If your server responds with a 4xx or 5xx status code (or doesn’t respond in time), the system automatically retries delivery using a backoff schedule. This behavior is identical for both APIs.
- Webhook delivery is retried up to 17 times over a span of roughly 7 days.
- Retries follow this interval schedule (in minutes):
- Retry #1 — after 2 minutes
- Retry #2 — after 10 minutes
- Retry #3 — after another 10 minutes
- Retry #4 — after 60 minutes
- Retry #5 — after 120 minutes
- Retry #6 — after 360 minutes (6 hours)
- Retry #7 — after 900 minutes (15 hours)
- Retry #8 to #17 — every 900 minutes (15 hours)
The retry count resets only when a 2xx response is received from your callback_webhook_url.
Webhook Timeout & Latency Guidelines
These are also identical for both APIs:
- Up to 3000ms (3 seconds) is allowed for your server to respond.
- If your server doesn’t respond within this window, the attempt is considered failed and will be retried.
- Keep your webhook processing latency below 300ms to account for network overhead, JSON parsing, and response handling.
Best practice: acknowledge the webhook immediately (return a 200 OK), then process the payload asynchronously in the background — don’t do slow work before responding.
Testing Webhook Notifications
For testing and debugging, you can temporarily use webhook.site as your callback_webhook_url for either API. This lets you:
- Instantly see the actual JSON payload sent by the system.
- Inspect and verify the HMAC signature.
- Debug your integration before going live.
This is the same approach shown in the collection’s own example requests, and works for both payment and disbursement flows without needing to stand up your own server endpoint first.