Paystack Insufficient Balance on Transfer
The insufficient balance error means your available Paystack balance is lower than the transfer amount. Your total balance might look large enough, but Paystack holds unsettled funds (payments from the last 1 to 3 business days) until they clear. Only the available balance can be used for transfers. Check your available balance via GET /balance before initiating transfers. If you need funds immediately, you can fund your Paystack balance via bank transfer from your company account.
What the Error Looks Like
When you call the Paystack Transfer API and your available balance is too low, you get this response:
{
"status": false,
"message": "Your balance is not enough to fulfil this request"
}
The HTTP status code is 400. The transfer is not created at all. Unlike the OTP required response, this is a hard rejection. Nothing is queued, nothing is pending. You cannot proceed until you have enough available balance.
This error can also appear when calling the bulk transfer endpoint with a total that exceeds your available balance. Paystack checks the sum of all transfers in the batch against your available balance before processing any of them.
Available Balance vs Total Balance
Paystack tracks two separate balance figures for your account:
- Total balance. All money that has been collected through your Paystack integration, minus any transfers and Paystack fees. This includes payments that have not yet settled.
- Available balance. The portion of your total balance that has completed the settlement process and is available for transfers. This is the number that matters for payouts.
The gap between total and available balance is your pending settlement. These are payments that customers have made, but the funds have not yet moved from the customer's bank to your Paystack balance.
Settlement timing depends on your account configuration:
- Next-day settlement (T+1). Payments settle the next business day. A payment on Monday is available Tuesday. A payment on Friday is available Monday.
- T+2 or T+3 settlement. Some accounts, especially newer ones or those processing high-risk transactions, have longer settlement windows.
- Weekends and public holidays. Banks do not process settlements on non-business days. A payment on Saturday does not settle until Tuesday (or later if Monday is a holiday).
A common scenario: you collect KES 500,000 in payments on Friday. On Saturday morning, your total balance shows KES 500,000 but your available balance is KES 0 because nothing has settled over the weekend. Your transfer of KES 100,000 fails with insufficient balance even though the money is "there."
Checking Your Balance Before Transfer
Always check your available balance before initiating a transfer. This lets you handle low-balance situations before hitting the error.
async function checkBalance() {
const response = await fetch('https://api.paystack.co/balance', {
headers: {
Authorization: `Bearer ${process.env.PAYSTACK_SECRET_KEY}`,
},
});
const data = await response.json();
if (!data.status) {
throw new Error('Failed to fetch balance');
}
// Paystack returns balances per currency
// Each entry has 'currency' and 'balance' (available balance in kobo/pesewas)
return data.data.map(entry => ({
currency: entry.currency,
available: entry.balance / 100, // Convert from kobo/pesewas to main unit
total: (entry.balance + (entry.pending || 0)) / 100,
pending: (entry.pending || 0) / 100,
}));
}
// Example output:
// [{ currency: 'NGN', available: 450000, total: 950000, pending: 500000 }]
Now build the balance check into your transfer flow:
async function safeTransfer(recipientCode, amount, currency, reference, reason) {
// Step 1: Check balance
const balances = await checkBalance();
const currencyBalance = balances.find(b => b.currency === currency);
if (!currencyBalance) {
return {
success: false,
reason: 'no_balance_for_currency',
message: `No ${currency} balance found on your Paystack account.`,
};
}
if (currencyBalance.available < amount) {
return {
success: false,
reason: 'insufficient_balance',
available: currencyBalance.available,
required: amount,
pending: currencyBalance.pending,
message: `Available balance is ${currency} ${currencyBalance.available.toLocaleString()}. Transfer requires ${currency} ${amount.toLocaleString()}. Pending settlement: ${currency} ${currencyBalance.pending.toLocaleString()}.`,
};
}
// Step 2: Initiate transfer
const response = await fetch('https://api.paystack.co/transfer', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAYSTACK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
source: 'balance',
amount: amount * 100,
recipient: recipientCode,
reference,
reason,
currency,
}),
});
const data = await response.json();
if (data.status) {
return { success: true, data: data.data };
}
return { success: false, message: data.message };
}
The balance check is not a lock. Between checking and transferring, another process might initiate a transfer that reduces your balance. For high-volume systems, add error handling that catches the insufficient balance error even after the check passes.
Building a Transfer Queue for Low-Balance Situations
If your available balance is too low but you know funds will settle soon, queue the transfer and retry after settlement.
// Simplified transfer queue logic
async function queueOrTransfer(transfer) {
const { recipientCode, amount, currency, reference, reason } = transfer;
const result = await safeTransfer(recipientCode, amount, currency, reference, reason);
if (result.success) {
await saveTransferResult(reference, 'completed', result.data);
return result;
}
if (result.reason === 'insufficient_balance') {
// Queue for retry after settlement
await saveToQueue({
...transfer,
queuedAt: new Date().toISOString(),
retryAfter: getNextSettlementTime(),
attempts: 0,
});
console.log(
`Transfer ${reference} queued. Available: ${result.available}, Required: ${amount}. Pending: ${result.pending}`
);
return {
success: false,
queued: true,
message: 'Transfer queued. Will retry after next settlement.',
};
}
return result;
}
function getNextSettlementTime() {
const now = new Date();
const hour = now.getHours();
const day = now.getDay();
// Paystack typically settles in the morning on business days
// If it is before 10 AM on a weekday, settlement might happen today
if (day >= 1 && day <= 5 && hour < 10) {
const settlement = new Date(now);
settlement.setHours(10, 0, 0, 0);
return settlement.toISOString();
}
// Otherwise, next business day at 10 AM
const next = new Date(now);
if (day === 5) next.setDate(next.getDate() + 3); // Friday -> Monday
else if (day === 6) next.setDate(next.getDate() + 2); // Saturday -> Monday
else next.setDate(next.getDate() + 1);
next.setHours(10, 0, 0, 0);
return next.toISOString();
}
Run a cron job that processes the queue after expected settlement times. Check the balance before each retry. If the balance is still too low after multiple retries, alert your team.
Funding Your Paystack Balance
If you need to make transfers but your collected payments have not settled, you can fund your Paystack balance directly from your bank account.
To do this:
- Log in to your Paystack dashboard.
- Go to Balance and click Fund Balance (or Top Up).
- Paystack will show you a dedicated bank account number. Transfer money to this account from your company bank account.
- The funds typically reflect within minutes to a few hours, depending on your bank.
This is useful in several scenarios:
- Payroll. You need to pay employees on the 28th, but your customer payments from the 26th and 27th have not settled yet. Fund your balance from your company account to cover the payroll transfers.
- Vendor payments. A vendor needs to be paid today, but your settlement is tomorrow. Top up your balance to cover it.
- Refunds via transfer. A customer needs a refund, but the original payment has not settled. Fund your balance to send the refund as a transfer.
Keep in mind that funding your Paystack balance is a bank transfer. It is subject to your bank's transfer limits and processing times. Plan ahead rather than trying to fund your balance 30 minutes before payroll runs.
Bulk Transfer Balance Calculation
When you use the bulk transfer endpoint (POST /transfer/bulk), Paystack checks whether your available balance covers the total sum of all transfers in the batch. If any single transfer would push you over, the entire batch is rejected.
async function safeBulkTransfer(transfers, currency) {
// Calculate total needed
const totalNeeded = transfers.reduce((sum, t) => sum + t.amount, 0);
// Check balance
const balances = await checkBalance();
const currencyBalance = balances.find(b => b.currency === currency);
if (!currencyBalance || currencyBalance.available < totalNeeded) {
const available = currencyBalance?.available || 0;
const shortfall = totalNeeded - available;
return {
success: false,
reason: 'insufficient_balance',
totalNeeded,
available,
shortfall,
message: `Bulk transfer needs ${currency} ${totalNeeded.toLocaleString()} but only ${currency} ${available.toLocaleString()} is available. Shortfall: ${currency} ${shortfall.toLocaleString()}`,
};
}
// Proceed with bulk transfer
const response = await fetch('https://api.paystack.co/transfer/bulk', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAYSTACK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
source: 'balance',
currency,
transfers: transfers.map(t => ({
amount: t.amount * 100,
recipient: t.recipientCode,
reference: t.reference,
reason: t.reason,
})),
}),
});
const data = await response.json();
return { success: data.status, data: data.data, message: data.message };
}
For payroll or batch vendor payments, run the balance check early in the process. If the balance is short, you have time to fund it or split the batch into smaller groups that fit within the available balance.
Preventing Balance Surprises
The best way to handle insufficient balance errors is to prevent them from happening in the first place.
- Monitor your balance daily. Set up a script that checks your available and pending balances every morning and sends a summary to your team. If your available balance is below a threshold, alert immediately.
- Understand your settlement schedule. Know exactly when your payments settle. If you are on T+1, payments from Monday settle Tuesday. Build your payout schedule around your settlement schedule.
- Account for Paystack fees. Every payment collected has a Paystack fee deducted. If a customer pays NGN 10,000, you might receive NGN 9,850 after fees. Your available balance will be lower than the sum of payments collected.
- Account for transfers already in progress. Pending transfers reduce your available balance. If you check your balance, see NGN 500,000 available, and initiate a NGN 400,000 transfer, your available balance drops to NGN 100,000 immediately, even before the transfer completes.
- Plan for weekends and holidays. No settlements happen on weekends or public holidays. If you run payroll on Mondays, fund your balance on Friday or ensure enough settled funds carry over from the previous week.
Further Reading
For more on Paystack transfers and troubleshooting:
- Paystack Errors and Troubleshooting: The Complete Reference covers all common Paystack errors.
- Paystack Transfer OTP Required Error explains the OTP requirement for automated transfers.
- Paystack Recipient Creation Failed covers errors when creating transfer recipients.
- Paystack Transfer Failed: Reasons and Recovery explains what happens when transfers fail after initiation.
Building reliable payout systems requires understanding settlement flows and balance management. The McTaba Full-Stack Software and AI Engineering course covers building production payment systems end to end, including automated payouts.
Key Takeaways
- ✓Paystack maintains two balances: total balance (all money collected) and available balance (settled funds you can transfer). Only the available balance matters for transfers.
- ✓Payments take 1 to 3 business days to settle on Paystack, depending on your settlement schedule. A payment collected today is not available for transfer today.
- ✓Always check your available balance via the GET /balance endpoint before initiating transfers. This prevents failed transfers and lets you handle low-balance situations gracefully.
- ✓You can fund your Paystack balance by transferring money from your bank account to your Paystack settlement account. This is useful when you need to make payouts but your collected payments have not settled yet.
- ✓For automated payout systems, build a balance check into your transfer flow. If the available balance is too low, queue the transfer and retry after settlement.
- ✓Weekend and public holiday payments take longer to settle because banks do not process settlements on non-business days.
Frequently Asked Questions
- Why does my Paystack balance show money but transfers still fail?
- Your total balance includes pending settlements, which are payments that have been collected but not yet cleared by the banks. Only the available balance (settled funds) can be used for transfers. Check the GET /balance endpoint to see the breakdown between available and pending amounts.
- How long does it take for payments to settle on Paystack?
- Most Paystack accounts settle on a T+1 basis, meaning payments settle the next business day. Some accounts have T+2 or T+3 settlement. Weekends and public holidays are not business days, so a payment on Friday settles on Monday at the earliest. Check your settlement schedule in the Paystack dashboard under Settings.
- Can I speed up settlement on Paystack?
- You cannot manually trigger early settlement. Paystack processes settlements on a fixed schedule. If you need funds faster than your settlement window allows, fund your Paystack balance from your bank account. Contact Paystack support if you need to discuss changing your settlement schedule.
- Does the balance check guarantee my transfer will succeed?
- No. The balance check is a snapshot at that moment. Between checking and transferring, another process (another API call, a Paystack fee deduction, or a concurrent transfer) could reduce your available balance. Always handle the insufficient balance error in your transfer code, even after a balance check passes.
- How do I fund my Paystack balance?
- Log in to your Paystack dashboard, go to Balance, and click Fund Balance or Top Up. Paystack shows you a dedicated bank account number. Transfer money to that account from your company bank account. Funds typically reflect within minutes to a few hours depending on your bank.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon