How it works
A single sentence: user's GBP or EUR sits at Infinia, and at payment time Infinia converts it to BRL — internally routed through a transient USDC pivot — and pushes it to the merchant's PIX key. For the user there's no crypto, no on-chain step, no wallet: the USDC pivot is an internal Infinia settlement detail they never see or hold.
The round-trip
The three moving pieces
| Piece | Owned by | Purpose |
|---|---|---|
| Native OAuth (Apple / Google) | Apple / Google + user | Identity. We verify their ID token against JWKS and issue our own session JWT. |
| Infinia virtual account | Infinia (in user's name) | UK sort code + account number (or IBAN). Receives deposits, holds the user's balance, is the source of PIX payouts and withdrawals. |
| GrinGo API | GrinGo | Stateless orchestrator: verifies session JWTs, kicks off Infinia's HOSTED KYC, creates virtual accounts, executes FX + payouts, records the ledger, processes webhooks. |
Not in the picture: no user wallet, no on-chain address, no seed phrase, no auth vendor, no separate KYC vendor. (Infinia's internal USDC pivot for the FX is a settlement detail inside Infinia, not a user-facing asset — see the payment flow below.) All bundled into the two boxes above.
Why "sits at Infinia" (not in a user-controlled wallet)
The architecturally important choice. The full trade-off analysis lives in architecture/custody-model; the short version:
- Model A (chosen): balance sits at Infinia → payment is two internal FX legs (GBP/EUR→USDC→BRL, both inside Infinia) + one payout → ~15–20s at the merchant terminal.
- Model B (rejected for MVP): balance sits as USDC in the user's wallet → payment adds an on-chain leg → ~35s.
At point-of-sale, that difference is the difference between "usable" and "not usable". Users of a tourist payments app care about speed, not self-custody. If that ever changes, the escape hatch to Model B is documented.
GrinGo still doesn't touch funds — Infinia is the custodian. GrinGo is a stateless orchestrator, verifying JWTs and calling Infinia's API to move Infinia-held money.
The load-bearing flow — one PIX payment
See flows/pix-payment for the full detail (state machine, failure modes, retry/recovery mechanics).
Why Apple + Google (not an auth vendor)
Two decisions for the price of one:
- Zero auth vendor bill. Apple and Google are free; we verify their ID tokens against their JWKS ourselves.
- ~95% coverage of the target audience. UK and EU tourists overwhelmingly have an Apple ID or Google account.
If the door to a user wallet ever needs to open, the auth choice doesn't block it — see custody-model for the deterministic-wallet-derivation constraint we bake in now to keep that migration cheap.