The Paystack Balance API returns your available and ledger balance per currency. The Settlement API lists settlement batches with gross amount, fees, net amount, settlement date, and status. Together they let you build automated reconciliation that matches Paystack payouts against your bank statement entries.
The balance endpoint tells you how much money is sitting in your Paystack account at this moment. It is a read-only snapshot.
const response = await fetch('https://api.paystack.co/balance', {
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
});
const data = await response.json();
// data.data is an array of balance objects
// Example response:
// [
// { "currency": "NGN", "balance": 15000000 },
// { "currency": "GHS", "balance": 500000 }
// ]
The balance value is in the smallest currency unit: kobo for NGN, pesewas for GHS, cents for ZAR and KES. To get the human-readable amount, divide by 100. So 15000000 kobo is NGN 150,000.
If you accept payments in multiple currencies, you get one balance entry per currency. A Nigerian business that also accepts GHS payments will see two entries.
What the balance includes:
What the balance does not include:
The balance is useful for two things: knowing if you have enough funds to initiate a transfer, and monitoring your account health at a glance.
The settlement endpoint lists every settlement batch Paystack has sent (or attempted to send) to your bank account.
// List settlements with optional date filters
const response = await fetch(
'https://api.paystack.co/settlement?from=2026-07-01&to=2026-07-22',
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
const data = await response.json();
// data.data is an array of settlement objects
// Each object:
// {
// "id": 12345,
// "total_amount": 5000000, // Gross charges included (kobo)
// "total_fees": 75000, // Fees deducted (kobo)
// "net_amount": 4925000, // What was sent to your bank (kobo)
// "currency": "NGN",
// "status": "success", // or "pending" or "failed"
// "settlement_date": "2026-07-22T00:00:00.000Z"
// }
Key fields in each settlement object:
Pagination: The settlement endpoint returns results in pages. Use the perPage and page query parameters to navigate through large result sets.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
When you find a settlement whose net amount does not match your bank credit, you need to see the individual transactions that were included. The settlement transactions endpoint gives you this breakdown.
// Get transactions included in settlement #12345
const response = await fetch(
'https://api.paystack.co/settlement/12345/transactions',
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
const data = await response.json();
// data.data is an array of transactions
// Each transaction contains:
// - reference: your transaction reference
// - amount: charge amount in kobo
// - fees: fee deducted for this transaction
// - customer: { email, ... }
// - created_at: when the charge happened
This endpoint lets you trace every kobo. If your bank statement shows a credit of NGN 49,250 but your records say you should have received NGN 50,000, you can pull the settlement transactions, sum the fees, and find the exact source of the difference.
Common reasons for discrepancies:
Here is a practical reconciliation workflow that runs as a daily background job.
async function reconcileSettlements() {
// 1. Fetch yesterday's settlements from Paystack
const yesterday = new Date(Date.now() - 86400000).toISOString().split('T')[0];
const today = new Date().toISOString().split('T')[0];
const response = await fetch(
'https://api.paystack.co/settlement?from=' + yesterday + '&to=' + today,
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
const settlements = await response.json();
for (const settlement of settlements.data) {
// 2. Check if we already reconciled this settlement
const existing = await db.query(
'SELECT id FROM reconciled_settlements WHERE paystack_settlement_id = $1',
[settlement.id]
);
if (existing.rows.length > 0) continue;
// 3. Fetch the transactions in this settlement
const txResponse = await fetch(
'https://api.paystack.co/settlement/' + settlement.id + '/transactions',
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
const transactions = await txResponse.json();
// 4. Cross-check against our orders
let matchedCount = 0;
let unmatchedRefs = [];
for (const tx of transactions.data) {
const order = await db.query(
'SELECT id FROM orders WHERE paystack_reference = $1 AND status = $2',
[tx.reference, 'paid']
);
if (order.rows.length > 0) {
await db.query(
'UPDATE orders SET status = $1, settled_at = $2 WHERE paystack_reference = $3',
['settled', settlement.settlement_date, tx.reference]
);
matchedCount++;
} else {
unmatchedRefs.push(tx.reference);
}
}
// 5. Record the reconciliation result
await db.query(
'INSERT INTO reconciled_settlements (paystack_settlement_id, net_amount, matched, unmatched, reconciled_at) VALUES ($1, $2, $3, $4, $5)',
[settlement.id, settlement.net_amount, matchedCount, unmatchedRefs.length, new Date()]
);
// 6. Alert on unmatched transactions
if (unmatchedRefs.length > 0) {
console.log('Unmatched transactions in settlement ' + settlement.id + ': ' + unmatchedRefs.join(', '));
// Send alert to finance team
}
}
}
Run this job daily after the settlement window closes. In Nigeria with T+1 settlement, run it in the morning to catch the previous day's settlement.
If you use Paystack Transfers to pay vendors, contractors, or customers, your available balance is the funding source. Before initiating a transfer, check that you have enough balance.
async function canTransfer(amountInKobo, currency) {
const response = await fetch('https://api.paystack.co/balance', {
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
});
const data = await response.json();
const balanceEntry = data.data.find(function(b) { return b.currency === currency; });
if (!balanceEntry) {
return { canTransfer: false, reason: 'No balance in ' + currency };
}
if (balanceEntry.balance < amountInKobo) {
return {
canTransfer: false,
reason: 'Insufficient balance. Available: ' + (balanceEntry.balance / 100) + ' ' + currency + ', Required: ' + (amountInKobo / 100) + ' ' + currency,
};
}
return { canTransfer: true, available: balanceEntry.balance };
}
This check prevents transfer failures due to insufficient balance. Paystack rejects transfers that exceed your available balance, but checking beforehand gives you a chance to show a meaningful error message or queue the transfer for later.
Keep in mind that the balance can change between your check and the actual transfer request. If multiple transfer requests happen concurrently, you could pass the balance check but still fail the transfer. Handle the insufficient balance error from the Transfer API as a fallback.
If your Paystack account accepts payments in multiple currencies, the Balance API returns a separate entry for each currency. Settlements happen per currency too. A GHS settlement goes to your Ghana bank account, and an NGN settlement goes to your Nigerian bank account.
When building financial dashboards or reports, display each currency balance separately. Do not convert and sum them. Exchange rates fluctuate, and your accounting system needs to track each currency independently.
async function displayBalances() {
const response = await fetch('https://api.paystack.co/balance', {
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
});
const data = await response.json();
for (const entry of data.data) {
const amount = entry.balance / 100;
console.log(entry.currency + ': ' + amount.toLocaleString());
}
// Output:
// NGN: 150,000
// GHS: 5,000
}
For settlement reconciliation across currencies, run separate reconciliation jobs for each currency. Each currency has its own settlement schedule, fee structure, and bank account destination.
For the broader picture of how settlement fits into the accept payments workflow, see the complete accept payments guide. For settlement timing specifics, see settlement timelines and what engineers should assume.
These mistakes show up repeatedly in production integrations:
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