The editorial argues that documents like this are rare not because the material is secret, but because senior payments engineers at Stripe, Adyen, and Block are paid too much to write it down. Pitula breaking from that pattern by publishing a practitioner-grade reference for free is framed as the story's central significance.
Pitula's handbook centers on the double-entry ledger as the source of truth: money is never mutated, only recorded as movement between accounts, with every transaction written as two balanced entries. He frames the common balance-increment/decrement approach as the underlying defect that surfaces during retries, duplicate webhooks, and audit requests.
The editorial endorses Pitula's diagnosis, listing concrete failure modes — double-tapped Pay buttons on flaky 4G, retry middleware firing twice on a 502, partners replaying the same webhook three times, and IRS requests for specific historical cents — that all trace back to treating balance as mutable state rather than a derived view of an immutable ledger.
Pitula treats idempotency keys as a contract rather than decoration, reconciliation as a first-class scheduled job, and PCI scope and KYC as design constraints that shape system architecture. The handbook's framing rejects the common pattern of delegating these to compliance or ops teams after the fact.
The submitter's post hit 398 points with 136 comments, an unusually strong signal for a single-author technical reference. That level of engagement typically reflects engineers forwarding the link to colleagues before they touch a payments service, validating the handbook as the kind of resource senior engineers wish had existed on their first on-call.
Wojtek Pitula published the Fintech Engineering Handbook at w.pitula.me — a free, book-length, practitioner-grade reference covering ledgers, idempotency, reconciliation, PCI scope, chargebacks, KYC, and the rest of the surface area that money-moving systems force on you. It hit 398 points on Hacker News, which for a single-author technical reference is the kind of signal that usually means engineers are forwarding it to coworkers with the subject line *"read this before you touch the payments service."*
The handbook is not a tutorial. It's the kind of document senior engineers wish had existed when they were on call for their first chargeback storm. It walks through specific patterns — the ledger as the source of truth, idempotency keys as a contract rather than a decoration, reconciliation as a first-class scheduled job — and treats PCI scope and KYC as engineering problems, not legal ones.
The reason a document like this is rare isn't that the material is secret — it's that the people who know it are paid too much to write it down. Stripe, Adyen, Block, and the other shops where this knowledge concentrates pay their senior payments engineers in the high six figures. Their blogs ship sanitized case studies, not the working playbook. Pitula released the working playbook.
Most backend engineers will, at some point in their career, be asked to "add payments." The default mental model — a `balance` column you increment and decrement — is wrong in ways that don't show up in staging. They show up when a customer double-taps the Pay button on flaky 4G, when your retry middleware fires twice on a 502, when a partner sends the same webhook three times because their queue had an outage, or when the IRS asks you to produce a transaction history for a specific cent on a specific day in 2023.
The handbook's central move is the double-entry ledger: money never *moves*, it only gets *recorded* moving, and every transaction is two opposing entries that must sum to zero. This is 700-year-old Venetian accounting, and it's the same pattern that survives Stripe-scale throughput because it's the only model that lets you answer "where is the money?" without race conditions. If your payment service stores a single mutable balance, you don't have a payment service — you have a counter that customers will eventually win an argument with.
Idempotency gets similar treatment. The handbook frames idempotency keys not as a retry convenience but as the only thing standing between you and double-charging a customer when the network coughs. The pattern is specific: the key is generated client-side, stored before the side effect, and the response is cached for long enough that any reasonable retry hits the cache. "Reasonable" here means 24 hours minimum, because that's how long it takes a misconfigured webhook receiver to give up. Most homegrown idempotency layers store the key *after* the work, which guarantees nothing.
Reconciliation is the section that separates fintech engineers from backend engineers who have done some payments. Your system and your payment processor will disagree, and the question isn't whether — it's how fast you find out and how cheaply you fix it. The handbook treats reconciliation as a scheduled cron, not a manual process: pull the processor's settlement file, diff it against your ledger, surface the deltas, and have a human-friendly UI for resolving the ones that don't auto-match. Shops that skip this step discover their disagreements in the form of regulator letters.
The Hacker News thread surfaces the cultural piece. Commenters from Plaid, Adyen, and ex-Stripe shops keep noting that the handbook "reads like our internal onboarding doc" — which is exactly the point. Fintech engineering is an information desert maintained by NDA, regulatory paranoia, and the lucrative consequences of staying scarce. A free handbook is a small leak in that moat.
If you're building anything that moves money — even sideways, even briefly, even just as a wallet balance for in-app credits — the handbook is a checklist of failure modes you haven't hit yet. Three concrete actions to take this week:
Audit your idempotency layer. Find every endpoint that performs a side effect and ask: if the client retries this request 30 seconds later with the same idempotency key, do they get the cached response or a second side effect? If you don't have idempotency keys, your retries are charging customers twice during partial outages. This is not theoretical; it's the most common production bug in payments code.
Convert your `balance` column to a ledger. If your wallet/credits/balance table has a single mutable amount, replace it with an append-only ledger of entries and compute the balance as a sum. Yes, it's more code. Yes, it requires care around partial sums and materialized views. The alternative is that someday a customer will prove their balance is wrong and you will have no way to reconstruct what happened.
Schedule reconciliation now, not later. Even if you're tiny, even if you trust your processor, write a job that compares your ledger to the processor's settlement file daily and alerts on deltas. The first time it fires will surprise you. The fifth time will save your audit.
A note on PCI scope: the handbook is honest that the easiest way to handle PCI is to never see card numbers, which means leaning on Stripe Elements, Checkout, or the equivalent. If your form has a ``, you're paying for a much larger compliance program than you need to.
The handbook lands at a moment when AI agents are about to start moving money on behalf of users at scale — agentic checkout, autonomous trading bots, programmatic B2B procurement. Every one of these systems will retry under uncertainty, and every one of them will expose every idempotency and reconciliation flaw their builders skipped. The patterns Pitula documents aren't going to get less load-bearing; they're about to get tested by software that's worse at handling ambiguity than a human with a Pay button. The handbook arrived just in time to be the thing AI-tool builders should read before letting a model call `POST /charge`.
Word of advice to anyone considering the "minor-units precision" strategy for representing monetary amounts: Don't (or at least, don't use it as an interchange/API data format).It seems like a clever idea (fast integer math, no rounding problems for addition and subtraction)
> Money can’t be created out of nowhereWell, in case of a bank it can. And it happens on a daily basis. In fact thats how most private bank money enters the system in the first place either when a bank makes a loan or when it buys any other asset like e.g. a corporate bond (you can conceptualize
As a programmer, what I feel when I see fintech programmers each speaking from their own different experiences and perspectives is that it makes me wonder what it really means to be good at programming.What user xlii said about not storing monetary amounts as floats is a common IEEE 754 issue. And w
Nice. The book contains a bunch of good information that could already be found elsewhere but collecting it is quite practical. I highly suggest to read Kleppmann's Designing Data-Intensive Applications. The first edition was very good, a second one came out recently.I was CTO of a FinTech wher
Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.
I glanced, and I found this handbook shallow and - in some areas - even bad advice.E.g. If I ever see a monetary value stored in something else than integers I'm going to run away screaming (thank you Rust decimals represented as JSON floats). It's always integers unless you have a VERY go