SIGNALS Documentation
API Reference

Payments

Payment record page — one signed amount against one invoice, with optional persisted settlement and allocation identity.

Overview

A payment row is one recorded amount against one invoice. It is not the whole provider receipt: verified provider settlements and their invoice allocations are stored separately, and a receipt can retain unapplied surplus. A payment row may name its persisted allocation and settlement; a manual or unlinked historical row does not receive an invented settlement. Refund rows carry a negative amount (isRefund()). Verified chargebacks also have negative amounts, but use the distinct verified_chargeback origin and are not refunds. The sign alone does not prove a provider refund has been initiated or confirmed.

The read API keeps the existing payment fields and adds currency_code, base_currency_code, invoice_aggregate_version, reference_origin, settlement_id and allocation_id. The amount uses the owning invoice's currency exponent, including JPY (zero decimals) and KWD (three decimals). The version belongs to the invoice, not the payment; it is not an idempotency key. Settlement/allocation IDs are null when no persisted link exists. These IDs do not include another invoice's allocations or provider payloads. paid_at is the effective date of this payment row, not the time when the entire invoice became paid.

List payments at /payments. The first-ever record page is /payments/{invoicePayment}. Record new payments from the invoice, not from this page. See also Invoicing & Payments and the Payments API.

Receipt, allocation and payment boundaries

Record What it establishes
Settlement Preserved verified provider receipt identity and gross amount, separate from invoice projections.
Allocation The amount of that receipt applied to a permitted invoice; any remaining receipt balance stays unapplied.
Invoice payment One signed amount against one invoice. It can name a persisted settlement/allocation or an admitted original payment for a refund.

An operator-recorded refund returns admitted original funding; a negative row does not confirm a provider refund. Write-offs and their reversals are separate non-cash receivable adjustments, not payment rows or effective credit notes. Receipt-date cash conversion and the invoice's frozen base carrying amount are separate evidence; do not use a current rate to reconstruct historical money or total different currencies together.

Provider receipts with unresolved conversion can retain a durable exception without a guessed posting. Legacy or conflicting original funding/posting evidence can prevent a refund or allocation. Pending Connect enumeration, duplicate-delivery and reconciliation repairs remain outside this documentation's acceptance claim.

Reversing an allocation restores its original transaction and base cash amounts. Reusing that restored cash on another permitted issued invoice keeps the receipt, reversal and preceding allocation identities. Successive allocations consume the captured restored basis with cumulative HALF_UP rounding and assign the final base residue to the last allocation; current exchange rates do not replace that basis. This creates another allocation and invoice payment, without recording another receipt or changing the original invoice. An original-funded operator refund does not replenish unapplied receipt cash. Later allocations verify the refund’s ordered original funding and recorded payment, then continue consuming the same captured basis and final residue.

Invoice projection rehearsal retains the immutable allocation, payment and posting dependencies of the same carrying settlement across invoices. It reconstructs the selected invoice's posting from its recorded source and refuses missing or contradictory components. Each restored-cash allocation and every preceding allocation must retain its own provider payment with the original invoice, exact minor amount, provider reference and reference origin. The allocation must also retain its recorded receipt, invoice, payment, base currency, amount, operator key, actor, reason and timestamp. A retained pre-reversal allocation has the same requirement as an earlier restored-cash allocation. Safe payment notes and effective-date corrections do not replace these financial identities. Qualified frozen replay and metadata repair do not establish a complete rebuild with all settlement projections absent, concurrent allocation ordering, provider refund outcomes or legal debit adjustment support.

Keep the integer minor amount with its named transaction currency and exponent: 100 JPY minor units means JPY 100, while 100 KWD minor units means KWD 0.100. Base amounts need their own named currency and stored conversion evidence. A manual or legacy unlinked row has no invented settlement, allocation or historical base denomination. Retrying a captured command returns its retained identity and outcome; it does not establish that the settlement's entire gross amount has been allocated.

Customer document descriptions

New receipt and invoice output reads payment and refund references, dates, methods and notes from the retained recorded-payment or confirmed-refund source. Recorded payment-metadata corrections then update the reference, notes and date in event order; raw edits to the projection remain ignored. Provider receipt descriptions retain the immutable allocation and settlement identity. Operator-recorded returns and confirmed provider refunds are labelled separately.

Invoice documents list write-offs and linked reversals as non-cash adjustments, with their recorded reason and effective date. A legacy payment without a unique retained source is labelled “Payment attribution unknown”; its existing display fields do not establish provider attribution. Previously saved document snapshots keep their captured data.

Settlement cash conservation

Allocation requires the original settlement and invoice to have the same account and exactly matching captured transaction and base currency codes. A merged account alias does not transfer the original cash debtor to its canonical successor. Missing, differently cased or conflicting currency evidence is refused; cross-currency application requires explicit realised-FX, currency-leg and residual-rounding rules. Changing today's base currency or exchange rate cannot supply those missing historical facts.

Let G be the original verified receipt, A its effective allocated principal, and R the cash returned from those allocations by admitted refunds or verified chargebacks. All three use integer minor units in the original transaction currency. The retained partition is G − R = (A − R) + (G − A): net cash equals funded applied cash plus original unapplied cash. A cash return does not replenish the original unapplied balance. Combined refunds and chargebacks cannot exceed the remaining original funded principal. A valid allocation reversal can release unreturned allocation principal; it cannot release cash already returned by either family.

The internal staff command records a verified chargeback only against one original verified provider allocation and its retained payment/posting evidence. It requires an authorised actor, explicit original currencies, a verification reference, reason and command key. Its immutable receipt captures the original cash, receivable and paid-base amounts separately; partial returns use cumulative rounding against each original basis, so a final return consumes the exact retained remainder without a current rate lookup. There is no chargeback REST or MCP endpoint, and this command neither initiates a provider debit nor interprets a chargeback-shaped webhook as a payment or refund.

REST and MCP allocation refusals preserve their existing authorisation and warehouse boundaries. An unsupported currency application returns HTTP 422 with settlement_allocation_currency_unsupported; a different or missing original debtor returns settlement_allocation_account_mismatch. An identical completed allocation command key is inert; a changed request returns settlement_allocation_idempotency_conflict. These refusals do not create a payment, allocation or posting. Historical conflicting funding requires explicit reconciliation rather than relabelling old cash or inventing conversion evidence.

A distinct pending chargeback records its provider dispute identity, selected original settlement/allocation and authorised actor without changing cash or reserving principal. Confirmation must match that pending source's invoice, original payment, amount and currencies; a second confirmation refuses, while an identical command retry is inert. Confirmed refunds and chargebacks share the original principal limit, including outstanding provider-refund reservations. Pending and confirmed facts fold from their recorded sources without consulting current prices or rates.

A verified provider win uses a separate internal restoration event against one confirmed chargeback. It exactly reverses that loss posting, including each original cash, receivable, FX and rounding leg, and records a positive chargeback_restored payment. It does not create a receipt, allocation or a refund. The confirmed loss and original settlement/allocation remain immutable; identical win retries are inert, conflicting wins refuse. Restored cash does not renew the original refund/chargeback principal limit.

With W as cash restored by verified wins, the retained partition becomes G − R + W = (A − R + W) + (G − A). Return capacity remains bounded by A − R, separately from net retained cash. Pending, confirmed and restored outcomes replay from captured original facts without current rate lookup. These staff commands neither contact a provider nor interpret unauthenticated outcomes.

Payments list

Route: /payments

Finance data table with columns Reference, Invoice, Account, Method, Paid date, Amount, and Type. Refunds carry a Refund badge. Reference and View open the record page; Edit opens the existing form.

Payment detail

Route: /payments/{invoicePayment}

Permission: invoices.view.

The page uses the shared document-brief chassis: identity band (number/reference, method, Favouritable star), a tab strip at the top and bottom, headline cards that drill into registers, four briefing verdicts, and an aside for Totals / Counterparty / Related documents.

There is no lines tab and no files tab.

Overview

Route: /payments/{invoicePayment}

  • Headlines — Reconciliation (One amount against one invoice / Refund against one invoice), Allocation (1 allocation · no unallocated balance), Lifecycle.
  • Reconciliation — recorded amount vs the invoice. Implied outstanding-before is shown only when this is the invoice's only or latest payment; otherwise the cell is Not derivable.
  • Allocation — the single invoice link represented by this row. The page's existing copy describes the row, not the whole settlement; it must not be used to infer that the receipt has no unapplied surplus.
  • Briefing — four graded verdicts. Future commitments are real dates only.
  • Aside — totals, counterparty, related invoice. Cost keys are omitted (not zeroed) without costs.view.

Unknown ?register= keys are ignored. Allowed keys: recon, alloc, life.

Allocations

Route: /payments/{invoicePayment}/allocations

The existing register shows this payment's invoice link. It is not a settlement-wide remittance or surplus-management view.

Documents and activities

Tab Route
Documents /payments/{invoicePayment}/documents
Activities /payments/{invoicePayment}/activities

Activities use the commitments spine (all / financial / comms). Audit rows are gated on action-log.view.

Plugin tabs

Plugins register extra tabs on payment.detail.tabs. Authorised tabs open /payments/{invoicePayment}/tabs/{key} (payments.plugin-tab), gated on invoices.view.

Refunds

A refund is this same payment record with amount < 0, excluding the distinct verified_chargeback origin. Refund identity and headlines use Refund; there is no separate refund document type on this page. A verified chargeback records a separate, evidenced cash return against its original funded payment.

An operator-recorded refund can name an admitted provider carrying allocation as its original funded payment. Partial returns share that original principal limit; the final return consumes only its remaining capacity. The recorded return preserves the receipt and allocation history and does not replenish unapplied settlement cash. It remains an operator attestation, separate from provider refund initiation or confirmation.

Signed provider refund snapshots

Drivers may implement ProviderRefundWebhookDriver::verifyRefundWebhook() to decode authenticated refund outcomes separately from checkout completions. Stripe verifies the raw body against the configured signing secret and retains the event, merchant, mode, refund and original PaymentIntent identities, exact minor amount, currency, original creation time and literal outcome status. Pending and requires_action remain distinct from succeeded, failed and canceled.

The webhook retains each authenticated refund delivery in an append-only inbox, scoped by provider, merchant, live mode and event ID. Exact redelivery returns refund_duplicate without another write; a different payload under that identity returns HTTP 409 and preserves the original. Out-of-order statuses are separate observations, without overwriting a newer outcome. Checkout-only drivers retain their existing behavior.

The immutable snapshot contains no local invoice/allocation authority from provider metadata. Recording it returns refund_recorded, which means delivery capture only. It creates no invoice payment, reservation, subledger posting or financial event. A provider succeeded observation alone does not confirm local cash; the separate local confirmation command requires the original outstanding reservation.

The internal funding-basis reader accepts an explicitly selected local allocation and verifies its original payment, posting and receipt. It retains cash, receivable and paid-base components separately with their captured currency units; later rates and company currency settings do not replace those amounts. Matching a delivery to that basis checks the original provider, merchant, mode, receipt, currency and exact requested amount. This read-only check grants no refundable capacity and performs no reservation or confirmation.

An authorized internal initiation command can link an already known provider refund ID to that explicit allocation and reserve its original principal. It sends no refund request to the provider and exposes no new API route. Its idempotent source shares remaining principal with operator-recorded refunds and prevents the same allocation from being released into unapplied cash while reserved. An exact authenticated failed or canceled observation releases that reservation once through a separate failure source. A verified success prevents failure release and requires confirmation or reconciliation. Initiation and failure leave payments, cash and subledger rows unchanged; their recorded sources rebuild the same reservation state without emitting financial events. A separate read-only confirmation admission requires a persisted authenticated success for that exact outstanding reservation and its unchanged original funding. Pending, failed, substituted or already released evidence is refused. Admission itself creates no confirmation source, payment or posting.

The prospective return calculator keeps the original cash, receivable and paid-base amounts separate. Each partial amount is the difference between cumulative HALF_UP targets; the final return consumes the exact remaining component, including zero-base and large integer amounts. It uses captured units and amounts without reading a current rate or currency catalogue. This pure calculation does not establish prior-return provenance, authorize a confirmation or write cash.

The internal confirmation command now records a distinct authenticated-success source and negative provider-owned payment under the original account, settlement, invoice and payment locks. It consumes the reservation, credits provider clearing and restores receivables using separate original cash, receivable and paid-base components. Earlier operator and provider returns share the same principal and ordered original-basis prefix; retries of the same confirmation are read-only. Its captured aggregate outcome folds without live lookups or financial event emission. The posting policy retains the same source and original-basis checks in PostgreSQL. Financial rebuild reconstructs failed and confirmed lifecycle outcomes and exact payment, allocation and posting rows from retained sources, without current money facts or new financial events. The internal command consumes an authenticated completed provider refund; it does not submit an external refund request. Legal debit adjustments use the separate explicit correction link described below.

Deposit and pro-forma worked examples

The approved deposit policy is a non-posting payment request: cash stays unapplied until allocation to the final posting invoice. A pro-forma is also non-posting and must be linked to its later posting invoice. These choices were confirmed by the product and finance owner on 4 October 2026; approval does not mean the complete conversion and settlement workflow is available in this beta.

The examples use GBP with two decimal places, a rental net charge of £1,000.00, an illustrative frozen tax rate of 20%, and a final gross invoice of £1,200.00. They assume no earlier standard invoice, write-off or foreign-currency conversion. The rate is an example, not a rule for every customer or jurisdiction. The approved default tax point is invoice issue unless the jurisdiction's policy requires an earlier supply date.

Deposit request, cash and the final invoice

A 25% request in this example asks for £300.00. Under the approved policy, the request creates no receivable, turnover or tax posting. Receiving £300.00 records cash once and leaves £300.00 unapplied; it does not make the rental paid or reduce the eventual invoice's gross value.

Step under the approved policy Final invoice gross Net cash allocated to it Outstanding Unapplied receipt
£300.00 received before the final invoice No invoice yet £0.00 No invoice receivable yet £300.00
Standard invoice issued £1,200.00 £0.00 £1,200.00 £300.00
Existing receipt allocated once £1,200.00 £300.00 £900.00 £0.00

Allocation must retain the original receipt and its permitted customer/currency identity. It moves unapplied funds to receivables; it must not record a second receipt, another £300.00 of turnover, or a second tax charge. A later invoice payment row represents that allocation, rather than the whole receipt.

Current beta boundary: new deposit requests are non-posting. Their displayed net/tax/gross amounts do not consume rental quantities or create receivable, revenue or tax postings on issue. Direct invoice payments are refused. The internal verified-receipt ledger can retain independently received cash as unapplied funds; an authorized operator can allocate that existing receipt once to an issued standard invoice through the settlement-allocation action. Standard generation retains the full rental value rather than subtracting the request. This is an explicit allocation workflow, not an automatic deposit offset or a deposit checkout. Historical deposit rows and missing captured facts are not rewritten by this policy.

The portal's optional part-payment button is separate from generating a deposit document: on a payable standard invoice, it asks for a configured portion of that invoice's current outstanding balance. A 25% button on an unpaid £1,200.00 standard invoice requests £300.00 against that invoice.

Tax snapshots and credits

The current deposit calculator has two document calculation settings. With the example's 25% net amount, Proportional displays £250.00 net + £50.00 tax = £300.00; Full tax up-front displays £250.00 net + the rental's full £200.00 tax = £450.00. These are existing calculation modes, not authorization to treat a non-posting payment request as a second tax invoice. The fixed-gross input derives net using the rental's net-to-gross ratio; with Full tax up-front, the resulting total need not equal the requested fixed gross.

For mixed tax groups, the original groups and pennies stay distinct. For example, £800.00 at 20% plus £200.00 zero-rated gives £160.00 tax: a proportional 25% deposit displays £250.00 net + £40.00 tax = £290.00. Full tax up-front retains £160.00 tax and displays £410.00. Credits use those frozen original groups and their remaining pennies, rather than today's rates. The final credit consumes the remaining residue exactly.

On the issued standard £1,200.00 invoice after £300.00 allocation, a credit for £100.00 net + £20.00 original tax has signed total −£120.00. An immediate issue or applied draft reduces outstanding from £900.00 to £780.00; cash remains £300.00. Saving that credit as a draft leaves outstanding at £900.00 until application. The effective credit reverses its own original invoice posting, not the deposit request.

An effective credit against the legacy proportional £300.00 deposit is a different document operation: a half credit is −£125.00 net −£25.00 tax = −£150.00. With no payment or earlier credit, its displayed outstanding becomes £150.00. Its issue-effect receipts explicitly record not_posted, and no credit financial posting is created. This does not offset the final standard invoice or return cash. See Credit notes.

A credit note is not a refund. If £100.00 is subsequently refunded from the standard invoice's £300.00 funded payment, the separate signed payment is −£100.00: net cash becomes £200.00 and outstanding after the £120.00 credit becomes £880.00. The refund requires admitted original funding and remaining capacity. An operator-recorded refund is an attestation; it does not initiate or confirm a provider refund, and it does not automatically restore provider allocation funds to unapplied cash.

Pro-forma, void and reissue

A pro-forma for the same rental displays £1,000.00 net, £200.00 preview tax and £1,200.00 gross. Those preview totals do not establish a payable receivable or tax posting. Direct positive invoice payments and portal collection against it are disabled. Under the approved policy, any independently received cash must remain an admitted unapplied settlement until the later posting invoice exists; this is not an available pro-forma checkout or automatic conversion promise.

The internal ConvertProformaInvoice action creates a full draft Standard invoice through the existing rental generator and records an immutable link to its original pro-forma. The source preview amounts, ownership and captured currency units must match; a changed rental version or pricing snapshot refuses conversion. The pro-forma stays non-posting and becomes locked. Retrying conversion returns the linked invoice without another document, event or quantity consumption. This action has no public conversion endpoint.

The linked Standard invoice cannot be deleted or voided, and the converted pro-forma cannot be voided. The retirement actions refuse before changing either document, the link or rental quantities, so conversion retry continues to return the original target.

Conversion does not issue the Standard invoice or move cash. After the Standard invoice is separately issued, an admitted unapplied settlement can be allocated once through AllocateUnappliedSettlement; a retry returns its original allocation. Direct allocation to the pro-forma and allocation to the draft Standard invoice remain refused. A pro-forma alone leaves rental invoiced quantities unchanged; conversion consumes the Standard invoice's quantities once.

Situation Current outcome
Unpaid draft deposit Draft void is allowed, subject to permission and version checks.
Unpaid draft or issued non-posting pro-forma Void is allowed; displayed outstanding becomes zero.
Issued non-posting deposit request Ordinary void is allowed when no payment is recorded; its independent unapplied receipt remains unchanged.
Historical issued deposit marked as posting Ordinary void refuses it; no deposit-specific dated cancellation is implemented.
Any document with recorded payments Ordinary void refuses it; a credit and a separately authorized refund are distinct operations.
Generate again after a deposit/pro-forma was voided Authorized generation creates a non-posting successor linked to the latest retired document of the same rental and type; the retired document and independent cash remain unchanged.
Generate after soft deletion Authorized generation creates the same explicit successor link; it does not restore or rewrite the deleted document.

Void does not erase cash, credit history or legal evidence, and it does not allocate or refund a receipt. Retrying generation returns the sole active document without another event; an ambiguous active set is refused. Replacement preserves the original document and cash identities, and does not issue the successor or move cash automatically.

Operational reconciliation

signals:reconcile-portal-payments compares paid Checkout Sessions and succeeded PaymentIntents without writing by default. --record retains verified receipt facts and aliases without allocating invoice cash. Use --repair only when the preview warrants allocation through the installed payment recorder. Repeating repair does not create a second payment. A locally locked account, settlement or invoice is reported as skipped_locked and can be revisited in a new selection after the lock is released.

Use --max-pages=1 to 100 per provider object type, with optional --created-after and --created-before bounds. --json emits version 1, allowlisted receipt rows, status counts and pagination with unit=provider_objects, the page limit, actual pages, truncated and next_cursor. It excludes provider metadata, customer contact details and exception text. Pass the returned opaque cursor with the same date bounds and mode to continue; each object stream resumes separately. A cursor cannot be moved to another tenant, command or selection. A completed selection has a null cursor; an interrupted run should restart the idempotent selection.

The five installed reconciliation commands use these source units:

Command Source bound and resume JSON contract Exit status
signals:reconcile-portal-payments --max-pages=1..100, optional --cursor version=1, rows, counts, pagination 0 for a completed comparison; 1 for validation, listing or row failures
signals:billing-runs:reconcile-attempts --limit=1..500, optional --cursor; stable attempt IDs and age cutoff version=1, rows, errors, pagination, exit_code 0 for inspection/repair with no failed attempts; 1 for refused or failed work; 2 for invalid options
signals:finance:integrity optional --limit=1..500 and --cursor inspect invoice roots only; omit both for the complete audit existing schema_version=22, findings, coverage; bounded runs add pagination 1 for critical findings or incomplete coverage; --allow-incomplete permits incomplete coverage only
signals:billing-runs:audit-counters exactly one named run, --limit=1; no cursor version=1, cached/grouped counts, mismatches, pagination 0 for matching counters; 1 for missing/mismatched run; 2 for invalid audit modes/bounds
signals:audit-invoice-source-links optional --limit=1..500 and --cursor inspect invoice-line IDs; omit both for all eligible lines version=1, scanned, anomalies, total, pagination 0 after inspection; 1 with anomalies and --fail-on-anomaly; 2 for invalid options

The three audits are read-only and refuse --record and --repair. Bounded invoice integrity reports explicitly omit other finance families, invoices outside that page and historical policy checks; they remain incomplete even when the page contains no findings. Audit samples and counts describe only the inspected page. Combine pages before interpreting a bounded selection, and never treat an empty page as a complete finance release pass. The counter audit's one named run is already a terminal unit. JSON option refusals use a versioned error envelope; the shell exit status remains authoritative. Choose at most one of default/explicit --dry-run, --record and --repair.

RecordInvoiceDebitAdjustment links an original posted standard invoice to a separately issued positive standard correction for the same current liable account. The caller supplies an idempotency key and a reason. The existing invoices.issue permission and current warehouse access to both documents authorize the command; draft issuance policy stays separate. Both invoices and their contributors are locked in the existing ranked mutation context. Only the original aggregate advances for a new link; an exact retry changes neither aggregate.

InvoiceDebitAdjustmentPosted captures both immutable InvoiceIssued identities, their original posting and conversion facts, the actor, reason and UTC time. invoice_debit_adjustments is its append-only projection. Each correction can belong to one link. The link creates no payment, receivable adjustment, revenue or financial posting: each independently issued invoice already owns its own economic posting. Neither invoice's totals, existing applied credits or original money units are rewritten. Replay uses the captured issue sources, without current rates, currency precision, authority or inferred historical links. Removing admission is refused while evidence remains.

Settlement operator queue

Open Payments → Settlement queue (payments.settlements, /payments/settlements). It requires invoices.view and uses the named user's warehouse visibility. Receipts whose invoice hint is outside that scope are hidden; unassigned or unknown-invoice receipts are visible only to users with all-warehouse access.

The queue pages through settlement identities, 25 at a time (service maximum 50), with a next-page cursor and a first-page link. It shows provider receipt identity, received time, UTC age in days, the captured account hint, currency, gross, allocated and unapplied minor amounts, plus the original recorded exception evidence and whether a separate resolution exists. It does not add amounts across receipts or currencies. The amounts are observations; the installed commands recheck funding and authority under their own locks.

Operator task Installed authority and queue behavior
Allocate A matching original account, transaction currency and captured base, positive known unapplied amount and invoice payment authority expose Open invoice allocation. Allocate verified cash also opens an in-queue form using integer minor units in the original currency. Both paths call the unchanged AllocateUnappliedSettlement command.
Investigate Investigate settlement opens the recorded diagnostic details. Record investigation resolution calls the unchanged ResolveSettlementException action with a reason and stable idempotency key. The original raised evidence stays separate and immutable; reading the queue does not resolve an exception.
Refund allocated cash InitiateProviderRefund links an already known provider refund to one original allocation, while confirmation needs a verified observation. Link known provider refund is available for authorized allocations and calls that unchanged action with the known refund ID, integer minor amount, reason and idempotency key. It reserves original allocated principal, sends no provider request and does not confirm cash.
Refund pure unapplied cash No released command exists for this case. Refund unavailable remains explicit, the receipt stays investigable, and no synthetic allocation, manual refund or new cash authority is created.

A missing original receipt posting, inconsistent receipt facts or incomplete posting lines produce unknown balance values and remove the allocation link. No live invoice arithmetic or current exchange rate fills those values. A legacy receipt remains visible for investigation with explicit unknowns. Opening the page does not change provider receipts, allocations, invoices, payments, posting facts or exception history.

Queue command forms recheck the current page visibility and action policy before validating inputs. The released actions retain their own authorization, idempotency, original-funding and lock checks. Their refusal messages and any existing machine code are shown unchanged; resubmitting the original command keeps its exact retry outcome.

Finance operations dashboard

Open Admin → System → Integrity → Finance (admin.settings.integrity, /admin/settings/integrity?tab=finance). The payments.operations route (/payments/operations) redirects to this tab. The tenant-wide integrity reader requires settings.manage and all-warehouse access; restricted users are refused before finance source queries. Cloud also requires a selected, fully bound tenant.

Eight cards show released observations for unapplied cash, recorded settlement exceptions, missing historical base evidence, net-tax return readiness blockers, posting conflicts, stale billing claims/runs, failed billing/credit effects and invoice projection drift. Counts are records, never cross-currency money totals. Each card names its limited coverage; a missing or failing reader produces unavailable values rather than zero. Zero observed conflicts do not certify complete financial health.

The page calls the existing read-only finance integrity audit and net-tax readiness checks, and reads durable issue-effect errors. It does not activate monitoring, emit operational alerts, dispatch retries, repair projections or change provider facts. Pure tax filing/jurisdiction status, live FX availability, other effect/claim families and complete replay coverage remain explicitly unavailable.

Balanced source postings

A supported financial source event owns one immutable posting with ordered debit and credit lines. Transaction minor units balance independently of base minor units; balances from different currencies are never added together. The posting preserves the original currency, precision, rate/date, financial dimensions and tax identities. Replay verifies the captured source instead of reading a current conversion or tax value. A provider payment points to its allocation posting; it does not create a second cash posting.

Source Accounting policy and account signs
Issued invoice operational-invoice-issue-v1: receivables debit, invoiced turnover and tax control credit. Historical operational-v1 remains explicitly supported.
Effective credit operational-credit-effect-v1 reverses original receivable, turnover and tax legs. A proposed draft has no posting; later application posts once.
Manual payment / original-funded refund operational-manual-payment-v1 / operational-operator-refund-v1: manual cash control debit and receivable credit for payment; the admitted original funding legs reverse for a refund. Frozen base amounts can require realized FX or rounding legs.
Verified receipt operational-provider-receipt-v1: provider clearing debit and unapplied funds credit. Receipt and invoice conversion evidence are distinct.
Allocation operational-provider-allocation-v1: unapplied funds debit and receivable credit, preserving before/after cash and base balance pointers plus any captured FX/rounding legs.
Allocation correction operational-allocation-reversal-v1: exact inverse of the original allocation, preserving the original receipt and payment. This is a non-cash correction, not a provider refund.
Write-off / reversal operational-write-off-v1 / operational-write-off-reversal-v1: write-off expense debit and receivable credit; an admitted reversal uses the exact inverse.

Admitted subsequent carrying payment sources retain their explicit operational-carrying-manual-payment-v1 or operational-carrying-manual-payment-v2 policy and original financial prefix; this description does not admit a new carrying producer.

An issued cancellation credits the eligible remaining original amount; its cancellation marker adds no duplicate posting. Voiding an effective issued invoice or credit is refused. Account-merge financial effects are provenance referencing the original issue posting, not another ledger entry. Verified chargeback posting implementation and acceptance belong to the shared chargeback source; no refund or generic negative-payment alias substitutes for it.

Allocation reversal retains account IDs, merge lineage and participant identity, authority and the caller's explicit invoice version. After waiting for another invoice's allocation, it captures current financial facts under the held owners rather than rejecting an unrelated pre-lock account credit-clock change. Reallocating restored cash still requires its admitted carrying policy; this correction does not waive that guard. An identical completed command is inert; another reversal command cannot reverse the same allocation twice.

PostgreSQL enforces line direction, immutable evidence and deferred complete balance with constraints and triggers. SQLite has no database-level balance or immutability enforcement; its projector validates supported complete frozen facts before writing and detects changed physical evidence when verifying it. This application check is not a SQLite trigger guarantee.

DEC-06 retains the fixed supported document-currency capability. KWD document creation refuses with invoice_document_currency_unsupported before writes; configuring EUR metadata to scale three still fails ISO-scale validation before posting. These are unavailable-producer qualifications, not a positive three-decimal posting certificate. Zero-decimal JPY and admitted two-decimal sources retain their original units.

Operator allocation is available through the invoice's REST route, generic MCP, curated allocate-settlement and Volt action. Allocation reversal is currently an internal PostgreSQL command, with no installed REST or Volt reversal entrypoint. The invoice Volt page has no refund command; existing REST/generic MCP refunds retain original-funded semantics. Signed provider webhook fixtures exercise local signature verification and receipt/allocation recording, not an external provider network settlement. The conservative producer/caller inventory includes read-only references, fixture builders and document effects separately; it grants no dynamic runtime absence certificate.

New invoice snapshots capture each original revenue-group identity as a soft reference. Turnover lines group only those frozen identities; deterministic cumulative base conversion preserves the exact subtotal base amount. Partial credits and the remaining credit inverse retain those groups and exhaust their original transaction and base amounts. A newly captured unassigned line is explicit; historical missing attribution is unavailable and cannot be rebuilt from current catalogue or rental groups. Legacy source replay keeps its original conversion contract. A draft with uncaptured group evidence refuses issue with invoice_revenue_group_missing; replace its affected draft lines through the existing draft editor before issuing. An issued schema-one invoice can still be credited or cancelled against its proven original unassigned turnover leg. Missing original posting evidence remains refused. PostgreSQL write-off admission accepts original conversion schemas one and two without relaxing its source, amount or approval checks.

Warehouse access to finance records

Restricted staff must have access to the warehouse of each participating invoice, credit note, billing-run item and finance document source. A visible parent does not grant access to a related record in another warehouse. Ordinary billing-run reads and writes, operator recovery, document generation and settlement allocation use the same warehouse boundary. Owners and roles with all-warehouse access retain their existing access.

When a settlement includes a hidden allocation, its queue entry shows only visible allocation identities and counts. Combined receipt balances and exception evidence are unavailable, and the allocation link is withheld, because subtracting those totals would reveal the hidden leg. The original cash, postings and allocations remain unchanged. Finance report caches use the current warehouse grants, and revoking an assignment takes effect on subsequent reads and writes in the same process. Queued system reconciliation retains its explicit tenant operator contract.