Production platformIn production since February 2026 · sole engineer

PesaFii

A multi-tenant platform for people who sell Wi-Fi: hotspot routers, vouchers, customer payments by mobile money, and the ledger underneath.

PesaFii on a desktop screen
PesaFii on a phone

What it enables

  • Business owners connect MikroTik routers, set prices and sell access from a captive portal.
  • Customers pay with MTN or Airtel mobile money and are let through by the router.
  • Owners run sales, vouchers, agents, wallet and live sessions from a web dashboard or the React Native operator app (16 feature areas).

My contribution

I am the only engineer: the React dashboard, the React Native operator app, the Express API, the PostgreSQL schema and ledger, RADIUS accounting and the router integration.

Engineering decisions

Wi-Fi WireGuard RADIUS accounting mobile money Customer phone captive portal MikroTik router hotspot Server API · FreeRADIUS · workers PostgreSQL ledger · sessions Online MTN · Airtel

Customers could be charged twice

Problem
If the captive portal lost its payment-intent ID mid-flow, initiation could run again and take a second payment.
Decision
Made payment initiation idempotent against the intent, so a retry settles onto the same charge.
Result
A repeated request can no longer create a second charge.

The portal was slow where it mattered most

Problem
Customers on cheap phones and thin signal waited for a package request that started 83.9 KB into the document.
Decision
Moved the request to 2.3 KB into the document and opened DNS, TCP and TLS at parse time with preconnect.
Result
About 330 ms of handshake removed from the critical path, and returning devices paint from cache.

A revoked session could come back

Problem
Caching session validity in Redis makes the hot path fast, and lets a stale “yes” outlive a revocation.
Decision
Fenced revocation so a cached positive can never resurrect a dead session, and reconciled fences at startup.
Result
PostgreSQL stays the only authority on whether a session is valid.

One RADIUS site was a single point of failure

Problem
Every login authorised through one site.
Decision
Brought up a second site and made disconnects site-aware, so a router is reached over the tunnel it is attached to.
Result
Failover verified by taking the primary away, not by reading the configuration.

Stack

  • React
  • React Native · Expo
  • Node · Express
  • PostgreSQL
  • Redis
  • FreeRADIUS
  • MikroTik RouterOS
  • WireGuard

Boundaries

Screens here are from the public website only. The dashboard and app handle real businesses’ data, so they are not shown.