Free tools Windows power users keep installed
One-click scans. No signup required.
The platform was first sketched as three things: account management, payments, and interest on held funds, with a handful of endpoints for each. In a post on DEV Community, Tobiloba describes what that sketch turned into: 94 entity types, more than 100 database migrations, five authentication schemes, two virtual-account providers, a general ledger, webhook retries, and distributed job locking. Most of the added work, in the author’s account, was not new features. It was correctness under failure and operational support: making retries safe when money may already have moved, making balances explainable, making webhooks reliable in both directions, and keeping one tenant’s data out of another’s reach. Every count and production claim below is the author’s own and self-reported. This is one engineer’s account, not an independent audit or an industry benchmark. The original post is at https://dev.to/teb111/building-a-fintech-infrastructure-platform-from-scratch-what-it-2e3b.
What the whiteboard version promised
The product was a multi-tenant API that other fintech companies could use to provision virtual bank accounts, send payouts to Nigerian banks, and hold customer funds with interest accrual. The author names the likely customers as neobanks, savings applications, and lending products. On the whiteboard, that scope looked like account management, payments, and interest, each with a few endpoints. The author’s framing of what came next is direct: “Here’s the gap between the whiteboard and the reality.”
As an Amazon Associate I earn from qualifying purchases.
The scope the author reports
The post gives these project-level counts. None of them is independently verified, and the post shows no year for them beyond an April 17 posting date.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →| Item | Reported by the author |
|---|---|
| Entity types | 94 |
| Database migrations | More than 100 |
| Authentication schemes | Five |
| Virtual-account providers | Two |
| Other components | A general ledger, webhook delivery with retry logic, and distributed job locking (no counts given) |
What happens if the HTTP request to the payment provider times out after we’ve sent the money but before we get the confirmation?
This is the question the author puts first, and it is the one a whiteboard diagram cannot answer. If a provider processes a transfer but the response never arrives, the caller does not know whether money moved. A plain retry can then send it twice. Idempotency is the usual fix. The author checks a client reference that is unique per company before processing a payment. That check is necessary, but in the author’s telling the hard cases sit around it:
#1 Best Overall
- Requests still in flight, where there is no settled outcome to return to a retrying client.
- Cases where the provider and the local system disagree about whether a payment succeeded.
- Partial failures, where money may have moved even though the caller never received a confirmation.
The author spent two days on these edge cases. That is a personal effort estimate for this system, not a benchmark for payment-system work in general. The work, as described, was defining the correct response for each of these states, which a uniqueness check on the reference does not do by itself.
Provider abstraction, and what it cost to add a second provider
Separate interfaces and runtime resolution
The design gives virtual-account providers and payout providers their own interfaces, with a runtime resolver that selects the implementation for a given request. The reason is that providers differ in more than endpoints. The author lists API behavior, credentials, error codes, rate limits, and webhook behavior as points of difference.
Rank #2
The retrofit cost
The author’s first integration was built against one provider, and the abstraction came afterward. Retrofitting it led to provider-specific assumptions that had crept into code meant to be generic. Bringing in the second provider took about a week. The author attributes much of that week to documentation review and credential handling, with careful refactoring of the earlier assumptions also part of the work. This is an anecdotal estimate from one project, not a typical integration duration. The post uses placeholder names, Bank A and Bank B, and mentions Polaris only as an example of provider-specific branching.
Why a transaction history cannot explain a balance
A transactions table records that something happened. It does not, on its own, show how a balance was reached, and that is the question a fintech faces when a customer, a partner, or an auditor asks. The author’s answer is a general ledger built from accounts, journals, and journal lines. Three rules govern it:
- Each journal must have equal total debits and credits.
- An unbalanced journal fails at commit rather than being saved.
- Foreign-exchange conversion rates are recorded at the moment the conversion executes, so the rate stays tied to that transaction.
These are the author’s implementation choices. The post does not present them as the only correct design.
Webhooks are a reliability contract
The author’s own summary of webhooks is: “Webhooks are not just sending HTTP requests. They’re a reliability contract.” The work splits into inbound notifications from providers and outbound notifications to client companies.
Rank #4
Inbound credits and duplicate deliveries
When a provider reports an inbound credit, the system stores the provider’s transaction reference under a unique constraint scoped to each company. A duplicate delivery matches the stored reference and is treated as already processed, so the same deposit is not credited twice.
Outbound notifications to client companies
For notifications the platform sends to the companies that use it, the author reports the following:
Best Value
- HMAC-SHA512 signing of notifications, so recipients can verify authenticity.
- Retries for failed deliveries.
- Delivery status records.
- Replay of missed events.
- Testing without live transactions.
- Delivery history.
The author’s point is that the status, replay, testing, and history interfaces add real operational scope beyond sending the request itself.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Tenant isolation in three layers
The author describes tenant isolation as three layers, each intended to catch a different class of mistake:
- Database: CompanyId constraints on tenant data.
- Services: a company context injected into service code.
- Authentication middleware: validation of a tenant-bearing token before a request reaches a controller.
The author’s justification is: “Defense in depth is not paranoia in financial software. It’s the minimum.” The layers are presented as complementary. The post does not claim that together they guarantee security or regulatory compliance.
Correctness properties instead of feature checklists
The closing takeaway is the author’s own: “I think that reframe from features to correctness properties is the most useful thing I took out of this project.” In practice, that means defining the invariants that must hold when something fails and treating them as the specification, rather than measuring the project by a feature list or by a suite of passing tests.
Design trade-offs at a glance
The table sets out the four design choices the author discusses, with the simpler alternative each one replaced. These are the author’s own comparisons, not a controlled evaluation.
Quick Recap
| Decision | Simpler option | Approach in the author’s build | Trade-off the author describes |
|---|---|---|---|
| Provider integration | Single provider, coded directly | Provider interfaces with a runtime resolver | Provider-specific simplicity now versus switching and failover flexibility later |
| Balance records | Transactions table | Double-entry ledger with balanced journals | Basic event recording versus explainable, balanced account movements |
| Webhooks | Best-effort HTTP sends | Managed delivery lifecycle | Simplicity versus deduplication, authenticated delivery, retries, replay, and observability |
| Tenant filtering | Filtering in one layer | Layered enforcement across database, services, and middleware | Fewer implementation points versus several safeguards against data-access mistakes |
What this account does not establish
- Production status. The author says the platform was in production and onboarding companies when the post was written. That is self-reported and time-sensitive. The post names no customers and gives no transaction volumes, loss rates, or reliability metrics, and nothing independent corroborates it.
- Regulation. The post is not regulatory guidance. It does not say which Nigerian licenses, safeguarding rules, or partner-bank obligations applied to the platform, so those questions remain open for any team considering a similar design.
- Publication year. The page shows an April 17 posting date without a year. No year is assigned here.
“
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




