Roadmap
Rough phasing. Detailed proposals live under openspec/changes/.
Geographic scope
Deliberately narrow at launch; expansion is a first-class roadmap item. Every phase is gated on Infinia having the right rails on both the deposit and withdraw side — a market where we can deposit but not withdraw creates stranded balances, which is worse than not supporting the market at all.
| Phase | Sender markets | Deposit rail | Withdraw rail | Blocker |
|---|---|---|---|---|
| MVP | UK (GBP), EU-27 (EUR) | FPS, SEPA | FPS, SEPA | None — Infinia supports both directions today |
| Phase 2 | US (USD) | ACH (via Infinia US virtual account) | Blocked — no US in Infinia's Payouts endpoint | Waiting on Infinia to add US ACH/wire as a payout destination |
| Phase 3 | Singapore (SGD) | TBC | TBC | Infinia lists SG in Country enum; specific rails need confirmation |
| Phase 4 | LatAm sender countries (AR, CO, MX, CL, etc.) | Local rails per country | Infinia already covers these on both sides | Product-market fit question (would a Colombian want a PIX-first app?) |
Enforcement. MVP restricts users to UK + EU-27 via a post-KYC country check. Infinia's HOSTED widget returns verified_identity.address.country; if it isn't in the allowlist, we reject account provisioning, mark KYC as country_not_supported, and show a friendly "not yet available in your country — join the waitlist" screen. See flows/onboarding § country allowlist.
Phase 0 — Pre-launch (current)
Architecture redesign around Infinia + native OAuth. Design captured in the architecture docs; implementation pending.
Blocking prerequisites to confirm with Infinia before build (see payment-providers open questions):
- UK / EU custodial licensing coverage
- Fee schedule (deposit, FX, payout)
- Whether an
owner.status_updatedwebhook exists (else we poll) - HOSTED widget branding options (SumSub / Infinia / white-label)
- Production base URL
- Ask Infinia about US payout roadmap — needed to unblock Phase 2 planning
Non-negotiable before real users (see privacy pre-production checklist):
- Signed DPAs with Infinia, Cloudflare, Neon
- International transfer mechanism documented
- Privacy policy published
- Data subject request process live
- Data breach notification runbook
Phase 1 — MVP
Build to the design captured in the architecture and flow docs.
- Sign in with Apple + Google (native OAuth + own session JWT)
- Infinia HOSTED KYC + account owner creation
- GBP virtual account (FPS) or EUR virtual account (SEPA), one per user, at signup
- Manual deposit flow with
movement.createdwebhook confirmation - PIX payment: locked quote → internal-transfer → payout, with the BRL-residual auto-reverse mechanic
- Withdraw to user's own bank (GBP / EUR, same currency in and out)
- Balance display + transaction history
- Column-level encryption for sensitive PII (
pgcrypto) - Data subject request tracking table + support runbook
- Nightly reconciliation cron against Infinia
- Retention cron for account closure + webhook events
- Observability baseline: edge SLIs (API request duration, error rate, traffic), business SLIs computed on read (PIX end-to-end, deposit visibility, withdraw settlement), the six page-worthy alerts + runbooks, tooling pick
GET /healthliveness probe under external monitoring from ≥ 2 regions
Phase 1.5 — Operational hardening
- Bank Account Validation on
user_bank_detailssave (instant typo feedback; skip validation on subsequent payouts) - Payment failure auto-reverse cron (backstop for missed webhook cases)
- Observability deepening: SLO burn-rate alerts (multi-window multi-burn-rate), ticket-tier alerts (KYC decline spike, reconciliation drift, retention cron failure, BRL residual high), synthetic PIX canary running against sandbox on an hourly cron
- Rate limits on write endpoints
- Server-side session revocation (KV-backed
jtideny-list) - Bank-transfer-only deposits — smart bank-details ingestion
Phase 2 — UX and reach
- Push notifications for deposit / payment status
- In-app support / dispute flow
- Refunds path (Infinia has refund endpoints — surface them in the app)
- BRL-residual reporting / manual reconciliation UI for support
- Additional home-currency support (make
users.home_currencymutable via a supported migration flow) - Widget branding decisions (if HOSTED brand cost turns out to matter, evaluate EXTERNAL with Persona once it lands in Infinia's roadmap)
Phase 2 — extend
Also worth flagging here: distributed tracing lands as part of Phase 2 — OpenTelemetry-instrumented traces across mobile → API → Infinia → webhook → ledger, plus business-metrics dashboards for unit economics.
Phase 3 — Reach
- US expansion (see Geographic scope) — gated on Infinia adding US to their Payouts endpoint. Would add USD deposits via ACH and USD withdrawals back to a US bank. HOSTED KYC and the balance-holding side should already work — this is a payout-rail addition, not an architectural change.
- Singapore — Infinia lists SG in their Country enum; specific rails need confirmation.
- Additional PIX-adjacent off-ramp corridors (MXN, COP, etc.) — Infinia covers many LatAm rails, and a UK/EU tourist paying merchants across LatAm is a natural extension.
- Locale-aware routing
- iOS / Android platform-specific optimisations (Apple Pay for deposits?)
Optionality kept open (not currently planned)
- Model B migration (crypto wallet balance) — the documented escape hatch. Would use Web3Auth or Turnkey for a "bring your own OAuth" MPC wallet. Roughly a 2–3 month project + gradual per-user rollout. Only pursued if a real trigger arises (Infinia issues, regulatory shift, crypto-native audience demand).
- Card issuance — would need a card programme partner; different vendor stack entirely.
- P2P transfers between GrinGo users — architecturally trivial (an Infinia internal-transfer between two of our users' accounts), product decision only.
- Merchant-side integrations — different product.
Explicit not-planned
- Custody of funds by GrinGo directly (no operational treasury on-chain or off).
- Self-declared KYC (
SELF_DECLAREDmode) — requires Infinia compliance approval and adds real biometric-data controller obligations. Only pursued if HOSTED / EXTERNAL both stop working for us.