Skip to main content

Reconcile Client Payment

What it is

Where a receipt from a client is turned into allocations against their outstanding invoices. Two ways to do it:

  • Auto-FIFO — the default. The amount settles the oldest outstanding invoice first, then the next, until it runs out.
  • Manual Selection — you pick the invoices and type the amount against each.

Either way you preview first and confirm second, and the confirm goes through reconcile_payment_atomic, which locks the rows so two people reconciling at once cannot double-apply the same invoice.

Who can open it

Needs the finance.payments feature grant while FEATURE_GRANULAR_RBAC is on; the owner bypasses it. With the flag off, any signed-in account can reach it by URL.

Before you start

danger
Every figure on this screen is printed with a $, whatever the client's currency

The screen loads clients as id, name only — it never reads clients.currency — and every amount is rendered with a hardcoded dollar sign: the preview totals, the per-invoice Outstanding, Applying and After columns, the manual Allocated / Remaining / Over-by banners, and the success summary.

An INR client's ₹250,000 receipt reads "$250,000.00" here. The number is right and the symbol is wrong. The allocation itself is unaffected — nothing is converted, the figures are the invoice's own — but do not read the symbol, and do not paste these lines into anything a client will see.

The client list is every client in the database, not just the entity you have selected in the header. Two companies with similar names are easy to confuse, and there is nothing on the row to tell them apart. Check the invoices in the preview before confirming.

Status decides whether the money has landed. Received (Confirm in Bank) treats the receipt as settled. Wired (In Transit) records it as on its way; it then appears on Wired Payments until someone confirms or rejects it. Pick this deliberately — marking a wire as Received credits invoices for money you do not yet have.

Preview does not write anything. You can preview as often as you like.

Every control on the page

ControlWhat it does
Manual Selection (override auto-FIFO)Tick to choose invoices yourself. Ticking or unticking clears the current preview and any amounts you had typed
Client *Every client, alphabetically. Changing it clears the preview
Total Amount ReceivedRequired in auto mode. In manual mode it is optional and the label says so — leave it blank and the total becomes the sum of what you allocate
Payment Date *Defaults to today
Reference / UTRFree text, "Bank ref or UTR"
Status *Received (Confirm in Bank) or Wired (In Transit)
NotesFree text
🔍 Preview AllocationAuto mode: shows what FIFO would do. Disabled until a client and an amount are entered
🔍 Show Outstanding InvoicesThe same button in manual mode: lists the client's outstanding invoices with a box against each
Apply FullOn each manual row: fills that box with the invoice's whole outstanding amount
✅ Confirm & ApplyAppears only after a preview. Writes the payment

The manual banner does the arithmetic as you type — Total, Allocated, and either Remaining or Over by. Over-allocating turns it red and blocks Confirm & Apply with "Over-allocated by … — reduce amounts before confirming." Under-allocating is allowed and warns that the difference will remain unallocated.

Confirm & Apply is blocked while a manual run has nothing allocated, or is over-allocated.

What it writes

POST /api/payments/reconcile with preview: false, which calls reconcile_payment_atomic. That writes the payment and updates every invoice it touches in one locked transaction, so a concurrent reconciliation cannot apply the same invoice twice.

Afterwards the screen shows Payment Reconciled, the amount applied, how many invoices it touched, any unallocated remainder, and a per-invoice breakdown marking each ✓ Paid or showing what is left.

⚠️ There is no undo on this screen. Correcting a mis-applied receipt means going to the invoices or issuing a credit note, not re-running this.

⚠️ An unallocated remainder is recorded, not refused. If you enter more than the client owes, the excess is kept against the payment as unallocated rather than blocking the save. Check the Unallocated figure on the preview before confirming.

When it goes wrong

"Select a client." No client chosen.

"Enter the amount received." Auto mode with an empty or zero amount. In manual mode the amount is optional — allocate against invoices instead.

"Enter at least one allocation amount." Manual mode with every box empty or zero.

"Over-allocated by …" The boxes add up to more than the total you entered. Either reduce them or raise the total.

The preview lists no invoices. That client has nothing outstanding. Check you picked the right one — the list spans every entity.

The figures show $ and the client bills in something else. Expected — see the warning above. The amounts are correct; the symbol is not.