Real‑time Webhooks for Modern Integrations
Receive instant, secure callbacks when events occur in your B21 account. Build reactive systems, reduce polling, and ship faster with verified deliveries.
curl -X POST https://your-app.example/webhook \\ -H "Content-Type: application/json" \\ -H "B21-Signature: $SIGNATURE" \\ -d '{ "id": "evt_123", "type": "payment.succeeded", "data": {"object": {"id": "pay_123", "amount": 10000, "currency": "NGN"}} }'
Reduced Polling
Stop wasting API calls; react the moment something happens.
Event Coverage
Payments, transfers, disputes, accounts — all in one stream.
Trust & Security
Signed requests, HTTPS only, and timestamp verification.
Webhook Payload Examples
Click any code to copycurl -X POST https://your-app.example/webhook \\ -H "Content-Type: application/json" \\ -H "B21-Signature: $SIGNATURE" \\ -d '{ "id": "evt_123", "type": "payment.succeeded", "data": {"object": {"id": "pay_123", "amount": 10000, "currency": "NGN"}} }'
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.get('B21-Signature'); const expected = crypto.createHmac('sha256', process.env.WEBHOOK_SECRET) .update(req.body) .digest('hex'); if (signature !== expected) return res.status(401).send('Unauthorized'); const event = JSON.parse(req.body); // switch(event.type) { ... } res.status(200).send('OK'); });
$payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_B21_SIGNATURE'] ?? ''; $expected = hash_hmac('sha256', $payload, $_ENV['WEBHOOK_SECRET']); if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Unauthorized'); } $event = json_decode($payload, true); // handle $event['type'] echo 'OK';
from flask import Flask, request import os, hmac, hashlib, json app = Flask(__name__) @app.post('/webhook') def webhook(): payload = request.data signature = request.headers.get('B21-Signature', '') expected = hmac.new(bytes(os.getenv('WEBHOOK_SECRET'),'utf-8'), payload, hashlib.sha256).hexdigest() if not hmac.compare_digest(expected, signature): return ('Unauthorized', 401) event = json.loads(payload) # handle event['type'] return ('OK', 200)
Popular Events
Setup in 4 steps
Security & Best Practices
Start receiving webhooks in minutes
Plug into payments, transfers, disputes and more — instantly.
Webhooks
Real-time notifications for your application when events occur in your B21 account
What are Webhooks?
Webhooks are HTTP callbacks that B21 sends to your application when specific events occur. Instead of polling our API for changes, webhooks allow you to receive real-time notifications, making your integration more efficient and responsive.
Real-time Updates
Get instant notifications when events occur
Reduced API Calls
No need to constantly poll for updates
Automatic Sync
Keep your systems in sync automatically
Secure Delivery
Cryptographically signed for security
Available Event Types
Payment Events
- payment.created
- payment.succeeded
- payment.failed
- payment.canceled
- payment.refunded
Transfer Events
- transfer.created
- transfer.processing
- transfer.completed
- transfer.failed
- transfer.reversed
Account Events
- account.updated
- account.verified
- account.suspended
- balance.updated
Dispute Events
- dispute.created
- dispute.updated
- dispute.resolved
- dispute.closed
Setting Up Webhooks
Create Endpoint
Create an HTTP endpoint in your application to receive webhook events
Configure Webhook
Add your endpoint URL in the B21 dashboard and select events to receive
Verify Signature
Implement signature verification to ensure webhook authenticity
Handle Events
Process the webhook events and update your application accordingly
Example Webhook Endpoint
Webhook Payload Examples
{
"id": "evt_1234567890",
"type": "payment.succeeded",
"created": "2025-08-02T23:31:00Z",
"data": {
"object": {
"id": "pay_1234567890",
"amount": "10000",
"currency": "NGN",
"status": "succeeded",
"customer": {
"id": "cus_1234567890",
"email": "customer@example.com",
"name": "John Doe"
},
"created_at": "2025-08-02T23:30:00Z",
"updated_at": "2025-08-02T23:31:00Z"
}
}
}
{
"id": "evt_0987654321",
"type": "transfer.completed",
"created": "2025-08-02T23:31:00Z",
"data": {
"object": {
"id": "txf_0987654321",
"amount": "50000",
"currency": "NGN",
"status": "completed",
"recipient": {
"account_number": "1234567890",
"bank_code": "044",
"name": "Jane Smith"
},
"created_at": "2025-08-02T23:25:00Z",
"completed_at": "2025-08-02T23:31:00Z"
}
}
}
{
"id": "evt_1122334455",
"type": "dispute.created",
"created": "2025-08-02T23:31:00Z",
"data": {
"object": {
"id": "dp_1122334455",
"payment_id": "pay_1234567890",
"amount": "10000",
"currency": "NGN",
"reason": "fraudulent",
"status": "warning_needs_response",
"created_at": "2025-08-02T23:31:00Z"
}
}
}
Security & Best Practices
B21 webhooks include several security features to ensure the integrity and authenticity of the data you receive.
HMAC Signatures
Every webhook is signed with HMAC-SHA256
Timestamp Verification
Prevent replay attacks with timestamps
Automatic Retries
Failed deliveries are automatically retried
HTTPS Only
All webhooks are delivered over HTTPS