Skip to content

Cash & treasury

Cash is the only balance sheet account with an independent third party asserting what it should be. That makes it both the most verifiable account and the one where a break matters most.


1. Balances are plural

A single "cash balance" is almost always wrong. There are at least four, and they differ.

Balance Meaning Source
Book (GL) What we've recorded GL
Bank current What the bank has posted Bank feed
Bank available Posted, minus holds, plus same-day credit Bank feed
Projected Available, minus scheduled payments, plus expected receipts Derived

UI rules:

  • BalanceCard shows available as the figure and current as a secondary line when they differ. Conflating them is the most consequential copy error in banking UI.
  • The ledger balance and the bank balance differ legitimately — deposits in transit, outstanding checks. That difference is the reconciliation, not an error.
  • Projected balance is a forecast and is rendered as such — dashed on charts, labeled, with the assumptions reachable.
  • Every balance carries its "as of" and its source. A cached bank balance shown as current is the most dangerous state in the product; StaleIndicator exists for it.

2. Transaction states

pending → posted → reconciled
   │         │
   │         └─ settled on the bank's books; reaches the GL once coded or matched
   └─ visible on the feed, may still change amount or vanish entirely

A pending card authorization is not a transaction. It can settle for a different amount (tips, fuel, hotels) or disappear. UI rules:

  • Pending transactions render at opacity: 0.6 with a --warning left border, and are excluded from the ledger balance.
  • When a pending transaction settles at a different amount, the change is shown, not silently overwritten.
  • Never reconcile a pending transaction.

3. Bank reconciliation

The full model is in periods & close. What matters at the component level:

Matching ladder

  1. Exact — amount, date, and reference all agree. Auto-matched, no review.
  2. Near — amount agrees, date within tolerance. Auto-suggested, one-click accept.
  3. Rule-based — a saved rule (this description pattern → this account). Suggested with the rule named.
  4. Many-to-one — a bank deposit covering several invoices, or one payment covering several bills. Common, and the case most tools handle worst.
  5. One-to-many — one book entry split across several bank lines.
  6. Unmatched — the actual exception.

UI rules:

  • Confidence is shown with its basis, not as a bare percentage. "Matched on amount and reference" is actionable; "94%" is not.
  • Many-to-one selection shows a running sum against the target, so the user can see when the selection is exact.
  • Auto-matched items are reviewable and reversible. An automation you cannot inspect is an automation you cannot trust at audit.
  • The difference is always on screen. It is the number being driven to zero.
  • The match animation is one of the four sanctioned delight moments — see motion catalog.

Categorization rules

type CategorizationRule = {
  conditions: { field: "description" | "amount" | "counterparty" | "account"; op: Op; value: string }[];
  actions: { account: string; dimensions?: Dimensions; memo?: string };
  autoPost: boolean;               // suggest vs. post automatically
  priority: number;
};
  • Rule creation happens inline from a transaction — categorize one, offer to categorize the other 40 like it. The highest-leverage interaction in bookkeeping.
  • Preview the match count before applying. "This rule matches 47 existing transactions."
  • autoPost is off by default. A rule that posts to the GL without review is a control decision, and it should be a deliberate one.

4. Cash forecasting

  Opening available balance                      412,880
  Add: expected receipts (AR due, by date)       184,200
  Less: scheduled payments (AP due + payroll)   (241,600)
  Less: committed (approved POs to invoice)      (48,000)
  ─────────────────────────────────────────────────────
  Projected closing balance                      307,480

UI rules:

  • Certainty tiers are visually distinct. Contracted (scheduled payments), expected (AR by due date, with a collection-probability haircut), and forecast (modelled) are three different qualities of number and must not render identically.
  • Show the minimum balance in the horizon, not just the endpoint. A forecast ending at $300k that dips to −$40k in week three is the important fact, and an endpoint-only view hides it.
  • Payroll is a separate, prominent line. It is the payment that cannot be delayed.
  • Scenario comparison (base / downside / upside) uses distinct line styles as well as color, never color alone.

5. Multi-account treasury

  • Sweeps and internal transfers are not income or expense. They net to zero at the group level and must be eliminated from any cash-flow presentation. A dashboard that counts an internal transfer as a receipt is double-counting.
  • InternalTransferMatch pairs the two sides of a transfer and marks both as eliminated.
  • Restricted cash is disclosed separately and excluded from available cash. It is on the balance sheet but it is not spendable.
  • Concentration risk: cash by institution against insured limits (FDIC $250,000 per depositor, per insured bank, per ownership category — sweep and reciprocal-deposit networks can extend it). CashConcentration renders exposure by bank with the limit line.

6. Payment rails

Different rails have different timing, reversibility, and cost, and the UI must state all three at the moment of choosing.

Rail Settlement Reversible? Cutoff
ACH Next or second business day; Same Day ACH up to $1M per payment Limited — returns and reversals within Nacha windows (generally 2 banking days; 60 days for unauthorized consumer debits) Three Same Day ACH windows; the last closes at 4:45 p.m. ET
Wire (domestic) Same day No Bank-specific, typically mid-afternoon
Wire (international) 1–5 days No Plus correspondent-bank delays
RTP / FedNow Seconds No 24/7
Check 5–10 days + float Stop-payment possible Mail
Card 1–3 days Chargeback window

UI rules:

  • Irreversible rails get HoldToConfirm. Wires, RTP, FedNow.
  • The cutoff is shown as a live countdown where it matters. "Submit within 2h 14m for same-day settlement."
  • Business days, not calendar days. Weekends and bank holidays are respected in every arrival estimate, and the holiday calendar is per-country.
  • The arrival estimate is always shown before confirming, and it's the sentence users read most: "Arrives Tue 8 Sep".

7. Cash component set

Component Purpose
BalanceCard Available as the figure, current as the secondary line, with source and as-of
AccountCard Per-account, with connection health — connected / stale / reauth-required, prominent
TransactionTable Pending and posted, with settlement changes visible
ReconciliationView The two-pane matcher; suggestions carry their confidence basis, not a bare score
CategoryPicker Rule creation inline from a transaction, with match-count preview
CashRequirements Due in 7/14/30 vs. available
CashForecast* Certainty-tiered, showing the minimum in the horizon
InternalTransferMatch* Pairs and eliminates both sides
CashConcentration* Exposure by institution against insured limits
PaymentRailSelector* Timing, reversibility, and cost at the point of choice

* Specified here, not yet in the catalog.

Built against this document

The surfaces that implement what this argues — running, computing, or shaped by it.

Told when this spec changes

The docs are the contract the components are built against. When one changes, the component changes with it — and the copy in your repo does not. One email when that happens.

One address, no list rental, unsubscribe in one click.

Works in your QuickBooks Online or Xero file

Get your books closed every month

Lopifi is building AI bookkeeping that keeps your books closed on US GAAP as transactions happen, with a CPA review every quarter, for $200 a month. We’re not open yet.

$200/month when we open. No card now.