Explainable, accountant-approved cash application. RemitMatch turns bank transactions and messy remittance advice into explainable, accountant-approved invoice allocations, leaving only genuine exceptions for people to resolve.
Accounts-receivable teams apply incoming B2B payments to open invoices by hand:
download bank transactions
→ hunt through email, PDFs, and portals for remittance advice
→ map the payer to a customer, decode invoice references
→ work out one-to-one, one-to-many, and partial allocations
→ investigate fees, deductions, overpayments, currency and duplicates
→ key in allocations, reconcile balances
→ chase customers for missing detail, keep evidence of every decision
RemitMatch automates the deterministic parts and surfaces the rest as owned exceptions. Every imported payment ends up either as a balanced, explainable, explicitly-approved, duplicate-safe export, or as an exception with a precise reason, evidence, owner, and next action.
AR and cash-application teams at small and midsize organizations receiving B2B payments that may cover one invoice, many invoices, partial invoices, deductions, fees, or ambiguous accounts.
This is the first public release (v3.0.0). It intentionally ships the full V3 product
contract — the complete import → match → review → approve → export → exception workflow, multi-
tenant organizations with role-based access, deterministic matching with accounting invariants,
idempotent replay, a review workbench, and a reproducible synthetic benchmark — rather than a
prototype. See CHANGELOG.md. It has not yet been run against production volumes;
see Limitations.
- Money is exact. All amounts are integer minor units with explicit ISO currency codes — never binary floating point. Cross-currency arithmetic throws.
- A human approves every batch. The engine suggests, explains, and validates; it never bypasses accountant approval, and approval is bound to the exact allocation revision digest. Editing a reviewed allocation invalidates its approval.
- Nothing is invented. No write-offs, deduction reasons, exchange rates, or ledger postings are fabricated. Unsafe or contradictory situations become exceptions, not guesses.
- No LLM in the core. Matching is deterministic and rule-based; identical inputs always produce identical, fully-evidenced output.
flowchart LR
I[Import CSV / PDF-text\ncustomers, invoices,\npayments, remittance] --> N[Normalize\nrefs, aliases, dates,\nexact money]
N --> M[Deterministic\nmatching engine]
M -->|high / review| R[Review workbench\nedit • evidence • balances]
M -->|unsafe / contradictory| X[Exception queue\nowned • recoverable]
R --> A[Approve\nrevision-bound digest]
A --> E[Export\nCSV / JSON • digest • idempotent]
X --> R
Prerequisites: Node.js 20+ and npm. No database server is required for local use — the app runs on SQLite out of the box.
git clone https://github.com/DevFoundry-labs/remitmatch.git
cd remitmatch
npm install
npm run setup # generates the Prisma client and applies migrations
npm run verify # lint + typecheck + all tests + buildsRun it with the bundled synthetic sample data:
npm run seed # creates "Sample Org", one user per role, imports sample data, runs matching
npm run dev:api # API on http://localhost:4000 (in one terminal)
npm run dev:web # web on http://localhost:5173 (in another)Open http://localhost:5173 and sign in as accountant@example.com (dev password
ChangeMe123!, or set SEED_PASSWORD). You will see 82 matched payments — high-confidence
suggestions, items needing review, and exceptions — ready to inspect, approve, and export.
The seed credentials are for local development only. Production startup fails fast if
SESSION_SECRETis missing or weak, and never ships a default password.
A safe, versioned, synthetic dataset (127 invoices, 82 labeled payments) exercises one-to-one, one-to-many, partial, fee/deduction, overpayment, unknown-payer, currency-mismatch, and competing-subset cases. Run it:
npm run benchmarkMeasured on this repository (node v24, results reproducible via the committed dataset and
runner — see docs/benchmark.md):
| Metric | Result |
|---|---|
| High-confidence precision | 100% (59/59) |
| Coverage / recall of definite allocations | 93.1% (67/72) |
| Exception detection | 100% (10/10) |
| Invariant violations | 0 |
| Manual-handling rate | 28% |
Release gates: high-confidence precision ≥ 90% and zero invariant violations — both pass. These are matching-quality measures on synthetic data; RemitMatch does not claim a business "time saved" figure.
Documented, downloadable templates for customers, invoices, payments, and remittance are in docs/import-formats.md; the approved-allocation export schema is in docs/export-formats.md. CSV exports are protected against spreadsheet formula injection, deterministically ordered, and content-digested.
A modular monolith (npm workspaces):
packages/core— framework-free domain: exact-decimal money, normalization, the deterministic matching engine, allocation invariants, and safe CSV. Pure and heavily property-tested; no web or database dependency.apps/api— Fastify + Prisma (SQLite locally / PostgreSQL in production), with auth, RBAC, tenant isolation, imports, a durable job runner, allocations/approvals, exports, exceptions, and a tamper-evident audit chain.apps/web— React + Vite review workbench and admin/reporting screens.benchmark— synthetic dataset generator and deterministic runner.
See docs/architecture.md and docs/data-model.md.
npm run verify # everything (lint, types, tests, builds)
npm test -w @remitmatch/core # domain unit + property tests
npm test -w @remitmatch/api # API integration tests (real SQLite)
npm test -w @remitmatch/web # component tests
npm run cli -w @remitmatch/api -- config:check # validate configurationA Dockerfile and docker-compose.yml are provided. Production uses PostgreSQL, TLS behind a
reverse proxy, and secure cookies. See docs/deployment.md,
docs/operations.md, and docs/backup-restore.md.
- Optional Xero connector is implemented as a preview-first adapter with contract tests only; no live sandbox verification is included and no ledger posting occurs. See docs/integrations.md.
- PDF ingestion covers selectable text via a replaceable adapter; scanned-image OCR is out of scope for this release.
- Automated tests run against SQLite. The PostgreSQL production path is documented and the schema is portable by design (a datasource change), but it is not yet covered by automated tests — validate it in your own environment before production.
- Not yet load-tested at production volume; performance budgets are documented, not guaranteed.
Autonomous ledger posting; inventing deduction reasons or exchange rates; replacing accountant judgment; an LLM-dependent core.
- CONTRIBUTING.md · CODE_OF_CONDUCT.md · SUPPORT.md · GOVERNANCE.md
- Report vulnerabilities privately per SECURITY.md.
MIT © DevFoundry-labs