Flo

Customer Wallet

A mobile-first wallet your customers carry in their pocket — built on the same double-entry ledger that runs the rest of the platform.

Not a separate product bolted on beside your books. The same ledger, which means a customer's balance and your accounts can never disagree, and there is no nightly synchronisation job to fail quietly at 3am.

The wallet ships as an installable mobile app — available through the Play Store — and as a mirrored set of back-office screens. Both call one self-scoped access layer, so a customer sees and moves only their own money, whichever channel they use.

Behind the simple Send · Request · Top up · Settle · Pay by QR buttons sits the full ledger engine: every movement is a balanced double-entry transaction, every fee is its own auditable posting, and every read is constrained to the authenticated customer. This page covers the options, who they are for, how fees work, and the security model that makes it safe to run under the customer's own least-privilege identity.

KYC & Verification →

Two Front-Ends, One Access Layer

The wallet exposes six money movements around a single balance:

Action Direction Typical use
Send out Pay another person, or pay a merchant
Request pull Ask someone to pay you
Top up in Load the wallet from card or bank
Settle out Withdraw to a bank account
Pay by QR in Show a code; anyone scans to pay you
Statement read Paginated history with proof of payment

The mobile app and the back-office screens are two doors into the same access layer, so a change to a rule updates both at once. There is no drift between what the app enforces and what the back office enforces — a class of bug that is otherwise almost guaranteed, and expensive when it concerns money.

Payment notifications reach the payee in real time the moment a transfer posts.

Person-to-Person (P2P)

The everyday case: one customer pays another, or asks to be paid.

Send debits the payer and credits the payee in a single balanced transaction, with a note from each side and a shared reference. The payee gets a live in-app notification and can email a proof-of-payment document straight from the statement line.

Request is the pull equivalent — nominate someone, an amount and a reference, and they are prompted to approve payment from one of their accounts. Nothing leaves any balance until the payer acts.

Pay by QR removes the need to know the other party in advance. The payee generates a code carrying a single-use token with an expiry; whoever scans it sees the payment details and pays from their own account. The request is locked the moment it is fulfilled, so a code can never be paid twice, cannot be paid by the person who raised it, and stops working when it expires — the three failure modes that make naive QR payment schemes dangerous.

Business-to-Business / Merchant (B2B)

The same rail carries merchant payments — a customer paying a shop, or one business settling with another. What differs is not the mechanism but the pricing attached to the account:

  • A merchant profile can charge the payer, the merchant, or both, and can take the fee on top of the amount or out of it.
  • Because every account inherits its pricing from a profile, you price consumer and merchant traffic independently without changing any code — and without a release, a deployment, or a developer.
  • Merchants settle collections to a bank through Settle, and a static "Scan to Pay Me" code lets walk-up customers pay in person with no pre-registration at all.

One product therefore serves consumer P2P, merchant acceptance and business disbursement. The ledger treats them identically; pricing and verification tier express the commercial difference. Launching a merchant proposition is a configuration exercise, not a second implementation.

How Fees Are Applied

Fees are configuration, not code. Every account inherits a pricing profile, and that profile carries an independent block of settings for every operation — send, receive, top up, settle, merchant, and per-message notification fees. For each one, the engine resolves the fee in four steps:

1 · Threshold — at or below a configured amount, the fee is zero. Small transfers run free while larger ones are priced — the standard shape of a consumer wallet proposition, available without special-casing.

2 · Rate — a percentage of the amount, capped at a ceiling, or a flat fee. Both are supported; you choose per operation.

3 · Who pays — payer, payee, or both. Charging both sides raises a separate fee for each.

4 · How it is taken — either on top of the transfer (the payee receives the full amount and the fee comes additionally out of the payer's balance) or out of it (the payee receives the amount less the fee).

Whatever the outcome, the fee is never hidden inside the transfer. It posts as its own debit/credit pair into a revenue account within the same parent transaction.

That is a revenue-recognition property, not a cosmetic one: your fee income is a first-class ledger figure that reconciles and reports on its own, instead of a number you have to reverse-engineer out of net movements at month end.

Consistent Pricing Across Every Operation

Every fee-bearing operation has the same shape, so pricing is configured consistently rather than learned six separate times:

Setting Meaning
Flat fee Fixed amount, used when no percentage applies
Percentage Proportion of the transaction amount
Cap Ceiling on the percentage fee
Threshold Minimum amount before any fee applies
Charged to Payer · payee · both
Method On top of the amount · out of the amount
Narration The text that labels the fee on a statement

The operations priced this way are send, receive, top up and settle. Merchant pricing is expressed through the send and receive settings on the merchant's own profile. Message fees — for SMS, WhatsApp or email notifications — are flat amounts that recover delivery cost.

Repricing your entire product is a configuration change an operations team can make and audit, not a development ticket.

Worked Example — A Capped Percentage Send Fee

A profile prices outbound person-to-person sends like this:

Free below         10.00
Percentage          1.50 %
Capped at           5.00
Charged to          payer
Method              on top of the amount
  • Send 8.00 → at or below the threshold → fee 0.00; payee receives 8.00.
  • Send 100.00 → 1.5% = 1.50, under the cap → fee 1.50; payer −101.50, payee +100.00.
  • Send 1,000.00 → 1.5% = 15.00 → capped to 5.00; payer −1,005.00, payee +1,000.00.
  • Switch the method to out of the amount and that last case becomes payer −1,000.00, payee +995.00.

Every one of those fee figures is a real ledger posting into a revenue account — reconciled and audited exactly like any other transaction. Nothing about your fee income is estimated, derived, or held in a spreadsheet.

Security — Enforced Beneath the Application

The wallet runs under the customer's own least-privilege identity, never a shared trusted service account.

That distinction is the whole security argument. In the common design, a mobile app authenticates as a privileged service and then decides what the user is allowed to see — so a stolen token, a tampered client or a single missed check exposes everyone. Here a stolen token can do no more than that one customer could already do, because the limit is enforced beneath the application rather than by it.

Defence is layered:

  • Identity is derived by the server, never asserted by the client. The platform reads who you are from your verified credential. A client cannot ask for someone else's data by changing a parameter, because it never supplies the identity in the first place.
  • Record-level isolation scopes every read to the authenticated customer, applied at the core and applied to the calling identity — not a filter the application remembers to add.
  • Ownership checks on every money movement. Each transfer confirms the customer actually owns the account being debited before anything happens.
  • Browser hardening — a strict content-security policy, an origin allowlist, a cache policy that never stores authenticated responses, and automatic logout on an expired session. The Android app is cryptographically bound to its origin.
  • The ledger's own guarantees underneath — balanced double-entry, automatic audit capture with full before-and-after detail, and real-time fraud scoring on every posting.

Safe-by-Design QR Requests

Payment codes are convenient and, done carelessly, dangerous. This flow is bounded on every axis that matters:

  • The token is minted by the server, never by the device, and carries an expiry (one hour by default).
  • The request is locked while being paid, so two simultaneous scans cannot both succeed. The second is told it has already been paid.
  • Self-payment is rejected outright.
  • Scanning reveals only the minimal details needed to pay. The code grants the right to pay, not to look at the payee's account.
  • The static "Scan to Pay Me" code carries no credentials at all — it simply pre-fills the send screen, where the normal authenticated, permission-checked path takes over.

Real-Time Notifications

When a payment posts, a structured notification is pushed to the payee only, in real time.

Notifications are best-effort by design: they fire after the payment has committed and can never roll a payment back. A notification service having a bad day must not be able to reverse settled money — so structurally, it cannot.

The interface renders notifications by shape rather than by hard-coded type, so new notification kinds need no app update and no release. Links are restricted to safe destinations within the application, and both the mobile and back-office channels render identical content — so what a customer sees and what your support agent sees never diverge mid-conversation.

API-First — No Private Wallet Protocol

Every button in the mobile app is a call to the same public, self-scoped REST API an integrator can drive directly. There is no hidden internal protocol reserved for our own client, which means embedding wallet movements into a partner app, a kiosk or an automated disbursement run is ordinary integration work rather than a bespoke engagement.

What you can build: send and request payments, top up and settle, open and fulfil payment codes, pull statements, and email proof of payment.

Base URL: https://api.ledgerflow.ai

Authentication is the platform standard — authenticate once, then present a bearer token. The credential carries the customer's identity, which the platform uses for both authorisation and notification targeting. The caller never supplies it as a parameter, so it cannot be forged by an integration, whether by malice or by mistake.

Full specification: https://swagger.ledgerflow.ai — every endpoint, parameter and response schema, browsable without writing code. The same ownership checks that protect the app protect the API: a customer can only ever touch their own accounts, and any attempt to reach another's is refused.