Download the PHP package moffhub/ussd without Composer
On this page you can find all versions of the php package moffhub/ussd. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package ussd
Short Description Enterprise USSD framework for Laravel. Multi-provider support (Safaricom, Airtel, MTN), session management, menu builders, form collection, pagination, security, analytics, and i18n for African mobile networks.
License MIT
Homepage https://github.com/moffhub/ussd
Informations about the package ussd
Moffhub USSD Framework
A powerful, enterprise-grade Laravel package for building scalable USSD applications with support for multiple African mobile network providers.
Features
- Multi-Provider Support: Built-in adapters for Safaricom/Africa's Talking, Airtel, MTN, and a generic fallback
- Menu System: Simple menus, forms, paginated lists, conditional menus, and multi-step wizards
- Session Management: Intelligent session recovery, grace periods, and context preservation
- Security: Rate limiting, input sanitization, audit logging, and blacklist/whitelist support
- Analytics: Track user journeys, menu interactions, and performance metrics
- Caching: Efficient caching layer for menus and data providers
- Data Providers: Pluggable data sources (Array, Database, API)
Requirements
- PHP 8.4+
- Laravel 12.0+
Installation
Publish the configuration file:
Run migrations (optional, for session persistence and analytics):
Quick Start
1. Create a USSD Controller
2. Register the Route
Menu Types
SimpleMenu
Basic menu with numbered options:
FormMenu
Collect multi-step form data:
PaginatedMenu
Display large lists with pagination:
ConditionalMenu
Show different menus based on conditions:
WizardMenu
Multi-step guided processes:
Using the MenuBuilder
Fluent interface for building menus:
Type-Safe Menu Names with Enums
For better type safety and IDE autocomplete, use enums for menu names:
Creating Your Menu Enum
Using Your Enum
Provider Adapters
The framework automatically detects the USSD provider from the request, or you can specify one:
Supported Providers
| Provider | Aliases | Field Mapping |
|---|---|---|
| Safaricom | safaricom, africas_talking, at |
phoneNumber, text, sessionId |
| Airtel | airtel |
msisdn, input/text, transactionId |
| MTN | mtn |
msisdn, UserAnswer, sessionId |
| Generic | generic |
Auto-detect multiple field names |
Register Custom Provider
Data Providers
ArrayDataProvider
DatabaseDataProvider
ApiDataProvider
Session Management
Accessing Session Data
Session Recovery
The framework automatically handles session recovery:
Security Features
Rate Limiting
Database-Backed Whitelist/Blacklist
For production applications, use database-backed access lists that can be managed via a UI:
Using the UssdAccessList Model Directly
Build your own admin UI using the Eloquent model:
Custom Access List Provider
Implement your own storage backend:
Input Sanitization
Validators
Built-in validators for form fields:
Response Types
Configuration
Full configuration options:
Publishing the config
This writes config/ussd.php. The published file is the authoritative control
surface: framework defaults are deep-merged with config('ussd') and then with
any array passed to new UssdFramework([...]) (nearest wins, nested blocks merge
recursively rather than replacing wholesale).
Config reference (selected keys)
| Key | Env var | Default | Purpose |
|---|---|---|---|
debug |
USSD_DEBUG |
false |
Rethrow menu exceptions instead of the generic error (dev/test). |
validate_menu_references |
USSD_VALIDATE_MENU_REFERENCES |
true |
UssdBuilder::build() fails fast on navigation to an unregistered menu. |
deduplication.enabled |
USSD_DEDUPE_ENABLED |
true |
Replay the cached response for a retried (session, input). |
deduplication.window |
USSD_DEDUPE_WINDOW |
5 |
Dedupe window, in seconds. |
session_timeout |
USSD_SESSION_TIMEOUT |
300 |
Inactivity (seconds) before a session expires; also the sweeper's default. |
security.rate_limiting |
USSD_RATE_LIMITING_ENABLED |
true |
Enable the rate limiter. |
rate_limiting.max_requests_per_minute |
USSD_RATE_LIMIT_PER_MINUTE |
60 |
Per-minute request cap (tuned for interactive menus). |
rate_limiting.max_requests_per_hour |
USSD_RATE_LIMIT_PER_HOUR |
600 |
Per-hour request cap. |
rate_limiting.max_requests_per_day |
USSD_RATE_LIMIT_PER_DAY |
3000 |
Per-day request cap. |
rate_limiting.use_database_lists |
USSD_RATE_LIMIT_USE_DATABASE_LISTS |
true |
Use the DB-backed whitelist/blacklist (needs the ussd_access_lists table). |
database.enabled |
USSD_DATABASE_ENABLED |
true |
Enable the database layer (sessions, analytics, stats). |
Session tables
Two tables, different jobs:
ussd_user_sessionsis the runtime session store: one row per live/finished session (menu, session data, activity timestamps, completion). This is what the cleanup and sweeper commands operate on, and what you query for live sessions.ussd_sessionsis used by access-management/admin tooling, not the normal request path, so it is empty in a plain menu deployment. If you are looking for "where are my sessions", it isussd_user_sessions.
Debugging: surface the real error
By default the framework catches menu exceptions and returns a generic message.
Set debug (or USSD_DEBUG=true) to rethrow the underlying exception so you see
the real cause in dev/test. The on_error hook fires either way:
Swapping components
Rate limiter, input sanitizer, audit logger and the session store resolve from the container. Bind your own to replace the default without forking:
Or via the builder:
Typed config access
getConfig() still returns the raw array. config() additionally gives a typed,
immutable view with dot-notation and a recursive merge() (so a partial override
never wipes sibling keys):
Metrics
Bind MetricsRecorderInterface to receive funnel metrics (menu entered,
completed, abandoned, dwell). Everything is keyed by menu only (never by phone
or session) to keep cardinality bounded. The default is a no-op.
Testing menus
UssdTester drives a session without a gateway and with test-friendly defaults:
Facade
Use the Ussd facade for convenient access:
Internationalization (i18n)
Built-in multi-language support:
Publish and customize language files:
Configure in config/ussd.php:
Signature Verification
Verify incoming provider requests using HMAC signatures:
Circuit Breaker
Protect external API calls from cascading failures:
The circuit breaker is automatically integrated into ApiDataProvider. It supports three states:
- Closed: All requests pass through normally
- Open: Requests return fallback data (after threshold failures)
- Half-open: One test request allowed after cooldown period
Session Encryption
Encrypt sensitive session data at rest:
Configure which fields to encrypt in config/ussd.php:
Events
The framework dispatches Laravel events at key lifecycle points:
| Event | Payload |
|---|---|
SessionStarted |
sessionId, phone, provider |
SessionResumed |
sessionId, phone, wasRecovered |
SessionEnded |
sessionId, phone, duration, menusVisited |
SessionExpired |
sessionId, phone, lastMenu |
MenuEntered |
sessionId, menuName, fromMenu |
MenuExited |
sessionId, menuName, toMenu, selection |
FormSubmitted |
sessionId, menuName, formData |
InputReceived |
sessionId, menuName, rawInput |
NavigationPerformed |
sessionId, action |
Listen to events:
Artisan Commands
Middleware
Two middleware are registered automatically:
Production Deployment
See docs/PRODUCTION.md for a detailed production deployment guide including:
- Deployment checklist
- Cache driver selection (Redis recommended)
- Database migration verification
- Provider credential setup
- Rate limit tuning
- Session timeout configuration
- Analytics retention policy
- Performance tuning guide
- Troubleshooting guide
Quick Checklist
- [ ] Set cache driver to Redis:
CACHE_DRIVER=redis - [ ] Run migrations:
php artisan migrate - [ ] Configure provider secrets in
.env - [ ] Enable signature verification:
USSD_VERIFY_SIGNATURES=true - [ ] Enable session encryption if handling PINs:
USSD_ENCRYPT_SESSION_DATA=true - [ ] Schedule session cleanup:
ussd:cleanup-sessions - [ ] Start queue worker for async analytics:
USSD_ANALYTICS_FLUSH_STRATEGY=async - [ ] Configure gateway IPs:
USSD_GATEWAY_AUTH_ENABLED=true - [ ] Verify health:
php artisan ussd:health
Local Development
USSD Simulator
Test your USSD flows interactively from the command line without needing a real gateway:
This starts an interactive CLI session that simulates a USSD flow. It sends requests to your registered menus, displays responses, and prompts for input just like a real USSD session.
Options
How It Works
- The simulator generates a unique session ID and sends an initial request to
UssdFramework::handle() - The response is displayed in the terminal with
[CON](continue) or[END](end) indicators - If the response is
CON, you are prompted to enter input - The simulator sends a follow-up request with your input
- This loop continues until the response is
ENDor you typeexit - A session summary is displayed at the end with total steps and duration
Testing
Run the test suite:
Or with PHPUnit directly:
Contributing
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Submit a pull request
License
This package is open-sourced software licensed under the MIT license.
Credits
All versions of ussd with dependencies
laravel/framework Version ^12.0 || ^13.0
sourcetoad/enhanced-resources Version ^7.3
sourcetoad/rule-helper-for-laravel Version ^6.3