Financial infrastructure / Case study
FlowLedger
Keep balances exact through payment retries.
- Type
- Open-source engineering
- Release
- v2.0.0
- Stack
- Python 3.12 · FastAPI · Pydantic v2 · Double-Entry Engine
- Automated tests
- 103
System architecture
- Immutable Double-Entry Ledger Engine (flowledger/ledger/engine.py)
- Idempotent Payment State Machine & Webhook Guard
- Automated 3-Way Reconciliation Pipeline
01 / Problem
Why it exists
Mobile money and payment integrations face duplicate webhook deliveries, out-of-order settlement callbacks arriving before authorization responses, network timeouts, and provider fee discrepancies that corrupt naive single-column balance tables.
02 / Design
How it works
Represent all monetary amounts as strict integer minor units and derive all account balances from append-only, SHA-256 hash-chained double-entry postings.
Immutable Double-Entry Ledger Engine (flowledger/ledger/engine.py)
Enforces integer minor-unit amounts, balanced debit/credit postings, account normal-balance rules, and SHA-256 hash chaining.
Idempotent Payment State Machine & Webhook Guard
Validates state transitions, buffers or resolves out-of-order settlement callbacks, and blocks replayed or tampered webhooks.
Automated 3-Way Reconciliation Pipeline
Cross-checks payment orders, ledger journal entries, and provider statements into MATCHED, FEE_DISCREPANCY, MISSING_IN_LEDGER, and STALE_UNSETTLED.
Strict Integer Minor-Unit Accounting & Hash-Chained Journal Entries
- Context
- IEEE-754 floating-point numbers introduce rounding drift during fee splits, and mutable balance columns hide audit history during payment disputes.
- Decision
- Represent all monetary amounts as strict integer minor units and derive all account balances from append-only, SHA-256 hash-chained double-entry postings.
- Trade-offs
- Requires explicit currency minor-unit scaling at display boundaries, but guarantees zero rounding drift and complete auditability.
- Verification
- Verified across 103 automated tests in tests/test_ledger_invariants.py, tests/test_reconciliation_and_api.py, tests/test_camt053_and_csv.py, tests/test_split_and_escrow.py, tests/test_mcp_and_aegis.py, tests/test_server_hardening.py, and tests/test_v2_pan_african.py.
Security and operational constraints
- Constant-time HMAC-SHA256 webhook signature verification (hmac.compare_digest) with timestamp replay-window enforcement and nonce caching.
- SHA-256 hash-chained journal entries (entry_hash = sha256(prev_hash + canonical_payload)) prevent silent ledger mutation.
- RFC 6962 standard Merkle tree inclusion proofs enabling logarithmic cryptographic verification of journal entry inclusion.
- SQLite Write-Ahead Logging (WAL) mode persistence with database-level append-only triggers preventing UPDATE and DELETE mutations on journal records.
- 100% synthetic sandbox data—no live merchant credentials or proprietary customer records are used.
- Every JournalEntry must satisfy Sum(Debits) == Sum(Credits) in integer minor units; floats and booleans are rejected.
- Duplicate idempotency keys with identical payloads replay the cached response without creating duplicate ledger postings.
- Every ledger posting is linked to an immutable SHA-256 hash chain verified by verify_invariants().
03 / Evidence
How to verify it
Repository-reported / Ledger Invariant Integrity
0 Imbalance · 103 Verified Tests100% balanced debits == credits across 12 currencies, M-Pesa Daraja 2.0, ISO 20022, FX corridors, and offline vouchers
Reproduce from the command line
git clone https://github.com/codesphere-u/flowledger.git
cd flowledger && pytest -v
python -m flowledger.cli demo