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
We may add new event types over time. Handle unknown event types gracefully: log them and return
200 OK without taking action. This way, new events we add won’t cause your endpoint to error.Setting Up a Webhook
1
Build an HTTPS endpoint on your server
Create a route in your web application that accepts
POST requests. This is where we 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)
2
Register your endpoint via the API
Tell us where to send notifications:Response:
3
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 doesn’t respond with 200 OK within 30 seconds, registration fails and you receive an error.Example ping payload:ping event and returns 200. You don’t need to do anything with it other than respond.4
Receive and verify notifications
Once registered, events start arriving. Always verify the
X-Signature header before processing any payload. See the full verification guide below.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: before processing a webhook, check whether you’ve already seen thistransactionRef. If yes, return 200 OK immediately without re-processing.
Retry Behaviour
If your endpoint returns anything other than200 OK, or doesn’t respond within 30 seconds, we retry delivery on this schedule:
After all 7 retries are exhausted, we stop. The event is marked as
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 isn’t publicly accessible, so we can’t 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. 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’re 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.

