KibiPay
HomeBlog › Mobile

A Phone-First Mobile Wallet: One-Time Codes, QR Pay, Send and Receive

8 min read Mobile
MobileWallet
A Phone-First Mobile Wallet: One-Time Codes, QR Pay, Send and Receive

The most natural payment interface most people carry is their phone. KibiPay's mobile wallet leans all the way into that: you sign in with your phone number, you pay by pointing the camera at a QR code, and you get paid by showing one. No passwords, no account numbers to transcribe. Here's how it's put together.

Built on Expo

The wallet is a React Native app built with Expo and file-based routing via expo-router. That choice buys a lot: over-the-air-updatable JavaScript, a rich library of native modules (camera, biometrics, secure storage) without hand-writing native code, and a cloud build pipeline that produces a real iOS binary without a Mac — a story told in from prototype to TestFlight. The screens are exactly what you'd expect of a wallet: a home tab with your balance and quick actions, a scan tab, a receive tab, an activity ledger, a profile, and a pay screen.

Sign in with a phone number and a code

There's no password anywhere in the app. Sign-in is a two-step one-time-code flow: you enter your phone number (or email), the app calls POST /v1/auth/otp/start, you receive a six-digit code, and the app verifies it with POST /v1/auth/otp/verify. A brand-new number simply gets a wallet created for it on the spot, pre-loaded with demo money, so onboarding is instant. Verification returns a session, which the app stashes in the device keychain via secure storage and sends as an X-User-Session header on every subsequent request. The phone is the identity and the keychain is the vault; there's no shared secret for a user to forget or leak.

Pay by scanning a QR

The scan tab opens the camera — configured to recognize QR codes specifically — and when it reads a KibiPay payment code, it resolves the code to a payee and pushes you straight to the pay screen with the details pre-filled. You're one confirmation away from sending. Under the hood the pay screen calls POST /v1/me/pay with the recipient, amount, currency and an optional memo, and lets the platform's routing pick the best available rail — the app doesn't make you choose between Faster Payments and Mojaloop, it just moves the money.

Get paid by showing a QR

Receiving is the mirror image. The receive tab asks the backend to create a payment request and renders it as a QR code for the payer to scan. It then polls every few seconds and, the moment the payment lands, flips to a "received" confirmation. For the payer, scanning that code drops them into the same pre-filled pay flow described above, and when they pay, the request is marked paid on both sides. It's the in-person payment experience people already understand from mobile-money apps: one person shows a code, the other scans it, done.

An activity ledger you can trust

The activity tab reads the user's ledger so every send and receive shows up as a clear line item. Because the wallet sits on top of the same canonical payment platform as everything else, the money movements it shows are the real thing — the same ledger, the same statuses — not a separate toy tally. The profile tab rounds it out with the user's aliases (the human-friendly names that resolve to their wallet) and a sign-out that clears the keychain session.

Why phone-first matters

Every friction point the wallet removes — no password to invent, no IBAN to type, no rail to choose — is a place a payment used to fail or a user used to give up. Anchoring identity to the phone, addressing by QR, and letting the platform route the rail turns "make a payment" into "scan and confirm." And because sending money is genuinely consequential, that confirmation is backed by the payee-name and biometric checks described in Confirmation of Payee and Face ID.

Where the wallet ends and the platform begins

A deliberate line runs through the wallet's design: the app is a thin, friendly client, and the hard parts live on the platform. The wallet doesn't decide which rail to use — it calls a single pay endpoint and lets the platform's routing pick the best available rail, so a user never sees the machinery behind "send money." It doesn't invent its own notion of a balance or a transaction — the activity tab reads the same ledger the rest of the platform posts to, so what the wallet shows is the authoritative record, not a separate tally that could drift. It doesn't hold long-lived secrets in application memory — the session lives in the device keychain and travels as a header. That thinness is what keeps the app trustworthy: the money logic, the ledger, the routing and the screening all sit server-side where they can be audited and hardened, while the app concentrates on being fast and legible. It's also what makes the phone-first experience honest — the simplicity the user sees isn't achieved by cutting corners, it's achieved by pushing the complexity to where it belongs.

See it in motion

KibiPay connects UK Faster Payments, Bacs, CHAPS, Mojaloop mobile money, a mock ACH rail and Solana behind one API, with a cross-rail alias directory, ISO 20022 messaging and real-time fraud & AML screening.

Open the live console Directory demo