Pillar Guide · Knowledge Hub

FinTech: The Constraints That Make Financial Software Different

A practical guide to building financial technology — why money must never be a floating-point number, what idempotency really means when payments are involved, the regulatory shape of the field, and how fraud and risk systems actually work.

FinTech Updated 2026-08-04 1233 words · about 6 min read

Financial software is ordinary software with a set of constraints that change how you build almost everything: mistakes move money, the rules are set by regulators rather than product managers, and "eventually consistent" is sometimes a compliance failure rather than an architectural choice.

None of this is exotic. It is a specific set of disciplines, and most of the expensive failures come from applying general software habits where these apply.

Money is not a number#

The single most important rule, and the one violated most often by teams new to the domain.

Never store or calculate money in floating point. Floating-point types cannot represent most decimal fractions exactly. The classic demonstration — 0.1 + 0.2 not equalling 0.3 — is not a curiosity; at scale it produces reconciliation breaks nobody can explain.

Use an integer count of minor units (pence, cents), or a decimal type with defined precision. Integers are the safest default: an amount is 1050 minor units, not 10.50.

Currency is part of the amount. An amount without a currency is meaningless, and adding two amounts in different currencies must be impossible by construction rather than by convention.

Define rounding explicitly, once, and apply it consistently. Rounding half-up versus half-even produces different totals across millions of transactions, and someone will eventually reconcile against a system that chose the other one.

Never lose precision in intermediate steps. Percentage calculations and currency conversion are where fractions of a unit disappear and totals stop matching.

Idempotency, and why it matters more here#

If a payment request times out, did the payment happen? The client does not know. It will retry.

Without idempotency, the retry takes the money twice. This is not a rare edge case — network timeouts are routine, and every payment integration encounters it.

The standard solution: the client generates a unique key per logical operation and sends it with every attempt. The server records the key with the result. A repeat of the same key returns the original result rather than performing the action again.

This must be implemented at the point where the money moves, not at the edge. An API gateway deduplicating requests does not help if the retry arrives an hour later from a batch process.

The ledger#

Financial systems record what happened, and never overwrite it.

Double-entry is the accounting model worth adopting even when nobody asked: every transaction creates balanced entries, debits equal credits, and the system can prove internal consistency at any moment. It catches whole classes of bug automatically, because an imbalance is detectable without knowing what the correct answer was.

Append-only. You do not update a transaction; you write a correcting entry. The history is the record, and regulators expect to see it.

Balance is derived, not stored — or if stored for performance, it is reconstructable from the entries and reconciled regularly. A stored balance that has drifted from its transactions is a serious defect.

Reconcile continuously against external sources: the payment provider, the bank, the card scheme. Reconciliation breaks found daily are investigable; found monthly they are archaeology.

The regulatory shape#

Specifics vary by jurisdiction, but the categories are consistent enough to design for:

Know Your Customer and Anti-Money Laundering. Identity verification at onboarding, sanctions and politically-exposed-person screening, ongoing monitoring, and reporting of suspicious activity. Screening is not one-off — sanctions lists change, and existing customers must be re-screened.

Payment regulation. Strong customer authentication requirements, rules about who may hold funds, and settlement obligations.

Data protection. Financial data is sensitive under essentially every privacy regime, with retention periods that are often mandatory minimums — you may be required to keep records for years, which interacts awkwardly with deletion rights.

Safeguarding. If you hold customer funds without being a bank, there are usually strict rules about segregation from company money.

Auditability. You must be able to reconstruct who did what, when, and why — for years.

The engineering consequence: audit logging, data retention and access control are requirements from day one, not features to add before the compliance review.

Fraud and risk#

Fraud detection in practice is layered rather than a single clever model:

Rules catch known patterns and are explainable to a regulator. Velocity limits, geography mismatches, amount thresholds.

Models catch patterns nobody encoded — see our machine learning guide for why the baseline comparison matters.

Human review for the middle band where automated confidence is low.

The design decision that matters is the trade-off between false positives and false negatives, and it is a business decision, not a technical one. Blocking a legitimate customer's payment has a real cost in relationship and revenue; letting fraud through has a direct cost. Someone must own where that line sits, and the system must make it adjustable without a code change.

Explainability is not optional. When a customer asks why they were declined, "the model said so" is not an acceptable answer in most jurisdictions.

Testing financial systems#

The stakes change the approach:

  • Test the money paths exhaustively. Rounding, currency conversion, partial refunds, reversals, chargebacks, fees.
  • Test the boundaries. Zero, negative, maximum, and the smallest representable unit.
  • Test the failure paths. Timeout mid-payment, provider unavailable, duplicate webhook, out-of-order events. Payment providers deliver webhooks more than once and out of order — this is normal and must be handled.
  • Reconcile in test. If your test environment does not reconcile, production will not either.
  • Never use real customer data in test environments.

FAQ#

Why can't we use floats for money?#

Because floating-point cannot represent most decimal fractions exactly, so arithmetic accumulates tiny errors. Across millions of transactions those become reconciliation breaks that are extremely difficult to trace. Use integer minor units or a decimal type.

Do we need to be regulated to build financial software?#

It depends on what you do. Holding customer funds, providing payment services or offering credit typically requires authorisation. Building software for a regulated entity usually does not, but you inherit their obligations contractually. Get this assessed early — it shapes the architecture.

How do we handle multiple currencies?#

Store the amount with its currency, never convert for storage, and record the rate and timestamp used for any conversion. Never add amounts in different currencies. Decide explicitly whether balances are held per currency or converted, because that decision is very hard to change later.

What is PCI DSS?#

The security standard for handling card data. The most practical strategy is to avoid handling card numbers at all — use a provider's hosted fields or tokenisation so card data never touches your systems. That reduces your compliance scope dramatically.

How do we deal with webhooks arriving twice?#

Assume they will. Make handlers idempotent using the provider's event ID, and expect events out of order. Treat the webhook as a hint to check state rather than as the state itself — query the provider for the authoritative status.

Why does our balance not match the transactions?#

Usually a stored balance updated separately from the ledger, a rounding inconsistency, or a failed transaction that updated one but not the other. Derive balance from entries where you can, and reconcile continuously so the drift is caught the same day.

What is the most common expensive mistake?#

Not building idempotency into the payment path from the start. Retrofitting it after duplicate charges have reached customers involves refunds, regulatory attention and a loss of trust that costs far more than the engineering would have.

What else is coming for FinTech

Pillar Guide Ready

The definitive explainer — start here.

Tutorials Soon

Step-by-step, with working examples.

Best Practices Soon

What holds up in production, and what quietly doesn't.

Checklists Soon

Run through before you ship.

Diagrams Soon

The architecture, drawn.

Downloads Soon

Templates and starter files you can edit.

Videos Soon

Walkthroughs.

FAQs Soon

The questions people actually ask.