Reconcile money in

Read the worklist, confirm the deposits whose candidates are clear, decide the rest. A deposit with an invoice candidate is matched with match_bank_credit_to_invoice, which records the payment on the bank's real value date and learns the payer's bank alias. A deposit that is not invoice income (interest, a marketplace payout, an old-system payment) is triaged into a reporting category instead, never matched. A match is reversible with unmatch_reconciliation.

Step 1: read the worklist

"What deposits are waiting?"

triage_bank_feed in worklist mode returns every untriaged line. For each deposit it carries candidates: the outstanding invoices it could be paying, ranked with a confidence score, a band of auto_suggest or needs_review, the evidence for the match in reasons, and any cautions in a separate warnings list. Read the candidates before you do anything else. A deposit with candidates should be matched to an invoice, not filed into a category, even when a payer rule has proposed one.

What counts as evidence, strongest first:

  1. The invoice number printed in the bank text. It outranks everything and surfaces the invoice even when the amount differs (a part payment, a fee deduction, a split).
  2. An exact amount against an outstanding invoice.
  3. A known payer. Both the client's legal and trading names are matched, because banks print the account holder's legal name, plus any bank alias learned from a previous match.
  4. A plausible date relative to the invoice.

A caution is never a point in a match's favour. already_paid means that invoice is settled and is only offered because the bank text names it; amount_mismatch means the amounts differ. A candidate with any warning is never auto-suggested.

Step 2: confirm the clear ones

"Match the high-confidence ones."

For each deposit whose top candidate is auto_suggest, match_bank_credit_to_invoice does four things: records the customer payment against the invoice on the bank's real value date through the audited payment gateway, marks the deposit reconciled and linked to that payment, transitions the invoice to paid or partially paid, and learns the client's bank alias so this payer is recognised next time. On screen, "Confirm high-confidence matches" does the same in bulk, gated by finance.reconcile.bulk_confirm_min_score_pct (default 95).

The payment is keyed to the deposit, so the same deposit can never pay twice; a second attempt is refused with already_matched rather than minting a duplicate that would become a spurious client credit.

Step 3: decide the rest

For deposits with no candidate, or a candidate you reject, the deposit is one of:

  • Invoice income the ranker could not see. Name the invoice yourself and match it.
  • A payment you already recorded (cash taken on site, an EFT keyed in by hand). link_bank_credit_to_existing_payment links the deposit to that payment without creating new money.
  • Not invoice income. Interest, a marketplace payout, a refund from a supplier, a payment for work invoiced in your previous system. Triage it into a reporting category with triage_bank_feed in decide mode (or triage_bank_transaction for one line). A category's treatment decides whether it reaches the P&L as income or is excluded. Never match a non-invoice deposit to an invoice to tidy the list; it would misstate income.
  • Your own money arriving from another account. Pair it as a transfer; see envelopes.
  • A cash or non-invoice receipt you want booked as a receipt anyway. "Record as a cash receipt" on the Reconcile screen books it against the client named in finance.reconcile.cash_receipt_client_id.

When a decision applies to every future line from the same payer, add create_rule to the decision. create_bank_payer_rule remembers the description substring and the category, and apply_bank_payer_rules runs after each import. A rule never auto-triages a line whose amount equals an outstanding invoice total; that line is offered for matching instead.

Step 4: check the story

"Show me everything that looks like it came from that childcare client."

get_client_money_story resolves the client by name, sweeps the feed's credits for deposits that look like theirs (legal and trading names, site contact names, any aliases), and lays them beside the client's invoices and recorded payments. It is the read for "did they pay, and when?".

Reversing a match

unmatch_reconciliation voids the payment the match created, which unwinds its allocation and recomputes the invoice off paid, then frees the deposit back to the worklist. Nothing is deleted; the audit log keeps both acts.

Related

Last updated 2026-09-18