Afrocentec (for The Booth Marketing) · Marketing Tech · Dec 2025 – Jan 2026

Any phone, no data: a USSD campaign gateway shipped in 7 days

7 days

Kickoff to production measured result

<500ms

Avg response in testing my estimate

3/3

Zambian networks covered measured result

In December 2025, Afrocentec asked me to build the entry mechanism for a bottle-top promotional campaign they were running for The Booth Marketing in Zambia. Buyers find a code under the bottle top; entering it puts them in a prize draw. The draw date (15 January 2026) was already committed, the budget was a K6,000 fixed price, and the entry channel had to work for everyone, including people on basic handsets with no data bundle. I scoped, built, and shipped a USSD gateway in seven days: user acceptance testing on 2 January, production on 10 January, draw on schedule on 15 January.

The challenge

A web form or an app would have excluded a large part of the campaign’s actual audience. Many Zambian mobile users are on basic GSM phones without reliable smartphone data access, and a promotion only smartphone owners can enter is a smaller promotion. USSD, the dial-a-shortcode menus used for airtime and mobile money across the region, works on every GSM handset with zero data. That made it the right channel, but it comes with hard constraints:

  • Each screen is limited to 160 characters, so menus must be terse and unambiguous.
  • Carriers expect a response within roughly 2 seconds; slower than that and sessions start dropping mid-entry.
  • The gateway had to behave identically on all three Zambian networks: Airtel, MTN, and Zamtel.

There was also an architectural constraint I wanted to respect rather than fight: the campaign logic for code validation, prize fulfillment, and campaign rules already existed in Afrocentec’s backend. Rebuilding any of it in the gateway would have doubled the work and created two places for the rules to disagree.

A feature phone lying on a wooden counter beside an oil lamp

A feature phone by lamplight. The draw ran over USSD so that any handset like this one could enter.

The approach

I built the gateway as a thin presentation layer between the USSD provider and the existing backend API, and deliberately nothing more.

Provider abstraction. Africa’s Talking handles the carrier connections, but I wrapped it behind an adapter so the provider can be swapped without touching anything else. If a future campaign runs on a different aggregator, the menus and session handling don’t change.

Sessions in Redis. USSD is stateless between screens, so the gateway keeps session state in Redis with a 180-second TTL matched to USSD session lifetimes. Expired sessions clean themselves up; nothing accumulates.

Menus within the limit. Every screen is composed to fit the 160-character ceiling, including error states. Timeouts, invalid codes, and backend failures each get a plain message telling the user what to do next, instead of a dead session.

Business logic stays put. The gateway validates nothing itself; it forwards entries to the backend API and renders the result. That separation is what made a seven-day build honest rather than reckless: the surface area I had to get right was small, and it was testable in isolation.

The stack was Node.js 20, TypeScript, Express, and Redis, packaged in Docker. Boring on purpose: a fixed-price, fixed-deadline build is the wrong place for anything I’d be debugging for the first time.

The outcome

The gateway went to production on 10 January 2026, five days ahead of the draw, and the campaign ran on schedule. Anyone with a GSM phone on Airtel, MTN, or Zamtel could dial in and enter a code. No smartphone, no data bundle, no app install.

In my testing, responses averaged under 500 milliseconds, about four times inside the 2-second budget carriers allow before sessions get flaky. I label that figure representative because it is my own benchmark, not a carrier-audited production measurement; what I can say plainly is that the design target was met before launch and sessions held up through acceptance testing.

The engagement came in at the agreed K6,000 fixed price, kickoff to production in one week. And because the gateway owns no campaign logic, it isn’t disposable: pointing it at a different campaign backend is configuration work, not a rebuild. The Booth Marketing got a promotion that anyone with a phone could enter, and Afrocentec kept a reusable entry channel for whatever they run next.