What are Webhooks?
Imagine you ordered a package and you want to know when it arrives. You have two options:- Polling: Call the courier every 5 minutes to ask “is my package here yet?” — exhausting, slow, and wasteful.
- Push notification: The courier texts you the moment the package lands at your door.
Events You Can Subscribe To
| Event | When it fires |
|---|---|
collection.credit | Money arrived in one of your collection accounts |
collection.reversal | A credit that arrived earlier was reversed (sent back to the sender) |
collection.dispute | A dispute was raised against a transaction in one of your accounts |
Additional event types may be added over time. Your webhook endpoint should handle unknown event types gracefully — log them and return
200 OK without taking action. This way, new events we add will never cause your endpoint to error.Setting Up a Webhook
Build an HTTPS endpoint on your server
Create a route in your web application that accepts
POST requests. This is where we will send notifications.Requirements for the endpoint:- Must use HTTPS (not plain HTTP) — we reject HTTP endpoints for security
- Must respond within 30 seconds — requests that take longer are treated as failures
- Must return HTTP 200 to acknowledge receipt — any other status code (including redirects) is treated as a failure
- Must be idempotent — we may deliver the same event more than once in rare circumstances (see Retry Behaviour below)
We test-ping your endpoint
During registration, we send a test Make sure your endpoint handles the
POST request to your URL with a ping event. If your endpoint does not respond with 200 OK within 30 seconds, registration fails and you receive an error.Example ping payload:ping event and returns 200. You do not need to do anything with it other than respond.Verifying Webhook Authenticity
This is the most important part of your webhook integration. Without signature verification, your endpoint is open to fake notifications — an attacker could send a forgedcollection.credit event and trick your system into crediting a customer without real money arriving.
We compute the X-Signature header by running an HMAC-SHA256 hash over the raw request body, using your webhook secret as the key.
- JavaScript (Node.js)
- Python (Flask)
Handling Duplicate Deliveries
In rare cases — such as a network timeout between our servers and yours — we may deliver the same event more than once. Your handler must be idempotent: processing the same event twice should produce the same result as processing it once. The simplest way to achieve this: before processing a webhook, check whether you have already seen thistransactionRef. If yes, return 200 OK immediately without re-processing.
Retry Behaviour
If your endpoint returns anything other than200 OK, or does not respond within 30 seconds, we retry delivery on this schedule:
| Attempt | Delay after previous failure |
|---|---|
| 1st retry | 5 seconds |
| 2nd retry | 30 seconds |
| 3rd retry | 5 minutes |
| 4th retry | 30 minutes |
| 5th retry | 2 hours |
| 6th retry | 6 hours |
| 7th retry | 24 hours |
FAILED in your delivery history. You can manually replay failed events from the sandbox dashboard or via the API.
View Delivery History
Check the status of recent webhook deliveries — useful for debugging:Remove a Webhook
Testing Webhooks in the Sandbox
During local development, your server is not publicly accessible — so we cannot reach yourlocalhost:3000. Two tools solve this:
webhook.site — simplest option for inspecting payloads
webhook.site — simplest option for inspecting payloads
webhook.site gives you a public HTTPS URL instantly, with no setup. Visit the site, copy the unique URL it gives you, and register that as your webhook URL in the sandbox. Every request we send to it appears in the browser in real time.Best for: Quickly inspecting what the webhook payload looks like. Not suitable for testing your actual application logic.
ngrok — tunnel to your local server
ngrok — tunnel to your local server
ngrok creates a secure public HTTPS tunnel to your local development server. Install it, run Best for: End-to-end testing your full webhook handling logic locally before deploying.
ngrok http 3000 (replacing 3000 with your local port), and it gives you a public URL like https://a1b2c3d4.ngrok.io. Register that URL as your webhook.Now when we send a webhook to that URL, it tunnels through ngrok to your local server — so your actual application code handles it, exactly as it would in production.The free tier of ngrok gives you a new URL every time you restart it. If you are doing extended testing, note down your webhook ID and update the URL each session, or sign up for a paid ngrok plan that gives you a fixed domain.