Skip to work
Back to all work

01Mobile · API · Operator portals·2025 — 2026

Coil

Fuel you pay for in the app and collect at the pump.

Role
React Native & full-stack engineer (contract)
Years
2025 — 2026
Stack
React Native · Expo Router · TypeScript · Node.js

Screens

Coil · 05 frames

Platform command centre01
Top up wallet02
Pay for fuel with a QR code03
  • Wallet and nearby stations04
  • Find a station and check prices05

01Overview

Drivers see which nearby stations have fuel, fund a naira wallet, and pay with a QR code. The ledger moves only when an attendant scans it. No card on the terminal.

02The problem

You cannot tell which station has fuel, or today's price, without driving there.

At the pump the POS hangs, and handing over a debit card is a fraud risk. If the app debits a wallet and the pump never dispenses, the customer has lost money.

03What we built

Stations are GeoJSON. A 2dsphere query returns live price and stock inside 5 km.

A purchase is a QR, not a completed debit. The attendant scans it — camera or NexGo POS — and only then does the ledger move.

04My role

Expo app, Express API, Paystack webhooks, and the operator portals.

  • Expo app: wallet, Paystack, PIN, biometrics, QR receipts
  • Station search within 5 km (GPS, maps, MongoDB 2dsphere)
  • Ledger writes in a transaction; Paystack credits verified by HMAC and idempotent
  • Admin, HQ, branch, and business portals on the same API

05Request path

Coil · how a request moves
  1. 01

    Expo app

    Driver

  2. 02

    REST API

    Express + JWT

  3. 03

    Ledger

    Mongo txns

  4. 04

    Paystack

    HMAC webhook

  5. 05

    Attendant

    QR / POS scan

A purchase stays pending until the attendant scans. Paystack retries webhooks, so every credit has to be idempotent.

06Technical decisions

  1. 01

    Pending until the scan

    Purchases stay PENDING_SCAN until the QR completes, so a missed scan never leaves the books.

  2. 02

    Idempotent webhook credits

    Credits are keyed on the Paystack reference and written in a MongoDB transaction after the HMAC check.

  3. 03

    Rate limits on money routes

    Top-up, purchase, and attendant scan have their own limits. Volume is the cheap attack.

  4. 04

    Search in the database

    Proximity, price, and stock come from a 2dsphere index, not a filter in application code.

07Stack

  • React Native
  • Expo Router
  • TypeScript
  • Node.js
  • Express
  • MongoDB
  • Paystack
  • NexGo POS
  • React 19
  • Vite
  • Leaflet

08Verification

Next project

Softfood

Scheduled meals for schools, offices, and organizations.

Want the code open?

I'll walk through the repos and what I'd rebuild.