Skip to main content

Reconciliation

Overviewโ€‹

Reconciliation in payments is the process of matching internal payment records against external confirmations (bank statements, network confirmations, settlement reports) to ensure every transaction is correctly accounted for, with no gaps, duplicates, or errors.


Why Reconciliation Mattersโ€‹

Risk if not reconciledImpact
Undetected failed paymentsCustomer funds lost or not delivered
Duplicate paymentsDouble payment to supplier
Settlement shortfallBank exposed to overnight liquidity risk
Unidentified creditsFunds sitting in suspense, not applied
Regulatory breachFailure to report or account for transactions

Reconciliation Typesโ€‹

1. Payment Reconciliation (Transaction Level)โ€‹

Match each internal payment order against network/bank confirmation:

Internal Payment Order โ†โ†’ pacs.002 / pain.002 confirmation
EndToEndId OrgnlEndToEndId
TxId OrgnlTxId
Amount IntrBkSttlmAmt
Status TxSts

2. Account/Ledger Reconciliationโ€‹

Match posted ledger entries against camt.053 bank statement:

Internal Ledger Entry โ†โ†’ camt.053 Ntry
LedgerEntryId AcctSvcrRef
Amount Amt
BookingDate BookgDt
CdtDbtInd CdtDbtInd

3. Nostro Reconciliationโ€‹

Match FI's own ledger of a correspondent account against the correspondent bank's statement:

Our Nostro Ledger โ†โ†’ MT940 / camt.053 from correspondent

4. Settlement Reconciliationโ€‹

Verify actual settlement movements at the central bank (ESA):

Expected net settlement position โ†โ†’ RBA FSS settlement confirmation

Reconciliation Data Sourcesโ€‹

SourceMessageContent
Internal payment systemN/APayment orders, statuses
NPP Networkpacs.002Per-transaction confirmation
SWIFTpacs.002 / MT199Status per payment
Bank statement (own)camt.053 / MT940All entries for period
Intraday notificationcamt.054Real-time transaction alerts
Settlement confirmationRBA FSS reportNet position settled

Reconciliation Processโ€‹

End of Business Day
โ”‚
โ–ผ
Collect all internal payment records for the day
โ”‚
โ–ผ
Receive camt.053 from correspondent/internal bank
โ”‚
โ–ผ
For each internal record:
Search for matching camt.053 entry
โ”‚
โ”œโ”€โ”€ MATCHED โ†’ Check amount, date, currency
โ”‚ โ””โ”€โ”€ All match โ†’ RECONCILED โœ…
โ”‚ โ””โ”€โ”€ Mismatch โ†’ FLAG for investigation
โ”‚
โ””โ”€โ”€ UNMATCHED โ†’ Check pacs.002 status
โ”œโ”€โ”€ RJCT โ†’ Reverse and reconcile
โ”œโ”€โ”€ PDNG โ†’ Carry forward
โ””โ”€โ”€ No response โ†’ Escalate
โ”‚
โ–ผ
Balance check:
Statement opening + credits โˆ’ debits = closing?
โ”‚
โ”œโ”€โ”€ YES โ†’ Reconciliation complete โœ…
โ””โ”€โ”€ NO โ†’ Investigate discrepancy

Match Keys (IDs Used for Reconciliation)โ€‹

IDSet ByCarried InUsed For
EndToEndIdOriginating customerpain.001, pacs.008, camt.054E2E payment tracking
TxIdDebtor bankpacs.008, pacs.002Interbank transaction matching
InstrIdSending bankpacs.008Instruction-level matching
AcctSvcrRefCreditor bankcamt.053, camt.054Statement entry matching
UETRDebtor bankAll SWIFT messagesSWIFT payment tracking
MsgIdSenderAll messagesMessage-level dedup

Suspense Accountโ€‹

The suspense account is a holding account for transactions that cannot be immediately matched or applied:

Reasons for suspense:
- Inbound payment โ€” creditor account not found
- Credit or debit with no matching payment order
- Amount mismatch
- Pending investigation (fraud, sanctions)

Suspense management:
- All suspense items must be aged and reviewed daily
- SLA: resolve within 5 business days
- Unresolved items escalated to operations management
- Regulatory obligation: cannot hold funds indefinitely

Reconciliation Statusesโ€‹

StatusMeaning
MATCHEDInternal record matched to external confirmation
RECONCILEDMatched and verified (amount, date, status correct)
UNMATCHEDNo corresponding external record found
DISPUTEDMatch found but data doesn't agree
PENDINGAwaiting confirmation (e.g., T+1 settlement)
WRITTEN_OFFUnrecoverable difference; actioned by finance
IN_SUSPENSEHeld pending investigation

Java Spring Reconciliation Serviceโ€‹

@Service
public class ReconciliationService {

@Scheduled(cron = "0 0 22 * * MON-FRI") // 10 PM weekdays
public void runDailyReconciliation() {
LocalDate today = LocalDate.now();

// 1. Get all internal payment orders for today
List<PaymentOrder> orders = paymentRepository.findByDate(today);

// 2. Get camt.053 statement entries
List<StatementEntry> entries = statementRepository.findByDate(today);

// 3. Match
ReconciliationReport report = matcher.match(orders, entries);

// 4. Handle unmatched
report.getUnmatched().forEach(unmatched -> {
suspenseService.createItem(unmatched);
alertService.notifyOpsTeam(unmatched);
});

// 5. Handle mismatches
report.getMismatches().forEach(mismatch -> {
investigationService.raise(mismatch);
});

// 6. Publish report
reportingService.publish(report);
}
}

@Component
public class PaymentMatcher {

public ReconciliationReport match(
List<PaymentOrder> orders,
List<StatementEntry> entries) {

Map<String, StatementEntry> entryByRef = entries.stream()
.collect(Collectors.toMap(
StatementEntry::getAcctSvcrRef,
Function.identity()
));

var report = new ReconciliationReport();

for (PaymentOrder order : orders) {
// Try matching by EndToEndId first, then TxId
Optional<StatementEntry> match = findMatch(order, entryByRef);

if (match.isEmpty()) {
report.addUnmatched(order);
} else if (!amountsMatch(order, match.get())) {
report.addMismatch(order, match.get());
} else {
report.addReconciled(order, match.get());
}
}

return report;
}
}

Reconciliation SLAsโ€‹

TypeSLAEscalation
NPP real-timeIntradayWithin 4 hours if unmatched
DE/BECSNext business dayWithin 24 hours
SWIFTT+1 to T+2Within 3 business days
Suspense items5 business daysFinance director sign-off
Nostro breaksEnd of dayTreasury escalation