Of all the products a team can take across borders, a payment wallet is the most tightly bound to geography. Ride-sharing has to adapt to a new market; a wallet has to be licensed into it. Fiat rails, card issuance, custody — each is regulated market by market, and each regulator has opinions about your architecture.
The default failure mode is subtle. You launch in one country on one banking partner, and eighteen months later you discover that partner's API shapes your ledger, their settlement windows shape your product, and their jurisdiction's rules are hard-coded into your core. You didn't design a national wallet on purpose. You inherited one.
We recently shipped a wallet — fiat and crypto balances in one place, virtual and physical cards — built primarily for India and APAC markets, where the brief demanded the opposite: no single country's banking rules were allowed to dictate the architecture. The client is under NDA; the pattern is worth publishing. We call it regulated at the edges, uniform at the core.
Sort every component by who regulates it
The first design act was a sorting exercise. Every part of a wallet falls into one of two piles:
| Component | Regulated per market? | Architectural consequence | | --- | --- | --- | | Fiat rails (deposits, transfers) | Yes — licensed corridors | Must be pluggable | | Card issuance (virtual + physical) | Yes — per region & network | Must be pluggable | | Custody of crypto keys | Jurisdiction-sensitive | Must not depend on geography | | The ledger | No | Uniform core | | The app (iOS/Android/web) | No | Uniform core | | Auth, sessions, notifications | No | Uniform core |
Everything in the "yes" pile gets an interface boundary and at least one credible alternative provider. Everything in the "no" pile is built once and never forked per market. The discipline sounds obvious; the discipline is also the entire game, because every convenience shortcut in month one ("just call the bank API from the transfer service") moves a regulated dependency into the core, where it calcifies.
Fiat rails: one API, many licenses
Instead of a single-country bank partner, the wallet sits on multi-market embedded-finance providers — the Airwallex/Nium/Currencycloud class — which already operate licensed rails across many countries behind one API. Entering a new market means activating a corridor and its KYC flow, not integrating a new bank.
The important architectural property isn't which provider; it's that the service layer orchestrates whichever rail is active for a given user. Rails are configuration plus an adapter, and two can run in parallel in the same market while you migrate between them — which, in fintech, you eventually will.
Cards without touching card data
Card issuance follows the same pattern (issuing platforms that operate across regions and networks from one integration). The sharper decision was about card data: the app never holds a PAN. Card numbers are tokenized the moment they enter the system, via a dedicated vault (the Basis Theory/VGS pattern), and every internal system works with tokens.
The cheapest PCI compliance is the scope you never enter. A vaulted token can't leak from a system that never saw the number.
That single choice keeps the application out of country-specific card-data scope in every market at once — a compliance posture that travels, instead of one renegotiated per launch.
Custody with no flag on it
The crypto side used the one component where geography can be engineered out entirely: MPC-based key custody. Key shares are distributed; no complete key exists anywhere; no single jurisdiction's infrastructure holds custody of anything. Where institutional-grade requirements applied, the same interface pointed at a Fireblocks-class provider instead. Either way, the property that matters: keys aren't tied to any one country, so custody never appears on the per-market launch checklist.
A ledger that doesn't know what money is
At the core sits a double-entry, currency-agnostic ledger. Every balance is an amount plus a currency — fiat, crypto, any denomination — and nothing in the transaction model privileges one. The ledger doesn't know INR from USDC; it knows debits equal credits.
This is the part teams most often get backwards: they model the first market's currency as the currency and bolt "multi-currency support" on later, which in a double-entry system is not a feature but a rewrite. Currency-agnostic from day one costs nearly nothing; retrofitting it costs the ledger.
Data residency without forking
The last regulated pressure is where data lives. Some markets require certain records pinned to their territory. The answer was infrastructure-level, not application-level: region-segmented storage, so residency is satisfied by bucket and database placement while the application remains one codebase. The security baseline — KMS/HSM key management on a SOC 2 roadmap — was chosen to satisfy the strictest realistic regulator, so it clears the rest by default.
The pluggability test
For any product entering regulated, multi-market territory, we ask three questions of the design:
- Can every regulated dependency be swapped without touching the core? If replacing the fiat rail means changes outside its adapter, the boundary is fiction.
- What does the system never see? Card numbers, complete keys, unencrypted documents — the strongest compliance position is data you structurally cannot leak.
- Is the strictest market the baseline? Designing for the toughest regulator once is cheaper than negotiating with each one separately.
The wallet this pattern comes from is in production across India and APAC — the fuller story is in the case study. And if your roadmap says "multi-market" while your architecture quietly says "one country," that's a conversation worth having early: book a technical call.