Fintech Architecture Best Practices: The Non-Negotiables

·11 min read

In most software, a bug is an incident. In fintech, a bug is a liability that may already have cost money nobody has noticed yet.

Fintech architecture has a small number of decisions that are genuinely non-negotiable. Get them wrong and no amount of later engineering fully recovers — you inherit a system where money can be silently wrong, which is the one failure mode a financial product cannot absorb.

1. Balances are derived, never stored as truth

The single most common and most damaging mistake is a mutable balance column that code updates directly. It is convenient, fast, and unrecoverable: when it drifts, there is no way to determine what it should have been.

The correct model is an append-only journal of entries. Nothing is ever updated or deleted; corrections are new compensating entries. The balance is the sum of entries, cached for performance but always reconstructible from the journal.

Mutable balanceAppend-only ledger
UPDATE accounts SET balance = balance - 100INSERT entry (debit 100), INSERT entry (credit 100)
History lost on every writeComplete history by construction
Drift is undetectable and unfixableAny state reproducible at any point in time
Concurrency bugs corrupt state permanentlyDouble-entry invariant catches errors
Audit means reading application logsAudit means reading the ledger

2. Every money path is idempotent

Networks retry. Users double-click. Payment providers deliver webhooks more than once — this is documented behaviour, not an edge case. Any operation that moves money must be safe to execute repeatedly.

  • Every money operation carries a caller-supplied idempotency key, unique per logical intent
  • The key is stored with a uniqueness constraint before side effects, not after
  • A repeated key returns the original result rather than performing the work again
  • Webhook handlers store the raw payload keyed by provider event id, then process — so a redelivery is recognised even mid-processing

3. Money is integers in minor units

Floating point cannot represent decimal fractions exactly, so arithmetic on float money accumulates error. Store minor units as integers (or a fixed-precision decimal type), and make currency explicit on every amount — an amount without a currency is a bug waiting for an international customer.

4. Reconciliation is a feature, not an afterthought

Assume divergence between your ledger and the payment provider — it will happen, through timeouts, partial failures, and provider-side corrections. The question is whether you detect it.

  • A scheduled job comparing internal state against provider settlement data
  • Alerting on discrepancy, with a defined owner and a runbook
  • A defined resolution path — compensating entries, never silent adjustment
  • Stuck-state sweeps: transactions in a pending state longer than they should be

5. Isolation, in both senses

  • Tenant isolation — enforced at the data layer, not by hoping every query includes the right filter
  • Failure isolation — a slow provider must not exhaust the request pool and take down unrelated functionality
  • Environment isolation — no test transactions in production ledgers, ever

6. Build for the audit you will eventually face

No. It provides technical findings within the agreed scope. Legal interpretation, regulated activities and formal certification require the relevant qualified reviewers.

  • Immutable audit trail of who did what, when — including internal admin actions
  • Card data never touching your servers unless you genuinely intend to be PCI-compliant (use hosted fields or a hosted page)
  • Data retention and deletion that can actually be executed on request
  • Access control that is reviewable — who can move money, who approved it
In ordinary software you optimise for speed of change. In fintech you optimise for the ability to prove, later, exactly what happened and why.

The five questions to ask your own system

  1. If this webhook arrives twice, does anything change the second time?
  2. Can I reconstruct any customer's balance at any past moment from the ledger alone?
  3. Would we detect a discrepancy with the provider, or would a customer tell us?
  4. Can a crafted request read or move another tenant's money?
  5. If a regulator asked who approved a manual adjustment last March, could we answer in minutes?

Separate transaction acceptance from settlement

Payment states must be explicit enough to reconcile delayed and repeated events. Verify both financial records and the operator's correction workflow.

  1. Use exact decimal or integer minor-unit amounts with currency rules.
  2. Correlate provider events and internal entries without applying retries twice.
  3. Preserve original records and trace authorised corrections.

Frequently asked questions

Do we need a double-entry ledger for a simple fintech product?

If you hold balances or move money on behalf of users, yes. The append-only journal is not an accounting formality — it is what makes state reconstructible and errors detectable. Retrofitting one after balances have drifted is far harder than starting with it.

What is the most common serious flaw in early fintech systems?

Mutable balances with no journal, followed closely by missing idempotency on payment and webhook paths. Both allow money to become silently wrong, which is the failure mode that is hardest to detect and hardest to remediate afterwards.

Should we store card data ourselves?

Almost certainly not. Use a provider's hosted fields or hosted payment page so card data never reaches your servers. Handling it yourself pulls your entire infrastructure into PCI DSS scope, which is a major ongoing compliance and audit burden.

When should a fintech startup get an architecture audit?

Before the first significant volume increase, and before any funding round where technical due diligence is expected. The structural decisions above are cheap to verify early and expensive to correct once real money has moved through the system.

Can we assume every currency has two decimal places?

No. Define precision and rounding by currency and operation, and verify provider requirements. Avoid binary floating-point for financial amounts that require exact decimal arithmetic.

Want these checked against your system?

We audit fintech architecture against exactly this list — ledger integrity, idempotency, reconciliation, isolation.

Fintech Audit →

Further reading

Technical Due Diligence for Investors: The Complete Guide

Technical due diligence is not a code review. It is an answer to one question: what will it cost to get this technology where the investment thesis needs it to be?

System Architecture Audit: When You Need One and What It Finds

An architecture audit is not an opinion on your tech stack. It is a map of where the system breaks under the plan you actually have.