Know instantly when payments succeed, fail, or need action. Webhooks keep your system in sync without polling our API.
Subscribe to any combination of events and receive HTTPS POST requests to your endpoint in real time.
Payment successfully processed and funds confirmed. Trigger fulfillment, unlock access, or send receipt.
Payment attempt failed. Contains the failure reason (insufficient funds, timeout, etc.) so you can retry or notify the customer.
Customer initiated the payment but confirmation is still awaited (e.g. USSD prompt not yet completed).
Disbursement sent successfully. Mobile wallet has been credited. Update your records and notify the recipient.
Disbursement failed (invalid phone number, operator error, etc.). The amount is refunded to your balance.
Refund successfully returned to the customer's wallet. Update the order status in your system.
Subscription successfully renewed for another billing period. Extend access and send a renewal confirmation.
Subscription cancelled (by user or after failed payment retry exhaustion). Revoke access and archive the customer.
{
"id": "evt_01HX9Z2KPQRS4T5UV6WX7YZ",
"type": "payment.completed",
"created_at": "2026-04-02T14:32:11Z",
"data": {
"id": "pay_9fX2m4qK8vLn3pR",
"amount": 25000,
"currency": "XOF",
"status": "completed",
"method": "orange_money",
"reference": "ORDER_2026_001",
"customer": {
"phone": "+23707XXXXXXXX",
"name": "Kofi Asante"
},
"completed_at": "2026-04-02T14:32:09Z"
}
}
Every webhook is signed with HMAC-SHA256 using your webhook secret. Always verify the signature before processing the event to prevent forged requests.
Bitwisi-Signature headerverifyWebhook() helperconst { verifyWebhook } = require('bitwisi-pay');
app.post('/webhook', (req, res) => {
const signature = req.headers['bitwisi-signature'];
const isValid = verifyWebhook(
req.rawBody,
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) return res.status(401).send('Unauthorized');
// Safe to process the event
const event = req.body;
if (event.type === 'payment.completed') {
fulfillOrder(event.data.reference);
}
res.sendStatus(200);
});
Auto-retry
Up to 5 delivery attempts with exponential backoff
Delivery time
Events delivered within a second of the transaction
Delivery logs
Full request/response logs kept for 30 days
Manual replay
Replay any failed event from the dashboard
Create a free account and configure webhooks in seconds from the dashboard.