Reconcile payments
in one command
OpenRecon matches transactions across your processor, gateway, and internal ledger — then tells you exactly what doesn't line up: fee mismatches, missing settlements, and charges you never recorded.
Decimal-precise. Deterministic. CI-friendly. No SaaS, no upload — your data stays local.
$ openrecon reconcile --left ledger.csv --right processor.csv OpenRecon — reconciliation summary ------------------------------------------ matched 3 amount mismatches 1 (1.00) in ledger only 1 (15.00) in processor only 1 (310.00) ------------------------------------------ status EXCEPTIONS FOUND
Why OpenRecon
Reconciliation that just works
Point it at two CSVs and get a clear, auditable answer — as a CLI or a Python library.
Two-phase matching
Exact match on a shared id or reference, then a heuristic pass on the leftovers by amount, currency, and date window.
Catches fee & amount drift
When ids match but amounts don't, the exact delta is reported — the processing fee or the error, made visible.
Both sides of the gap
Settlements missing from the processor and charges missing from your ledger are listed separately.
Decimal-precise
Every amount is a Decimal — never a float. No rounding surprises on money.
CI-friendly
Exits non-zero when discrepancies exist, so a nightly job can fail the build on a broken settlement.
Zero dependencies
Pure Python standard library. Auto-detects common column names across processor exports.
Processor presets
Every processor, one vocabulary
Stripe calls it gross, PayPal calls it Gross, Adyen calls it
Gross Credit (GC). Presets map them all — and fall back to auto-detection
for anything a preset doesn't cover, so variant exports still resolve.
- Built in: Stripe, Adyen, PayPal, Razorpay, Braintree, Square
- Graceful fallback to column auto-detection
- Override with an explicit mapping anytime
$ openrecon reconcile \
--left ledger.csv \
--right stripe_payouts.csv --right-preset stripe
# list every preset
$ openrecon presets
stripe key=charge_id, amount=gross, …
paypal key=Transaction ID, amount=Gross, …
adyen key=Merchant Reference, …
left = load_csv("ledger.csv")
right = load_csv("processor.csv", preset="stripe")
result = reconcile(left, right,
amount_tolerance="0.01",
date_window_days=2)
for m in result.mismatches:
print(m.left.key, m.amount_delta) # fees
for t in result.unmatched_right:
print("unrecorded:", t.amount)
Library API
Drop it into your stack
OpenRecon is a clean Python API, not just a CLI. Embed reconciliation inside ETL jobs, internal dashboards, or scheduled tasks — and get back structured results you can act on programmatically.
- Typed
Resultwith matches, mismatches, and both unmatched sides - Configurable amount tolerance and date window
- Export to JSON or CSV for downstream tooling
How it works
From two CSVs to a clean answer
Deterministic, explainable, and easy to audit.
Load & normalize
Both files are parsed into normalized transactions; columns like reference, gross, and created are auto-detected (or mapped by a preset).
Phase A — key match
Transactions sharing an id/reference are paired. Amount differences beyond your tolerance become flagged mismatches with the exact delta.
Phase B — heuristic match
Remaining rows are paired by currency and amount within tolerance, choosing the closest date inside the window.
Report exceptions
A console summary plus optional JSON/CSV of every discrepancy — matched, mismatched, and missing on each side.
Who it's for
Built for payments teams
Anywhere money moves through more than one system.
Processor settlements
Reconcile Stripe / Adyen / PayPal / Razorpay payout reports against your order ledger.
Finance & accounting
Catch fee drift and unrecorded refunds before they reach the books or an audit.
Engineering & ops
Run it nightly in CI; fail the build the moment a settlement doesn't balance.
Marketplaces
Match split payouts and connected-account transfers back to internal records.
Audit & compliance
Produce a deterministic, timestamped exception report for every period.
Embedded in your stack
Use the Python API directly inside ETL jobs, dashboards, or internal tools.
How it compares
Why not a spreadsheet or a SaaS?
OpenRecon sits between a brittle manual process and a heavy paid platform.
| Capability | OpenRecon | Spreadsheet / manual | SaaS platform |
|---|---|---|---|
| Deterministic, repeatable matching | ✓ | ✕ | ✓ |
| Decimal-precise money (no float drift) | ✓ | risky | ✓ |
| Runs in CI / automatable | ✓ | ✕ | varies |
| Data stays on your machine | ✓ | ✓ | ✕ |
| Free & open source | ✓ | ✓ | ✕ |
| Embeddable Python API | ✓ | ✕ | API tier |
| Zero setup / no account | ✓ | ✓ | ✕ |
At a glance
Specifications
Everything you'd want to know before installing.
| Version | 0.2.0 |
|---|---|
| Language | Python 3.9+ |
| Interface | CLI (openrecon) and Python library |
| Input | Two CSV files (ledger + processor report) |
| Matching | Key match, then heuristic (amount · currency · date window) |
| Outputs | Console summary, JSON report, exceptions CSV |
| Presets | Stripe, Adyen, PayPal, Razorpay, Braintree, Square |
| Money | Decimal throughout — never float |
| Dependencies | None (standard library only) |
| License | MIT |
| Source | github.com/Naresh-Paturi-Community/openrecon |
Get started
Install & run
Python 3.9+. No other dependencies.
pip install openrecon
# reconcile two files and write the exceptions
openrecon reconcile --left ledger.csv --right processor.csv --csv exceptions.csv
# use a processor preset
openrecon reconcile --left ledger.csv --right payouts.csv --right-preset stripe
Questions
Frequently asked
Short answers to the things people ask most.
Is OpenRecon free?
Yes — free and open source under the MIT license. No paid tier, no account, no SaaS.
Does my data leave my machine?
No. OpenRecon is a local CLI/library with no network calls. Your ledger and processor files never leave your computer.
What CSV formats does it accept?
Any CSV with an amount column. It auto-detects common names (id/reference, amount/gross, currency/ccy, date/created), and ships presets for major processors.
How are amounts handled?
Every value is parsed into a Python Decimal — never a float — so summing thousands of transactions never drifts by a cent.
Can I use it in CI?
Yes. It exits with a non-zero status when discrepancies exist, so a scheduled job can fail the moment a settlement stops balancing.
What if ids don't match between systems?
That's the point of the heuristic phase — transactions without a shared id are matched by currency, amount (within tolerance), and the closest date inside a window.
My processor isn't in the presets — what now?
Auto-detection covers many exports already. Otherwise, pass an explicit column mapping, or open a PR adding a preset for your processor.
What's next
Roadmap
Planned improvements — contributions and ideas welcome on GitHub.
- Many-to-one matching — reconcile a single payout against the batch of charges it settles.
- Multi-currency settlement — handle FX conversion between presentment and settlement amounts.
- More presets — additional processors and report types, contributed by the community.
- Refund & chargeback awareness — first-class handling of negative and reversed transactions.
- HTML report — a shareable, human-readable reconciliation report.
- PyPI release —
pip install openreconfor one-line setup.