Paystack balances are funded in two main ways: through customer payments (which settle into your balance automatically) and through direct deposits to a dedicated funding account (bank transfer to the account shown in your Paystack dashboard). Paystack does not provide an API endpoint for depositing money. Monitor your balance programmatically using GET /balance and set up alerts before scheduled payout runs.
Your Paystack balance grows from two sources.
Customer payments. Every successful payment through your Paystack integration adds to your balance. The money enters your total balance immediately but is not available for transfers until it completes the settlement cycle. The settlement cycle depends on your account configuration and market (often T+1 or next business day in many markets).
Direct deposits. You can fund your balance by making a bank transfer to a dedicated account provided by Paystack. Log into your Paystack dashboard and look for the "Fund Balance" or "Dedicated Account" section. Paystack assigns you an account number at a partner bank. Any deposit to that account is credited to your Paystack balance.
Direct deposits are useful when your payout obligations exceed your incoming payments, or when you need to pre-fund payouts (like payroll) that are not covered by customer revenue.
Paystack can assign a dedicated virtual account (DVA) to your business. This is a permanent bank account number at one of Paystack's partner banks. Any transfer to this account is credited to your Paystack balance.
To set up a DVA, check your Paystack dashboard under Settings or Contact Paystack support. The availability and configuration of DVAs depends on your market and account type.
Once you have a DVA, your finance team can set up a standing order or recurring transfer from your company's bank account to keep your Paystack balance funded. This is especially useful for companies that run regular payouts (weekly vendor settlements, monthly payroll) and need a predictable balance.
// You cannot create DVAs through the API for balance funding
// But you can monitor when funds arrive using the balance endpoint
async function checkForNewFunding(previousBalance, currency) {
var current = await getAvailableBalance(currency);
if (current.total > previousBalance) {
var increase = current.total - previousBalance;
console.log(
'Balance increased by ' + (increase / 100) + ' ' + currency
+ '. New balance: ' + (current.total / 100)
);
// Check if we now have enough for pending payouts
var pendingTotal = await db.payouts.sumPendingAmount(currency);
if (current.total >= pendingTotal) {
console.log('Balance sufficient for all pending payouts. Ready to execute.');
return { ready: true, balance: current.total };
}
}
return { ready: false, balance: current.total };
}
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
// Run every hour or on a schedule matching your payout cadence
async function monitorBalance() {
var currencies = ['NGN', 'KES', 'GHS'];
for (var i = 0; i < currencies.length; i++) {
var currency = currencies[i];
var balance = await getAvailableBalance(currency);
// Check against upcoming payouts
var upcomingPayouts = await db.payouts.sumApprovedAmount(currency);
var status = {
currency: currency,
available: balance.total / 100,
upcoming: upcomingPayouts / 100,
surplus: (balance.total - upcomingPayouts) / 100,
canCoverPayouts: balance.total >= upcomingPayouts,
};
// Low balance alert
if (!status.canCoverPayouts) {
await sendAlert({
type: 'funding_needed',
message: currency + ' balance (' + status.available
+ ') cannot cover upcoming payouts (' + status.upcoming
+ '). Shortfall: ' + Math.abs(status.surplus) + ' ' + currency,
urgency: 'high',
});
}
// Healthy balance log
console.log(
currency + ': Available=' + status.available
+ ', Upcoming=' + status.upcoming
+ ', Surplus=' + status.surplus
);
}
}
Set the monitoring frequency based on your payout cadence. If you run daily payouts, check the balance every 2-4 hours. If payouts are weekly, a daily check is sufficient. The key is to catch shortfalls before the payout execution window, giving your finance team time to fund the balance.
The best payout systems do not fail when the balance is short. They hold payouts until the balance is funded.
async function executePayoutsWithFundingCheck(currency) {
var approved = await db.payouts.findApprovedByCurrency(currency);
if (approved.length === 0) return;
var totalNeeded = 0;
for (var i = 0; i < approved.length; i++) {
totalNeeded += approved[i].amountMinorUnit;
}
var balance = await getAvailableBalance(currency);
if (balance.total >= totalNeeded) {
// Full execution
console.log('Balance sufficient. Executing all ' + approved.length + ' payouts.');
await executeBatch(approved, currency);
return;
}
// Partial execution: prioritize by age (oldest first)
var sorted = approved.sort(function(a, b) {
return new Date(a.createdAt) - new Date(b.createdAt);
});
var runningTotal = 0;
var canExecute = [];
var mustWait = [];
for (var j = 0; j < sorted.length; j++) {
if (runningTotal + sorted[j].amountMinorUnit <= balance.total) {
runningTotal += sorted[j].amountMinorUnit;
canExecute.push(sorted[j]);
} else {
mustWait.push(sorted[j]);
}
}
if (canExecute.length > 0) {
console.log(
'Partial execution: ' + canExecute.length + ' payouts now, '
+ mustWait.length + ' held for funding.'
);
await executeBatch(canExecute, currency);
}
if (mustWait.length > 0) {
await sendAlert({
type: 'partial_execution',
message: mustWait.length + ' payouts held due to insufficient '
+ currency + ' balance. Fund ' + ((totalNeeded - balance.total) / 100)
+ ' ' + currency + ' to cover the remainder.',
});
}
}
This approach maximizes the number of payouts processed with the available balance while holding the rest for later. It is better than the alternative of failing the entire batch because the balance is 10% short.
If your payouts are funded by customer payments (the most common model for marketplaces), you need to align your payout schedule with your Paystack settlement cycle.
Example: If your settlement cycle is T+1 (next business day), customer payments received on Monday settle into your available balance by Tuesday. If you run vendor payouts on Monday, you only have access to funds from Saturday's payments and earlier. Monday's customer payments are not yet available.
Practical guidelines:
For the broader payout scheduling picture, see payout scheduling and batching strategies. For balance checks, see transfer balance checks before initiating payouts.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course