Get Ledger Reconciliation
Retrieve reconciliation data combining the daily summary with current account balances. This endpoint is designed for daily reconciliation workflows and financial auditing.
GET
https://api.zenpayz.com/merchant/api/v1/ledger/reconciliationBearer · API key
Request
Headers
| Header | Description |
|---|---|
Authorization REQUIRED | Bearer {api_key} |
X-Signature REQUIRED | HMAC-SHA256 signature |
X-Timestamp REQUIRED | ISO 8601 timestamp |
X-Secret-Salt REQUIRED | Secret salt for HMAC validation |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
date REQUIRED | string- | Date in YYYY-MM-DD format |
currency OPTIONAL | string- | Filter by currency code (e.g., INR, USD) |
Response
Success (200 OK)
{
"success": true,
"data": {
"summary": {
"summaryId": "sum_20240115_mer_xyz789",
"summaryDate": "2024-01-15",
"merchantId": "mer_xyz789",
"currency": "INR",
"openingAvailableBalance": 100000,
"closingAvailableBalance": 125000,
"openingPendingBalance": 5000,
"closingPendingBalance": 7500,
"openingBlockedBalance": 2000,
"closingBlockedBalance": 3000,
"totalDepositsGross": 35000,
"totalDepositsNet": 33250,
"depositCount": 15,
"totalDepositFees": 1750,
"totalPayouts": 8000,
"payoutCount": 3,
"totalPayoutFees": 250,
"totalRefunds": 1500,
"refundCount": 2,
"totalChargebacks": 500,
"chargebackCount": 1,
"totalSettlements": 0,
"settlementCount": 0,
"totalFeesCollected": 2000,
"totalTransactionCount": 21,
"grossTransactionValue": 45000,
"netMovement": 25000,
"generatedAt": "2024-01-16T00:05:00.000Z",
"isFinalized": true
},
"balances": [
{
"accountCategory": "MERCHANT_AVAILABLE",
"currency": "INR",
"balance": 125000
},
{
"accountCategory": "MERCHANT_PENDING",
"currency": "INR",
"balance": 7500
},
{
"accountCategory": "MERCHANT_BLOCKED",
"currency": "INR",
"balance": 3000
},
{
"accountCategory": "RESERVE_PAYOUT",
"currency": "INR",
"balance": 5000
},
{
"accountCategory": "RESERVE_RISK",
"currency": "INR",
"balance": 1250
},
{
"accountCategory": "RESERVE_CHARGEBACK",
"currency": "INR",
"balance": 500
}
]
},
"message": "Reconciliation data retrieved successfully"
}
Reconciliation Verification
To verify reconciliation, ensure the following conditions are met:
- Balance Continuity: Today's opening balance should equal yesterday's closing balance
- Net Movement Calculation:
netMovement = totalDepositsNet - totalPayouts - totalRefunds - totalChargebacks - Closing Balance Verification:
closingAvailableBalance = openingAvailableBalance + netMovement - Current Balance Match: The
balancesarray should match the summary's closing balances
Discrepancy Indicators
| Check | Formula | Action if Failed |
|---|---|---|
| Balance continuity | today.openingBalance == yesterday.closingBalance | Investigate overnight adjustments |
| Movement accuracy | netMovement == deposits - payouts - refunds - chargebacks | Check for missing transactions |
| Real-time match | balances.MERCHANT_AVAILABLE == summary.closingAvailableBalance | May indicate pending transactions |
Examples
- cURL
- SDK
# Get reconciliation data for specific date
curl -X GET "https://api.zenpays.com/merchant/api/v1/ledger/reconciliation?date=2024-01-15¤cy=INR" \
-H "Authorization: Bearer zp_test_xxxxx" \
-H "X-Timestamp: 2024-01-15T10:30:00.000Z" \
-H "X-Signature: a1b2c3d4e5f6..." \
-H "X-Secret-Salt: your_secret_salt"
// Get reconciliation data for yesterday (finalized)
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const dateStr = yesterday.toISOString().split('T')[0];
const { summary, balances } = await zenpays.ledger.getReconciliation({
date: dateStr,
currency: 'INR'
});
console.log(`Reconciliation for ${summary.summaryDate}`);
console.log(`Status: ${summary.isFinalized ? 'Finalized' : 'Pending'}`);
// Verify net movement calculation
const calculatedNetMovement =
summary.totalDepositsNet -
summary.totalPayouts -
summary.totalRefunds -
summary.totalChargebacks;
const movementMatch = calculatedNetMovement === summary.netMovement;
console.log(`\nNet Movement Verification:`);
console.log(`Reported: ${summary.netMovement}`);
console.log(`Calculated: ${calculatedNetMovement}`);
console.log(`Match: ${movementMatch ? 'YES' : 'DISCREPANCY!'}`);
// Verify closing balance
const expectedClosing = summary.openingAvailableBalance + summary.netMovement;
const closingMatch = expectedClosing === summary.closingAvailableBalance;
console.log(`\nClosing Balance Verification:`);
console.log(`Expected: ${expectedClosing}`);
console.log(`Reported: ${summary.closingAvailableBalance}`);
console.log(`Match: ${closingMatch ? 'YES' : 'DISCREPANCY!'}`);
// Compare with current balances
const availableBalance = balances.find(b => b.accountCategory === 'MERCHANT_AVAILABLE');
const pendingBalance = balances.find(b => b.accountCategory === 'MERCHANT_PENDING');
const blockedBalance = balances.find(b => b.accountCategory === 'MERCHANT_BLOCKED');
console.log(`\nCurrent vs Closing Balance Comparison:`);
console.log(`Available: Current ${availableBalance?.balance} vs Closing ${summary.closingAvailableBalance}`);
console.log(`Pending: Current ${pendingBalance?.balance} vs Closing ${summary.closingPendingBalance}`);
console.log(`Blocked: Current ${blockedBalance?.balance} vs Closing ${summary.closingBlockedBalance}`);
// Check for reserves
const reserves = balances.filter(b => b.accountCategory.startsWith('RESERVE_'));
const totalReserves = reserves.reduce((sum, r) => sum + r.balance, 0);
console.log(`\nTotal Reserves: ${totalReserves}`);
reserves.forEach(r => {
console.log(` ${r.accountCategory}: ${r.balance}`);
});
// Generate reconciliation report
const reconciliationReport = {
date: summary.summaryDate,
status: summary.isFinalized ? 'FINALIZED' : 'PENDING',
checks: {
netMovement: movementMatch ? 'PASS' : 'FAIL',
closingBalance: closingMatch ? 'PASS' : 'FAIL',
},
summary: {
deposits: summary.totalDepositsGross,
fees: summary.totalFeesCollected,
payouts: summary.totalPayouts,
refunds: summary.totalRefunds,
chargebacks: summary.totalChargebacks,
netMovement: summary.netMovement,
},
balances: {
available: availableBalance?.balance || 0,
pending: pendingBalance?.balance || 0,
blocked: blockedBalance?.balance || 0,
reserves: totalReserves,
}
};
console.log('\n=== Reconciliation Report ===');
console.log(JSON.stringify(reconciliationReport, null, 2));