JustTap
USSD

Vendor Application Design

Design a reliable, stateful USSD journey behind a stateless HTTP endpoint.

Vendor Application Design

Use a stateless HTTP service and a shared state store such as Redis or a database. A continuation can reach another instance after a deployment or load-balancer decision, so process memory is not a production session store.

Example vendor-side menu state machine
Example vendor-side menu state machineA new session begins at the main menu, moves through input collection and confirmation, then ends with either a cancelled or completed outcome. Invalid entries loop back to the current step.New sessionMain menuCollect inputConfirmationEnd: cancelledEnd: outcomenewSession=truevalid optionvalid input2 or 01: idempotent operationinvalid entryinvalid input

Store the current step

For a new session, create the journey and return the first menu. For a continuation, load its state by sessionId, interpret userInput in the context of the current step, atomically save the transition, and return the next menu or final message.

{
  "sessionId": "demo-session-001",
  "step": "main_menu",
  "data": {},
  "status": "active"
}

These are application fields, not fields to return to Just-tap. Use atomic updates or transactions so concurrent requests cannot overwrite state. An invalid selection is expected customer input: retain the step and return Continue with a useful prompt. Treat userInput as a string because leading zeroes can be significant.

Handle expiry and missing state

Set state expiry slightly longer than the gateway's 180-second inactivity window and refresh it for valid interactions. If a continuation has no usable state, end safely rather than attempting an operation:

{
  "sessionState": "End",
  "message": "Your session has expired. Please dial again to start a new session."
}

Do not rely on a final request when a customer abandons a session; use expiry for cleanup. Do not execute a business operation if information needed to validate the current step is missing.

Prevent duplicate operations

Requests may be retried. For every irreversible payment, registration, or order, create a durable operation record using a stable key derived from the session and logical action. Enforce uniqueness atomically, and return the recorded outcome if the operation is repeated. Keep operation records separate from temporary menu state: session cleanup must not erase evidence of a completed operation.

If a session supports more than one operation, give each one a distinct identity. A key alone is not enough; the database or store must enforce its uniqueness and downstream systems should use idempotency support where available.

To confirm before publication: Specify retry conditions and timing, whether webhook-id is reused, and how duplicate new-session or terminal requests are delivered.

Stay within the deadline

The gateway deadline is 10 seconds. Configure dependency timeouts so your application can still form a response. When an outcome is uncertain, do not claim success or failure: provide a safe pending or recovery journey. Return a valid End response when safe; otherwise the gateway's generic fallback applies.

On this page