Three-way reconciliation report

merchant ledger · gateway report · bank statement — generated 03 September 2026, 04:59
Batch size
120
orders → 141 entities
Resolved
90.8%
95% CI [84.9%, 94.5%]
Classification accuracy
100.0%
129/129 vs answer key
Exceptions
13
8 genuine breaks

Resolution by confidence tier

Each resolution records the method that produced it, so the result is stratified by certainty rather than reported as one opaque figure.
TierMethodCountShare
tier 1exact key join12496.9%
tier 2deterministic inference43.1%

Where the engine breaks

Raising defect density alone does not degrade accuracy: each record is classified independently, so more defects of the same kinds change nothing. Defects that interact do. Allowing several defects on one record produces this curve.
90%93%95%98%100%100.098.697.695.792.322%37%52%62%82%compound defect density
Every failure has one shape: an order carrying both a fee mismatch and a refund is reported as one or the other, because the taxonomy allows a single label per record. Neither answer is wrong. The limitation is in the classification scheme, not the matcher.

Per-class performance against the answer key

The generator plants each defect deliberately and records it in a ground-truth file the engine never reads. Every figure below is measured against that key.
ClassPrecisionRecallF1SupportFPFN
clean1.001.001.008200
refund1.001.001.00600
unsettled1.001.001.00600
fee_mismatch1.001.001.00500
failed_payment1.001.001.00500
rounding_noise1.001.001.00400
partial_refund1.001.001.00400
messy_narration1.001.001.00400
chargeback1.001.001.00300
duplicate1.001.001.00300
net_arithmetic_error1.001.001.00200
missing_payment1.001.001.00200
orphan_bank_credit1.001.001.00200
missing_bank_row1.001.001.00100
What this number does and does not show. These figures measure whether the engine correctly identifies the defect classes it was designed around, on data generated by the same author. They are evidence of no false positives and no silently dropped records. They are not evidence of performance on a real merchant's books, where defect types the generator does not model would appear.

Exceptions — 13 records the engine could not resolve

Listed in full, with the reason in each case. Nothing here is dropped or absorbed into the match rate.
RecordTypeClassificationReason
ORD4088orderfee_mismatchfee 20.00 vs expected 15.00 for card (delta 5.00)
ORD4034orderfee_mismatchfee 13.50 vs expected 12.00 for netbanking (delta 1.50)
ORD4051orderfee_mismatchfee 2.25 vs expected 0.00 for upi (delta 2.25)
ORD4089orderfee_mismatchfee 8.25 vs expected 6.00 for card (delta 2.25)
ORD4038orderfee_mismatchfee 17.00 vs expected 12.00 for netbanking (delta 5.00)
GAP_BEFORE_BNK000014statement_gapmissing_bank_rowbalance gap of 7227.29 before BNK000014: a statement line is absent
ORD4026ordermissing_paymentorder present in ledger with no gateway record
ORD4054ordermissing_paymentorder present in ledger with no gateway record
pay_000056txnnet_arithmetic_errorgross 750.00 - fee 0.00 - gst 0.00 != net 760.00
pay_000042txnnet_arithmetic_errorgross 499.00 - fee 0.00 - gst 0.00 != net 509.00
BNK000004bank_roworphan_bank_credit4200.00 on 2026-08-13 corresponds to no settlement
BNK000006bank_roworphan_bank_credit2750.00 on 2026-08-16 corresponds to no settlement
setl_0010settlementsettlement_not_in_bankagent: missing_bank_rowpayout of 7227.29 due 2026-08-21 has no statement line

Agent investigation of the exceptions

Each unresolved record is passed to a bounded agent that selects its own investigation tools. The agent never computes a result: every value below came from deterministic code the model cannot influence. It contributes the investigative path, not the arithmetic.
Investigated
13
44 model calls
Agreed with matcher
12/13
independently, without being told
Tool calls
50
8 distinct tools, across 44 model rounds
Wall clock
259s
20s per record

Tools the agent chose to call

Unprompted. No ordering or preference was specified.
find_related_transactions11
get_order10
check_fee_against_rule8
search_settlements_by_amount6
check_settlement_composition5
check_balance_continuity4
find_subset_summing_to4
check_payout_window2

Investigation traces

Every step, in the order the agent chose it. Expand a record to see what it did.
pay_000056net_arithmetic_error4 tool calls · 24s
1get_order(order_id=ORD4055)order ORD4055 found
2check_fee_against_rule(txn_id=pay_000056)fee matches the upi rule
3find_related_transactions(order_id=ORD4055)1 row(s) reference ORD4055
4check_settlement_composition(settlement_id=setl_0001)15 members sum to 21272.37, matching the report
ConclusionThe order (ORD4055) confirms gross = 750.00 and the fee rule tool confirms fee = 0 for UPI, yet the net field is recorded as 760.00 — 10.00 more than gross with no deductions. The settlement (setl_0001) is internally consistent across 15 members, so the error is isolated to the net field of pay_000056 itself.
For the analyst. Manually verify the source system that wrote the net field for pay_000056. The net is 10.00 higher than gross with zero fees/GST, which is arithmetically impossible. This may indicate a data-entry error, a stale/corrupted write, or an erroneous credit adjustment not captured as a separate transaction row. Correct the net to 750.00 if no legitimate credit exists, or create a reconciling adjustment row if a real credit of 10.00 was applied.
pay_000042net_arithmetic_error4 tool calls · 22s
1get_order(order_id=ORD4041)order ORD4041 found
2find_related_transactions(order_id=ORD4041)1 row(s) reference ORD4041
3check_fee_against_rule(txn_id=pay_000042)fee matches the upi rule
4check_settlement_composition(settlement_id=setl_0008)14 members sum to 20406.67, matching the report
ConclusionThe order and gateway both confirm gross = 499.00, and check_fee_against_rule confirms fee = 0 is correct for UPI (delta = 0 paise). With fee and GST both at zero, the net must equal 499.00, but the ledger reports net = 509.00 — a surplus of exactly 10.00 that no tool result accounts for. The settlement composition for setl_0008 is internally consistent across its 14 members, so the error is isolated to the net field of this single transaction record.
For the analyst. Manually inspect the ledger write path for pay_000042 to identify where the net field of 509.00 was populated. Check whether a 10.00 adjustment, cashback credit, or incentive was incorrectly booked into the net field rather than as a separate line item. Also verify whether the settlement member entry for pay_000042 within setl_0008 uses 499.00 or 509.00, to determine if the error propagated into the settlement or is confined to the transaction record.
GAP_BEFORE_BNK000014missing_bank_row4 tool calls · 24s
1check_balance_continuity(bank_txn_id=BNK000014)balance gap of 7227.29: a statement line is missing before this row
2search_settlements_by_amount(amount_paise=722729, tolerance_paise=100)1 settlement(s) totalling 7227.29 (+/- 100p)
3check_settlement_composition(settlement_id=setl_0010)9 members sum to 7227.29, matching the report
4check_payout_window(settlement_id=setl_0010, observed_date=2026-08-21)2026-08-21 is inside the plausible window 2026-08-21..2026-08-25
Conclusioncheck_balance_continuity confirmed a gap of 722729 paise (₹7227.29) immediately before BNK000014. search_settlements_by_amount identified settlement setl_0010 for exactly that amount with a payout date of 2026-08-21, which check_payout_window confirmed is within the plausible working-day window. check_settlement_composition verified that setl_0010's 9 member transactions correctly sum to 722729 paise — meaning the settlement is internally sound but its corresponding bank credit row is absent from the statement.
For the analyst. Obtain the full bank statement for 2026-08-21 to 2026-08-25 and locate the credit for ₹7227.29 linked to setl_0010. If the credit exists but was not imported, re-ingest the statement line and map it to setl_0010. If the bank never received the funds, escalate to the payment gateway/treasury team to investigate why setl_0010 was not paid out.
ORD4088fee_mismatch3 tool calls · 16s
1get_order(order_id=ORD4088)order ORD4088 found
2find_related_transactions(order_id=ORD4088)1 row(s) reference ORD4088
3check_fee_against_rule(txn_id=pay_000089)fee 20.00 exceeds the card rule of 15.00 by 5.00
Conclusionget_order confirmed ORD4088 is a paid card transaction for ₹750.00. find_related_transactions returned one captured payment (pay_000089). check_fee_against_rule confirmed the actual fee of ₹20.00 exceeds the card rule fee of ₹15.00 by ₹5.00 (500 paise), which is not rounding noise.
For the analyst. Escalate to the gateway/pricing team to investigate why pay_000089 was charged a fee of ₹20.00 instead of the contracted card rate of ₹15.00. Verify whether the transaction was mis-categorised (e.g., as a premium card or international card tier) or if a rate change was applied incorrectly. Recover the ₹5.00 overcharge if confirmed.
ORD4026missing_payment5 tool calls · 25s
1get_order(order_id=ORD4026)order ORD4026 found
2find_related_transactions(order_id=ORD4026)no gateway rows reference ORD4026
3search_settlements_by_amount(amount_paise=34900, tolerance_paise=100)0 settlement(s) totalling 349.00 (+/- 100p)
4find_subset_summing_to(target_paise=34900, on_date=2026-08-10, window_days=3)1 transaction(s) sum exactly to 349.00
5check_fee_against_rule(txn_id=pay_000115)fee matches the upi rule
ConclusionORD4026 is marked 'paid' in the ledger for ₹349.00 via UPI, but find_related_transactions returned zero gateway rows referencing it. search_settlements_by_amount also found no settlement matching ₹349.00. While find_subset_summing_to identified a UPI transaction pay_000115 of exactly ₹349.00 in the same date window (with a correctly applied zero UPI fee), no tool has confirmed that pay_000115 is linked to ORD4026 — it could belong to a different order entirely.
For the analyst. A human should look up pay_000115 in the gateway and check which order_id (if any) it references. If pay_000115 is genuinely unlinked to any order, it may be the actual payment for ORD4026 that was never mapped — the gateway reference on the transaction should be updated and the reconciliation re-run. If pay_000115 belongs to a different order, ORD4026 has no gateway payment at all and the 'paid' status needs to be audited with the UPI payment provider directly to determine whether the customer was charged.
ORD4034fee_mismatch3 tool calls · 14s
1get_order(order_id=ORD4034)order ORD4034 found
2find_related_transactions(order_id=ORD4034)1 row(s) reference ORD4034
3check_fee_against_rule(txn_id=pay_000035)fee 13.50 exceeds the netbanking rule of 12.00 by 1.50
Conclusionget_order and find_related_transactions confirm ORD4034 is a single captured netbanking payment of ₹349.50 (txn pay_000035, settlement setl_0003). check_fee_against_rule definitively confirmed that the actual fee of ₹13.50 (1350 paise) exceeds the contracted netbanking rule fee of ₹12.00 (1200 paise) by exactly ₹1.50 — this is a genuine overcharge, not rounding noise.
For the analyst. Escalate to the gateway/acquirer with txn pay_000035 and settlement setl_0003 as references. Request a fee credit of ₹1.50 (150 paise). Also check whether other netbanking transactions in the same settlement period (setl_0003) are subject to the same inflated rate, which could indicate a systematic fee rule misconfiguration rather than an isolated incident.
ORD4051fee_mismatch3 tool calls · 16s
1get_order(order_id=ORD4051)order ORD4051 found
2find_related_transactions(order_id=ORD4051)1 row(s) reference ORD4051
3check_fee_against_rule(txn_id=pay_000052)fee 2.25 exceeds the upi rule of 0.00 by 2.25
Conclusionget_order confirmed ORD4051 is a paid UPI transaction for ₹199.00. find_related_transactions identified a single captured payment (pay_000052) settled under setl_0006. check_fee_against_rule confirmed that the UPI fee rule mandates ₹0.00, but ₹2.25 (225 paise) was actually charged — a delta of 225 paise with no ambiguity.
For the analyst. A fee of ₹2.25 was incorrectly applied to UPI transaction pay_000052 (ORD4051), which should be fee-free. Human should verify whether this was a misconfiguration in the fee plan, a gateway error, or if pay_000052 was incorrectly tagged as UPI when it was actually processed through a different (chargeable) method. A refund of the ₹2.25 overcharge to the merchant may be required.
ORD4054missing_payment4 tool calls · 18s
1get_order(order_id=ORD4054)order ORD4054 found
2find_related_transactions(order_id=ORD4054)no gateway rows reference ORD4054
3search_settlements_by_amount(amount_paise=399900, tolerance_paise=500)0 settlement(s) totalling 3999.00 (+/- 500p)
4find_subset_summing_to(target_paise=399900, on_date=2026-08-16, window_days=3)no subset of <= 4 transactions in the 3-day window sums to 3999.00
ConclusionORD4054 is confirmed in the ledger with status 'paid' for ₹3999.00 via UPI, but find_related_transactions returned no gateway rows whatsoever. Additionally, search_settlements_by_amount found no settlement matching this amount (±₹5), and find_subset_summing_to found no combination of transactions in the surrounding 3-day window that accounts for the amount — meaning no gateway or settlement record exists, despite the order being marked paid.
For the analyst. A human should investigate: (1) whether the UPI payment was actually captured at the gateway level (check the UPI PSP/NPCI logs directly for ORD4054 or the customer's VPA/UTR around 2026-08-16T20:42:00); (2) whether the order status was manually or erroneously set to 'paid' without a corresponding gateway confirmation; (3) if a gateway transaction exists under a different order reference, it should be re-linked and the ledger corrected. Until a gateway record is found or the status is corrected, this is an unresolved missing payment.
ORD4089fee_mismatch3 tool calls · 15s
1get_order(order_id=ORD4089)order ORD4089 found
2find_related_transactions(order_id=ORD4089)1 row(s) reference ORD4089
3check_fee_against_rule(txn_id=pay_000090)fee 8.25 exceeds the card rule of 6.00 by 2.25
Conclusionget_order confirmed ORD4089 is a paid card transaction for ₹299.99, linked to a single captured payment pay_000090 in settlement setl_0007. check_fee_against_rule confirmed that the actual fee charged was ₹8.25 (825 paise) against a card rule ceiling of ₹6.00 (600 paise), yielding an excess of ₹2.25 (225 paise) — consistent with the automated tier alert and well above any rounding threshold.
For the analyst. Escalate to the payment gateway or finance team to investigate why pay_000090 was charged at 8.25 instead of the contracted card rate of 6.00. Verify whether the transaction was mis-categorised at the gateway (e.g., routed as a premium/international card tier), and request a fee credit of ₹2.25 if the overcharge is confirmed. Also check setl_0007 to see if other transactions in that settlement batch are affected by the same incorrect fee tier.
ORD4038fee_mismatch3 tool calls · 16s
1get_order(order_id=ORD4038)order ORD4038 found
2find_related_transactions(order_id=ORD4038)1 row(s) reference ORD4038
3check_fee_against_rule(txn_id=pay_000039)fee 17.00 exceeds the netbanking rule of 12.00 by 5.00
Conclusionget_order and find_related_transactions confirm ORD4038 is a captured netbanking payment of ₹899.00 via transaction pay_000039 (settlement setl_0008). check_fee_against_rule definitively confirmed that the actual fee of ₹17.00 exceeds the contracted netbanking rule of ₹12.00 by ₹5.00 — this is a genuine fee overcharge, not rounding drift.
For the analyst. Escalate to the gateway/acquirer for fee reconciliation on txn pay_000039 under settlement setl_0008. Verify whether the netbanking bank tier or surcharge configuration was recently changed, and request a credit note or fee adjustment of ₹5.00 from the payment gateway.
BNK000004orphan_bank_credit5 tool calls · 32s
1search_settlements_by_amount(amount_paise=420000, tolerance_paise=200)0 settlement(s) totalling 4200.00 (+/- 200p)
2find_subset_summing_to(target_paise=420000, on_date=2026-08-13, window_days=3, max_terms=5)5 transaction(s) sum exactly to 4200.00
3check_balance_continuity(bank_txn_id=BNK000004)balance is continuous
4get_order(order_id=RZP879978972)no such order RZP879978972
5find_related_transactions(order_id=pay_000120)no gateway rows reference pay_000120
Conclusionsearch_settlements_by_amount returned zero matches for ₹4200.00 (±₹2), so no registered settlement corresponds to this bank credit. The description reference 'RZP879978972' does not resolve to any known order. find_subset_summing_to identified 5 transactions (pay_000120, pay_000032, pay_000064, pay_000060, pay_000054) that sum exactly to ₹4200.00, but find_related_transactions returned no gateway rows for pay_000120, suggesting these are not a formally settled batch — the grouping is not confirmed by the ledger. Balance continuity is intact, confirming the bank row itself is real and not a dup
For the analyst. A human should: (1) look up each of the 5 candidate transactions (pay_000032, pay_000064, pay_000060, pay_000054) in the gateway and ledger to confirm whether they share a settlement ID; (2) contact Razorpay with UTR / reference 'RZP879978972' to obtain the settlement advice for this ACH credit; (3) if Razorpay confirms a settlement, record it in the ledger and re-run reconciliation; (4) if no settlement advice is found, escalate for potential mis-directed or unreported payout.
BNK000006orphan_bank_credit5 tool calls · 21s
1search_settlements_by_amount(amount_paise=275000, tolerance_paise=500)0 settlement(s) totalling 2750.00 (+/- 500p)
2find_subset_summing_to(target_paise=275000, on_date=2026-08-16, window_days=3)3 transaction(s) sum exactly to 2750.00
3check_balance_continuity(bank_txn_id=BNK000006)balance is continuous
4find_related_transactions(order_id=pay_000060)no gateway rows reference pay_000060
5check_settlement_composition(settlement_id=pay_000068)no such settlement pay_000068
Conclusionsearch_settlements_by_amount returned 0 matches for ₹2750.00 (±₹5.00), confirming no settlement record corresponds to this bank credit. check_balance_continuity confirmed the bank row BNK000006 is genuine (gap_paise = 0, no missing statement line). find_subset_summing_to identified three transactions (pay_000060, pay_000068, pay_000079 summing exactly to ₹2750.00) that appear to have been grouped and paid out together, but no settlement entity exists in the ledger to link them — the credit arrived in the bank without a corresponding settlement record.
For the analyst. A human should: (1) Check with Razorpay whether a settlement was created for UTR RZP813326083 on 2026-08-16 that was never posted to the merchant ledger. (2) Confirm that pay_000060, pay_000068, and pay_000079 are all in a 'captured/settled' state and have no settlement_id assigned. (3) If Razorpay confirms the payout, raise a ledger correction to create the missing settlement record linking these three transactions to UTR RZP813326083.
setl_0010missing_bank_rowdisagreed4 tool calls · 16s
The agent disagreed with the matcher. The deterministic engine classified this record settlement_not_in_bank; after its own investigation the agent concluded missing_bank_row. Both are recorded. Neither overrides the other -- the agent investigates independently and is not shown the engine's verdict as a fact.
1check_settlement_composition(settlement_id=setl_0010)9 members sum to 7227.29, matching the report
2check_payout_window(settlement_id=setl_0010, observed_date=2026-08-21)2026-08-21 is inside the plausible window 2026-08-21..2026-08-25
3search_settlements_by_amount(amount_paise=722729, tolerance_paise=100)1 settlement(s) totalling 7227.29 (+/- 100p)
4check_balance_continuity(bank_txn_id=RZP366888337)no such row RZP366888337
Conclusioncheck_settlement_composition confirmed that setl_0010's 9 member payments correctly sum to ₹7,227.29 with no internal arithmetic error. check_payout_window confirmed 2026-08-21 is a valid payout date. However, check_balance_continuity found no bank statement row matching UTR RZP366888337, meaning the expected bank credit of ₹7,227.29 has no counterpart in the bank feed.
For the analyst. Escalate to the banking/treasury team with UTR RZP366888337 and payout date 2026-08-21. Request confirmation from the bank whether the credit was actually remitted and, if so, obtain the correct statement row (the UTR may have been mis-reported or the bank file import may be incomplete for that date). If the payment was never remitted, initiate a payout query with the payment gateway.

Settlement Q&A

Plain-English questions about the batch. The model translates the question into a structured query and explains the result; it does not compute the figures. Every number below came from the query named beneath each answer.
How did the reconciliation go overall?reconciliation_summary
The reconciliation processed 141 entities in total, of which 128 were resolved, giving a resolution rate of 90.8%. Of the resolved records, 97 were classified as clean, while the remaining resolved records fell into categories such as refund (6), failed payment (5), fee mismatch (5), unsettled (6), partial refund (4), rounding noise (4), chargeback (3), duplicate (3), missing payment (2), net arithmetic error (2), orphan bank credit (2), settlement not in bank (1), and missing bank row (1). Confidence-wise, the vast majority of records, 124, landed in Tier 1 (high confidence), with just 4 in Tier 2. Overall, the reconciliation went quite well, with a strong resolution rate and most records coming in at the highest confidence level.
reconciliation_summarythe query this answer rests on
How much did I pay in fees, and which payment method costs me most?fee_summary
Across all 107 payments in this batch, you paid a total of INR 1770.20 in Merchant Discount Rate (MDR) fees and INR 1770.00 in chargeback penalties as separate charges. Looking at MDR alone, card is your most expensive method in absolute terms at INR 1356.94 (effective rate 2.37%), followed by wallet at INR 319.53 (2.12%), netbanking at INR 91.46 (2.82%), and UPI at just INR 2.27 (effectively 0.00%). However, if you consider the effective rate rather than the absolute amount, netbanking is actually the costliest at 2.82%, though it processes far fewer transactions than card.
fee_summarythe query this answer rests on
What could the system not resolve, and how much money is involved?exception_summary, unsettled_value
The system flagged 13 records across six classifications that it could not resolve. There are 5 fee mismatches where the charged fee exceeded the expected fee (deltas ranging from INR 1.50 to INR 5.00 across card, netbanking, and UPI transactions), 2 net arithmetic errors where the gross minus fees does not equal the stated net (for pay_000056 and pay_000042), 2 missing payments where orders exist in the ledger but have no corresponding gateway record (ORD4026 and ORD4054), 2 orphan bank credits with no matching settlement (INR 4200.00 on 2026-08-13 and INR 2750.00 on 2026-08-16), 1 missing bank row representing a balance gap of INR 7227.29 before BNK000014, and 1 settlement not found in the bank statement (setl_0010, a payout of INR 7227.29 due 2026-08-21). Separately, there is INR 3264.48 across 6 captured transactions that has not yet been paid out, though the system notes this is expected and not considered an error.
exception_summary, unsettled_valuethe query this answer rests on
How much value is captured but not yet paid out?unsettled_value
There are 6 transactions that have been captured but not yet paid out, with a total unsettled value of INR 3264.48. As noted in the data, this is expected and is not an error.
unsettled_valuethe query this answer rests on
Did I lose anything to refunds or chargebacks?refund_summary
Yes, there were losses to both refunds and chargebacks in this batch. There were 13 total incidents — 10 refunds and 3 chargebacks — with a combined total value of INR 23446.49 returned to customers. On top of that, the 3 chargebacks attracted penalty fees of INR 1770.00, so the chargeback penalties are an additional cost beyond the reversed transaction amounts themselves.
refund_summarythe query this answer rests on
A weaker guarantee than the resolution agent. Every figure here came from a query result, but the rule against combining figures lives in the prompt rather than in code. On one run the model added two results together and reported the sum -- correctly, which is worse than incorrectly, because a right answer produced by a forbidden route looks identical to a grounded one. The resolution agent's constraints are enforced in code and tested without a model; these are not.