ZAMACE (via Afrocentec) · Fintech · 2024
Two portals, one shortcode: financial account access on any GSM phone
Full Stack Developer, Afrocentec Zambia · 3–4 weeks

ZAMACE runs Zambia’s agricultural commodity exchange. Its web platform works well, if you have a smartphone and a data bundle. A large share of its market participants have neither. In a three-to-four-week engagement at Afrocentec, I built a USSD gateway (the dial-a-shortcode menus used for airtime and mobile money across the region) that put account services for two portals, ZAMACE and Tradis, on any GSM phone in the country, behind a single shortcode.
The challenge
Reliable internet access in Zambia was estimated at just 21% of the population at the time. The rest, including many of the farmers and traders the exchange exists to serve, carried feature phones. They could participate in the physical commodity market, but they could not check an account balance or confirm that a transaction had settled without borrowing someone’s smartphone.
Two portals needed coverage: ZAMACE itself and Tradis. Running separate USSD services would have meant two shortcode leases, two deployments, and two codebases to maintain for what is substantially the same interaction.
USSD brings its own constraints. Sessions feel stateful to the user but arrive as stateless HTTP callbacks from the gateway. Carriers enforce tight response deadlines and kill idle sessions. Screens are a few lines of plain text. And because this was financial data, the channel’s austerity relaxed none of the security requirements: authentication, lockouts, and audit trails all still had to hold.

A feature phone beside an oil lamp. The whole service had to fit on a screen like this, with no app and no data bundle.
The approach
I built a Laravel (PHP 8.2) middleware sitting between the Africa’s Talking USSD gateway and the existing ZAMACE and Tradis platform APIs.
One shortcode, two portals. The welcome menu asks which portal you belong to; everything downstream is portal-scoped. One deployment and one shortcode lease serve both user bases, and adding a third portal later is a menu entry and an API client, not a new system.
Model the session as a state machine, because it is one. A USSD interaction is inherently a walk through states with numeric transitions. I used the sparors/laravel-ussd package to declare menus and transitions explicitly, rather than reconstructing context from ad-hoc session flags on every request, with Redis holding session state between the gateway’s stateless callbacks.
Financial-grade controls. Users authenticate with a username or account number plus a 4-digit PIN, with a three-attempt lockout. PINs are encrypted and never logged in plain text. Phone numbers are masked to their last four digits in logs. Audit logs are retained for 90 days to meet financial-services compliance requirements.
Fail politely. A circuit breaker fronts the calls to the internal platform APIs. When an upstream service degrades, users see a short plain-language message instead of a hung session or a raw error, and the breaker stops the middleware from hammering an API that is already struggling. The availability target was 99.5%+ during business hours.
The outcome
The gateway shipped within the three-to-four-week window. From any GSM phone on any Zambian network, a ZAMACE or Tradis user can dial the shortcode, authenticate with their PIN, check their account balance, review their last five transactions, and change their PIN through a full verification workflow, all without a data bundle, a smartphone, or an app install.
Both portals run from the single gateway, and the shared audit logging meets the compliance requirements that come with handling financial account data over a public telecom channel.
The adoption goal set at launch was 1,000+ active users within three months. I don’t have post-launch analytics from the client to report against that figure, so it appears here as what it was: the target. What I can state directly is what shipped: two portals on one shortcode, working across every Zambian network, with security controls sized to the money it touches.
USSD is unglamorous, and that is the point. It was the one channel that reached the users the platform was built for. A few weeks of middleware extended a full commodity-exchange platform to the majority of its market that the web version could not reach.