Fintech Engineering Handbook – Comprehensive Guide to Building Money‑Critical Systems

Fintech Engineering Handbook – Comprehensive Guide to Building Money‑Critical Systems

TL;DR

The Fintech Engineering Handbook codifies the immutable, auditable, and trust‑less patterns required to build software where money is the primary data model. It covers everything from money representation to ledger design, external integration, access controls, and testing, each tied to the three guiding principles.


Who Should Use This Handbook?

  • New fintech hires – a crash‑course on domain‑specific patterns and vocabulary.
  • Experienced fintech engineers – a reference for solving concrete problems and a shared language for cross‑team discussions.
  • Engineers outside fintech – a primer on why money systems differ from typical web applications.

Contributions are encouraged; the document is intended to evolve.


Core Principles

Principle What It Enforces Typical Mechanisms
No invented data Money cannot appear or disappear arbitrarily. Idempotency keys, deduplication, double‑entry bookkeeping, reservations.
No lost data Every monetary event must be persisted and traceable. Full‑precision types, at‑least‑once delivery, event sourcing, immutable audit trails.
No trust Neither external providers nor internal components are assumed reliable. Webhook signatures, schema validation, cross‑source reconciliation, explicit failure handling.

Representing Money

Precision Handling

  • Avoid floating‑point – it introduces non‑deterministic rounding.
  • Use integer minor‑units for fiat (e.g., store €12.34 as 1234). Crypto often needs arbitrary‑width integers because token decimals can be up to 18 digits.
  • Arbitrary‑precision libraries (BigDecimal, etc.) are ideal for intermediate calculations such as FX or pricing.
  • Rational numbers guarantee zero precision loss but are slower and harder to serialize.

Key rule: Store amounts as integers in the smallest unit and perform calculations with a high‑precision type; serialize as a string or integer, never as a JSON number.

Rounding Strategies

  1. Round explicitly – every division, conversion, fee, or precision change must invoke a rounding step.
  2. Business‑driven direction – round down to avoid overspending or use half‑even for statistical fairness; the choice can affect tax/legal outcomes.
  3. Round as late as possible – keep full precision until persisting or presenting to the user.
  4. Handle residuals – when splitting amounts, track rounding leftovers to avoid balance drift.

Key rule: Rounding must never create or destroy money; residuals belong in a dedicated account.

Currency Handling

  • Pack amount and currency together in a Money type.
  • Disallow arithmetic across different currencies; conversions must be explicit with a controlled rate.
  • Validate currency codes against a curated list at system boundaries.
  • For crypto, identify assets by (network, contract address) rather than ISO 4217 codes.

FX Rates

  • Rates are directional – EUR/USD ≠ USD/EUR; bid/ask spreads mean the inverse is not a simple reciprocal.
  • Timestamp matters – use current‑time rates for live valuations and value‑date rates for tax or reporting.
  • Distinguish transactional rates (derived from the actual conversion) from reference rates (mid‑market or central‑bank rates used for valuation).
  • No single canonical source; always store the source identifier for auditability.

Recording Money: The Ledger

Double‑Entry Bookkeeping

  • Every entry moves the same amount from a credit account to a debit account, guaranteeing the books always balance.
  • Balance is derived, never stored directly.
  • Account types (asset, liability, equity, revenue, expense) enforce the accounting equation assets = liabilities + equity.
  • Corrections are performed by posting compensating entries; original rows remain immutable.

Temporal Dimensions

  • Value time – when the economic event occurred.
  • Booking time – when the event was recorded in the system.
  • Settlement time – when the actual transfer of funds happened (often expressed as T+X).
  • Record all three timestamps; collapsing them loses reconstructability.

Audits & Audit Trails

  • Capture what, when, who/what, and why for every change – not just balance updates but also configuration changes, permission updates, and rule evaluations.
  • Event sourcing treats the event log as the source of truth, making the audit trail primary.
  • Immutability – append‑only storage, runtime checks, and tamper‑evidence (hash chains) prevent silent edits.
  • Reversals vs. Corrections – a reversal negates the original entry; a correction posts the net difference, preserving the history.

Executing Money Flows

Invariants

  • Enforce critical properties by construction (type‑safe constructors, DB constraints), at runtime (assertions, property‑based tests), and post‑factum (reconciliation jobs).

Funds Reservation

  • Reserve funds before invoking external services; distinguish total vs. available balance (available = total – reserved).
  • Reservations must be linearizable and always resolve (release or settle) to avoid dead‑locked funds.

Overdraft Handling

  • Distinguish intentional overdrafts (a credit product) from unintentional ones caused by external mismatches.
  • Do not encode “balance ≥ 0” as a hard type constraint; instead enforce it as an invariant and handle violations explicitly.

Idempotency

  • Use explicit idempotency keys scoped to the operation and client.
  • Treat duplicate deliveries as a single logical effect; retries must collapse to one outcome.
  • Apply idempotency on both inbound and outbound sides of the system.

Full Resumability

  • Model long‑running flows as durable state machines; persist progress after each step.
  • An external driver must detect incomplete flows and resume them.
  • Every step must be idempotent; external effects are unrecoverable, so either retry forward or emit compensating actions (saga pattern).

The External World

Consuming APIs

  • Validate responses aggressively; fail loudly on unexpected schema changes.
  • Expect all calls to fail – implement retries, timeouts, and exponential back‑off.
  • Persist every request and response – this forms part of the audit trail and enables reprocessing.
  • Consider provider redundancy for critical paths, but be aware of the added complexity.

Handling Webhooks

  • Do not trust ordering, validity, or delivery guarantees.
  • Store the raw payload and verify signatures (HMAC or asymmetric).
  • Use the webhook as a trigger to fetch the authoritative state via the provider’s API.
  • Acknowledge quickly (2xx) and process asynchronously; ensure idempotent handling.

Reliable Notifications (Outbox / CDC)

  • Publish events transactionally with the state change (outbox table) or rely on change‑data capture to stream committed rows.
  • Delivery is at‑least‑once; consumers must deduplicate using a stable event ID.

Reconciliation

  • Periodically compare internal records with external sources (hourly, daily, etc.).
  • Match on provider‑generated IDs; if unavailable, use heuristics (amount + timestamp).
  • Resolve mismatches via correction entries or re‑processing, never by overwriting historic data.

Controls & Access

Segregation of Duties & Four‑Eyes

  • Require a second approver for any action that can move or misstate funds (large withdrawals, ledger corrections, fee schedule changes).
  • Record who requested and who approved; the approval must be a distinct actor.

Access Control

  • Apply least privilege via role‑based access control (RBAC).
  • Log every grant/revoke with the same audit‑trail fields used for monetary events.
  • Conduct periodic recertification to catch stale permissions.

Change Trail (SDLC)

  • Treat source control history as the authoritative record of code changes.
  • Enforce mandatory code reviews, protected branches, and signed commits.
  • Deployments must be traceable (who, when, which version) to tie incidents back to the responsible change.

Testing Money‑Critical Systems

  • Property‑based testing – assert invariants (e.g., total debits = total credits) for arbitrary inputs.
  • Invariant checks after each step – automatically verify bookkeeping rules throughout a generated operation sequence.
  • Generative idempotency tests – repeat each operation and confirm no double‑counting.
  • Crash‑and‑resume injection – simulate failures between steps to validate resumability.
  • Round‑trip tests – serialize/deserialize money types and ensure no precision loss.
  • Golden tests – lock down complex calculations (fees, statements) and detect regressions.
  • Backward‑compatibility tests – verify current code can read historic event formats.
  • Testing in production – run canary or synthetic transactions with real money, tagging them for later reversal; never bypass the ledger.

Appendices

Appendix A – Domain Glossary

A concise list of essential fintech terms (ledger, IOU, minor units, bid/ask spread, T+X, etc.) with links to the relevant handbook sections.

Appendix B – End‑to‑End Flow Examples

  1. Crypto withdrawal – demonstrates idempotency, reservation, compliance checks, on‑chain broadcast, finality waiting, ledger posting, and reconciliation.
  2. Card deposit – shows webhook handling, clearing accounts, settlement lag, and chargeback reversal.
  3. In‑app conversion with cashback – highlights currency isolation, precision preservation, rounding at boundaries, and double‑entry posting of both spread revenue and promotional expense.

Conclusion

The Fintech Engineering Handbook provides a self‑contained, principle‑driven blueprint for building systems where money cannot be invented, lost, or trusted implicitly. By adhering to the patterns described—precise representation, immutable double‑entry ledgers, explicit invariants, robust external integration, strict access controls, and exhaustive testing—engineers can deliver trustworthy financial products that survive audits, regulatory scrutiny, and the inevitable failures of distributed systems.

Sources