1curl -X GET 'https://api.budpay.com/api/v2/resend_transaction_webhook/BUD_1673600359168063493' \2 -H 'Content-Type: application/json' \3 -H 'Authorization: Bearer YOUR_SECRET_KEY'{ "success": true, "message": "Webhook Resent Successfully"}This section contains the recommended flow for integrating BudPay Callback/Webhook services when using the BudPay RESTful API. The webhook service enables BudPay to send your system an update on certain activities.
Webhooks allow you to receive real-time notifications about events that happen in your BudPay account. When an event occurs, BudPay sends an HTTP POST request to the webhook URL you've configured.
BudPay sends webhook notifications for the following activities:
When a transaction is completed, BudPay sends a webhook with the following structure:
{
"notify": "transaction",
"notifyType": "successful",
"data": {
"id": 1050471,
"currency": "USD",
"amount": "5.22",
"reference": "482208088163205800",
"ip_address": null,
"channel": "card",
"type": "transaction",
"domain": "live",
"fees": "0.19836",
"plan": null,
"requested_amount": "5.22",
"status": "success",
"card_attempt": 1,
"settlement_batchid": null,
"message": "Approved",
"metadata": "MID: DPPSPBDNG|15173|5399|CAPTURED|Approved|SUCCESS|520149xxxxxx1019|MASTERCARD|2022-08-08T12:59:17.516Z|2022-08-08|175714|USD|222012015173|13203834|UBAS3I01",
"created_at": "2022-08-08T12:58:09.000000Z",
"updated_at": "2022-08-08T12:59:23.000000Z",
"paid_at": "2022-08-08 13:59:23",
"customer": {
"id": 427351,
"first_name": null,
"last_name": null,
"email": "melasbah83@gmail.com",
"phone": null,
"domain": "live",
"customer_code": "CUS_6kj536tc0kx9brb",
"metadata": "{}",
"status": "active"
}
}
}| Field | Type | Description |
|---|---|---|
notify | String | Event type: transaction |
notifyType | String | Event status: successful, failed, pending |
data.id | Integer | Transaction ID |
data.reference | String | Unique transaction reference |
data.amount | String | Total amount including fees |
data.requested_amount | String | Original amount before fees |
data.currency | String | Currency code (NGN, USD, GHS, KES) |
data.status | String | Transaction status: success, failed, pending |
data.channel | String | Payment channel: card, transfer, mobile_money |
data.fees | String | Transaction processing fees |
data.customer | Object | Customer information |
When a payout is completed, BudPay sends a webhook with the following structure:
{
"notify": "payout",
"notifyType": "successful",
"data": {
"id": 4552,
"reference": "BUD_trf_4fe1v.....",
"sessionid": "110021221004050251.....",
"currency": "NGN",
"amount": "500000",
"fee": "100",
"bank_code": "090405",
"bank_name": "Rolez Microfinance Bank",
"account_number": "0000222293",
"account_name": "Samuel Bud",
"narration": "my narration",
"domain": "live",
"status": "success",
"settled_by": null,
"subaccount": null,
"created_at": "2022-10-04T05:03:00.0000000000Z",
"updated_at": "2022-10-04T05:03:03.000000Z"
}
}| Field | Type | Description |
|---|---|---|
notify | String | Event type: payout |
notifyType | String | Event status: successful, failed, pending |
data.id | Integer | Payout ID |
data.reference | String | Unique payout reference |
data.amount | String | Payout amount |
data.fee | String | Payout processing fee |
data.bank_code | String | Recipient bank code |
data.bank_name | String | Recipient bank name |
data.account_number | String | Recipient account number |
data.account_name | String | Recipient account name |
data.status | String | Payout status: success, failed, pending |
When a virtual account receives a credit, BudPay sends a webhook with the following structure:
{
"data": {
"id": 14457138,
"fees": "30",
"plan": null,
"type": "dedicated_account",
"amount": "20",
"domain": "live",
"status": "success",
"channel": "dedicated_account",
"gateway": "wema",
"message": "Account credited successfully",
"paid_at": "01/01/2025 15:03:44",
"currency": "NGN",
"customer": {
"id": 7608196,
"email": "2532-adetunjioluwakayode@gmail.com",
"phone": "08031975397",
"domain": "live",
"status": "active",
"metadata": "{}",
"last_name": "Adetunji",
"first_name": "Kayode",
"customer_code": "CUS_ff0ondr3rxekzsd"
},
"reference": "100033250101140325860393638601",
"created_at": "2025-01-01T15:03:44",
"ip_address": null,
"business_id": 30,
"customer_id": 7608196,
"card_attempt": 0,
"requested_amount": "50.00"
},
"notify": "transaction",
"notifyType": "successful",
"transferDetails": {
"amount": "50.00",
"bankcode": "100033",
"bankname": "PALMPAY",
"craccount": "4051242100",
"narration": "OLUWAKAYODE AYORINDE ADETUNJI:8031975397",
"sessionid": "100033250101140325860393638601",
"craccountname": "Inclusive 1 / Kayode Adetunji",
"originatorname": "OLUWAKAYODE AYORINDE ADETUNJI",
"paymentReference": "100033250101140325860393638601",
"originatoraccountnumber": "8031975397"
}
}| Field | Type | Description |
|---|---|---|
notify | String | Event type: transaction |
notifyType | String | Event status: successful |
data.type | String | Transaction type: dedicated_account |
data.amount | String | Net amount after fees |
data.requested_amount | String | Original amount credited |
data.fees | String | Processing fees |
data.gateway | String | Bank gateway used |
transferDetails | Object | Transfer information from sender |
transferDetails.originatorname | String | Sender's name |
transferDetails.originatoraccountnumber | String | Sender's account/phone |
Important: Your webhook URL must be publicly accessible and respond with HTTP 200 status within 30 seconds.
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook/budpay', (req, res) => {
const { notify, notifyType, data } = req.body;
// Verify webhook authenticity (recommended)
// const isValid = verifyWebhookSignature(req);
// if (!isValid) return res.status(401).send('Invalid signature');
// Handle different event types
switch(notify) {
case 'transaction':
handleTransaction(data, notifyType);
break;
case 'payout':
handlePayout(data, notifyType);
break;
case 'virtual_account':
handleVirtualAccount(data, notifyType);
break;
default:
console.log('Unknown webhook type:', notify);
}
// Always respond with 200
res.status(200).json({ received: true });
});
function handleTransaction(data, status) {
if (status === 'successful') {
// Update order status
// Send confirmation email
// Fulfill order
console.log(`Transaction ${data.reference} completed`);
}
}
function handlePayout(data, status) {
if (status === 'successful') {
// Update payout status
// Notify recipient
console.log(`Payout ${data.reference} completed`);
}
}
function handleVirtualAccount(data, status) {
if (status === 'successful') {
// Credit customer wallet
// Send notification
console.log(`Virtual account credited: ${data.reference}`);
}
}
app.listen(3000, () => console.log('Webhook handler running on port 3000'));Resend transaction webhook using transaction reference number.
GET https://api.budpay.com/api/v2/resend_transaction_webhook/{reference}Endpoint: GET https://api.budpay.com/api/v2/resend_transaction_webhook/BUD_1673600359168063493
1curl -X GET 'https://api.budpay.com/api/v2/resend_transaction_webhook/BUD_1673600359168063493' \2 -H 'Content-Type: application/json' \3 -H 'Authorization: Bearer YOUR_SECRET_KEY'{ "success": true, "message": "Webhook Resent Successfully"}Tip: Always verify transactions using the verification API before fulfilling orders, even after receiving a webhook.
Webhooks Not Received
Duplicate Webhooks
Webhook Verification Failed