M-Pesa-style USSD menu simulator — session-based state machine with Africa's Talking API compatibility, web phone UI, tiered fees, and PIN verification
# USSD Simulator
When you dial `*334#` on your phone and navigate through menus to send money or buy airtime, there's a backend managing your session, tracking which screen you're on, and processing your input one digit at a time. This project is that backend.
It simulates the full M-Pesa USSD experience with 28 menu screens across 7 flows (send money, withdraw, deposit, buy airtime, check balance, account management, loans). It works with Africa's Talking USSD gateway format out of the box, and includes a browser-based phone simulator for testing.
But beyond the menu navigation, it also handles the things a production USSD system needs: persistent session logging for compliance, transaction logging for dispute resolution, PIN lockout after failed attempts, analytics on which screens users drop off at, and self-service account registration for new phone numbers.
## What It Does
**USSD menu flows:**
- Send money with tiered M-Pesa-style fee calculation and a cumulative
daily transfer limit (default KES 300,000 per phone per UTC day,
configurable via `ussd.daily-transfer-limit`; resets at midnight UTC)
- Withdraw cash at agent
- Deposit to wallet
- Buy airtime (own phone or another number)
- Check balance
- My Account (phone number, change PIN, language, mini/full statement)
- Loans and savings
**Account management:**
- Unregistered phone numbers are automatically redirected to a self-service registration flow
- Users create a 4-digit PIN during registration
- 3 pre-seeded demo accounts for immediate testing
**Security:**
- PIN lockout after 3 consecutive failed attempts, with 15-minute cooldown
- Locked accounts reject all PIN-protected operations until the lockout expires
- Failed attempt counter resets on successful PIN entry
**Persistent logging:**
- Every USSD session is logged to the database: session ID, phone number, screens visited, duration, and outcome (completed vs timed out)
- Every financial transaction is logged: type, amount, fee, counterparty, …