All Projects
Mobile · Offline-first merchant payments

Building a payments app that works where the signal doesn't

A merchant-facing payments app rebuilt offline-first, so a sale can be captured and settled later instead of stalling without signal.

Start a Project
Client
Kestrel
Industry
Merchant payments & point-of-sale
Year
2024
Duration
14 weeks
Role
Mobile engineering + sync architecture
Team
4 engineers, 1 mobile lead
Platform
Mobile
Under NDA
The challenge

Merchants sell from markets, delivery routes and basement pop-ups — exactly where the old app's server-dependent design left a cashier staring at a spinner mid-sale. A payments app that assumes a signal it never had isn't a payments app in most of the places it's actually used.

Approach & solution

Approach

We rebuilt the core sale flow to assume no connection by default, not as a fallback mode bolted on afterward. Settlement was redesigned as a background concern the merchant never waits on, so the app's happy path and its offline path are the same path.

Solution

An offline-first payments app with local-first transaction capture, a conflict-resolved settlement layer that reconciles once signal returns, and a merchant dashboard that reflects sales status without waiting on a connection.

The sale-capture flow, completing a transaction with no network present.
The merchant dashboard, showing a sale as settled once signal returns.
What shipped

The capabilities behind the screens.

Local-first transaction capture

A sale is recorded on-device the instant it happens, connection or not.

Conflict-resolved settlement

Reconciles automatically once signal returns, no manual review needed.

Merchant dashboard

Sales status reflects reality without waiting on a round trip.

Offline transaction queue

Every unsent sale sits in an ordered queue, never silently dropped.

On-device encrypted ledger

A merchant's local sales record is encrypted at rest, not just in transit.

Sync status indicator

A merchant always knows whether a sale has settled or is still queued.

Tech Stack & Architecture

The client-side architecture and interface layer shipped for this engagement.

2 tools · 1 primary

Services, APIs, and business logic running the system end to end.

3 tools · 1 primary

Datastores and pipelines chosen for this engagement's consistency and throughput needs.

3 tools · 1 primary

Deployment, orchestration, and delivery tooling running the platform in production.

3 tools · 1 primary

System architecture

Technical challenges

Resolving conflicts when a terminal settles twice

Two devices could capture the same sale before either reconnected. Every transaction carries a device-scoped idempotency key, so settlement can safely retry without ever double-charging a customer.

Keeping the local ledger consistent after days offline

A market vendor might not reconnect for a week. The sync protocol replays queued transactions in causal order and rejects any that conflict with a server-side state the device hasn't seen yet, rather than blindly overwriting.

Background sync within a mobile battery budget

Aggressive background sync would have drained the merchant's phone by midday. Sync batches and backs off based on both connectivity quality and queue size, so it never runs more than it needs to.

How it was built

The stages this engagement ran

01

Brief & Strategy

1 week

Shadowed merchants selling from a market stall and a delivery route with no reliable signal.

02

Strategy & Planning

2 weeks

Offline-first sync protocol designed before a single screen was built.

03

UX & UI Design

2 weeks

Sale flow designed to look identical whether or not a connection was present.

04

Development

6 weeks

Local-first capture and the settlement layer built together from the first commit.

05

QA & Optimization

2 weeks

Field-tested across real dead zones, not simulated airplane mode.

06

Deployment & Support

1 week

Rolled out to a pilot group of markets before the wider merchant base.

Results

What changed, in the numbers.

0
Sales lost to a dropped connection since launch
100%
Transactions captured locally before any network call
7 days
Longest offline stretch reconciled without a conflict
<1%
Battery drawn by background sync in a typical day

“Our vendors stopped asking for a signal before they'd sell. The app just doesn't need one anymore.”

Ben Okafor · Operations Manager · Kestrel

Selected screens

Kestrel, in the product

A sale in progress with no connection — the same flow as online.
The sync status indicator, showing a queued sale waiting for signal.
The merchant dashboard reconciling a week's worth of offline sales at once.
The conflict-resolution log, showing two devices' sales merged without a double-charge.

Technical briefingNot a sales desk

PRJECT IN MIND?

Tell us the load.
We will calculate the structure.

Let's Talk