Webhooks & Event Handling

Webhooks power the most important parts of your system: receiving Bitcoin, settling fiat, delivering airtime, or triggering a downstream event. They are the bridge between Bitnob and your app when something changes — and they must be handled with care.

This guide teaches you how to build a robust webhook system: one that can handle retries, duplicate messages, bad payloads, delayed delivery, and even downstream service outages.


How Webhooks Work

A webhook is an HTTP request Bitnob sends to your server when something happens. Instead of you polling an endpoint to see “has this payment arrived?”, Bitnob notifies you the moment it’s confirmed.

For example, when a user sends BTC and it clears, Bitnob sends:

Node.js
Note

This is a push notification for your backend. You must handle it like an incoming transaction.

Webhook Flow Overview

Webhook Flow Overview
Note

If your app does not return a 200 OK, Bitnob retries the webhook.

What You Get from Bitnob

Bitnob supports:

Secure webhook delivery for all asynchronous flows

A dashboard to inspect webhook logs, payloads, and retry attempts

Webhooks for offramps, swaps, airtime, and payment confirmations

Note

This makes debugging significantly easier, especially during integration or failure scenarios.

Writing a Webhook Handler

Use a backend route that accepts POST requests with a JSON payload.

Example in Node.js:

// ...existing code...

Writing a Webhook Handler

Use a backend route that accepts POST requests with a JSON payload.

Example in Node.js:

Node.js (Express Example)

Key things to remember:

Respond with 200 OK quickly to prevent retries.

Do not block this handler with long-running DB calls or downstream logic (consider using a queue).

Log every webhook attempt with timestamp and reference.

Bitnob Webhook Retry Behavior

Bitnob retries if:

Your endpoint is offline or times out

Your server returns a 4xx or 5xx

You don't acknowledge the webhook with a 200 OK

Note

The retry interval follows exponential backoff. To prevent repeated delivery of the same event, you must handle idempotency.

idempotency means processing a webhook once and only once, no matter how many times it is received.

Without idempotency, you may:

Send multiple offramps for the same crypto payment

Deliver airtime multiple times (especially dangerous if the amount is large)

Trigger double card funding or duplicate messages to a user

Corrupt internal logs by writing duplicate events with different timestamps

Real-World Failure Example

Before processing any event, check if that reference has already been marked as processed in your database.

1.

Bitnob sends airtime.delivered

2.

Your webhook server receives it but times out before responding

3.

Bitnob retries

4.

Your app processes it again → duplicate airtime top-up sent

How to Fix It

Node.js (Idempotency Check)

Suggested Database Schema

Every time you create a quote, store it alongside your transaction or UI session.

idreferenceeventstatusreceived_at
atx_123abcairtime.deleiveredprocessed2025-04-08T14:20

This makes auditing, debugging, and duplicate suppression easy.

Webhook Retry Behavior

Recommended Webhook Architecture (with Queue)

This decouples fast acknowledgment (step B) from slow logic (step D). Bitnob gets a 200 OK immediately. You process the event asynchronously in the background. Use queues like:

BullMQ or BeeQueue (Node.js)

Sidekiq or Sneakers (Ruby)

Celery (Python)

Redis Streams or Kafka (at scale)

Securing Your Webhooks

Signature Verification

If Bitnob provides webhook signatures (e.g., in a header like X-Bitnob-Signature), verify the payload:

Node.js (Signature Verification)

IP Whitelisting

If Bitnob publishes webhook IP ranges, restrict your endpoint to only accept requests from those addresses.

HTTPS Required

Always use https:// URLs for your webhook. Never expose webhooks over HTTP.

Testing and Debugging Webhooks

For local development:

Use ngrok, localtunnel, or cloudflared to expose your local server

Simulate a transaction (e.g., simulate deposit in sandbox)

Use webhook inspection tools to replay and analyze events

You can also log webhook attempts using a simple logger:

Node.js (Simple Logging)

For production observability, log:

Event type

Reference

Timestamp

Delivery status (received, retried, failed)

What to Always Do

1.

Handle webhooks in a dedicated endpoint

2.

Respond with 200 OK fast

3.

Always make your logic idempotent

4.

Log everything (reference, type, status)

5.

Use a queue if your processing takes time

6.

Verify signatures to secure the source

7.

Use the Bitnob dashboard to inspect payloads and retry if needed

Webhooks are your single source of truth for offchain confirmations. If you treat them like production infrastructure, your product will feel real-time, even though the underlying rails (blockchain, fiat, telcos) are asynchronous and imperfect.

Did you find this page useful?