PHPackages                             bmatovu/laravel-ussd - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. bmatovu/laravel-ussd

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

bmatovu/laravel-ussd
====================

Laravel USSD Builder

v2.1.0(1y ago)1537110[5 issues](https://github.com/mtvbrianking/laravel-ussd/issues)MITPHPPHP ^8.1CI passing

Since Jun 20Pushed 1y agoCompare

[ Source](https://github.com/mtvbrianking/laravel-ussd)[ Packagist](https://packagist.org/packages/bmatovu/laravel-ussd)[ Docs](https://github.com/mtvbrianking/laravel-ussd)[ RSS](/packages/bmatovu-laravel-ussd/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (6)Dependencies (9)Versions (7)Used By (0)

[![](./art/banner.png)](./art/banner.png)

[![License](https://camo.githubusercontent.com/670b735118eace6d242d90c59a7a4121d65509cd58640244d90d9178370e0e23/68747470733a2f2f706f7365722e707567782e6f72672f626d61746f76752f6c61726176656c2d757373642f6c6963656e7365)](https://packagist.org/packages/bmatovu/laravel-ussd)[![Unit Tests](https://github.com/mtvbrianking/laravel-ussd/workflows/run-tests/badge.svg)](https://github.com/mtvbrianking/laravel-ussd/actions?query=workflow:run-tests)[![Code Quality](https://camo.githubusercontent.com/de5d4aa9006f6c58bbbd582b5f4ede913512f7dc16fcee51d920e59c0d202d73/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d7476627269616e6b696e672f6c61726176656c2d757373642f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mtvbrianking/laravel-ussd/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/71084d3d5eb2ebf03372423be92dae9e8790c9bac7bd49f5fe57fc627afa6bcf/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d7476627269616e6b696e672f6c61726176656c2d757373642f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mtvbrianking/laravel-ussd/?branch=master)[![Documentation](https://github.com/mtvbrianking/laravel-ussd/workflows/gen-docs/badge.svg)](https://mtvbrianking.github.io/laravel-ussd)

Table of Contents
-----------------

[](#table-of-contents)

- [Overview](#overview)
- [Getting started](#getting-started)
- [Usage](#usage)
    - [Example](#example)
    - [Menu validation](#menu-validation)
    - [Simulator](#simulator)
- [Constructs](#constructs)
    - [Variable](#variable)
    - [Question](#question)
    - [Response](#response)
    - [Options](#options)
    - [If](#if)
    - [Choose](#choose)
    - [Action](#action)
    - [List](#list)
- [Advanced](#advanced)
    - [Exceptions](#exceptions)
    - [Retries](#retries)
    - [Comparisons](#comparisons)
    - [Localization](#localization)
    - [Cache](#cache)
    - [Parser](#parser)
    - [Simulation](#simulation)
    - [JSON](#json)
- [Testing](#testing)
- [Alternatives](#alternatives)

Overview
--------

[](#overview)

Effortlessly construct intricate USSD menus with streamlined efficiency by replacing convoluted nests of PHP files with the simplicity of XML-based menu construction. This approach allows for seamless execution similar to standard PHP scripts, minimizing code complexity and enhancing readability.

Let's explore an example of a simple SACCO USSD application.

```

```

Getting started
---------------

[](#getting-started)

**Installation**

```
composer require bmatovu/laravel-ussd
```

**Publishables**

```
php artisan vendor:publish --provider="Bmatovu\Ussd\UssdServiceProvider"
```

Usage
-----

[](#usage)

### Example

[](#example)

> menus/menu.xml

```

```

> app/Http/Controller/UssdController.php

```
namespace App\Http\Controllers;

use Bmatovu\Ussd\Exceptions\FlowBreakException;
use Bmatovu\Ussd\Ussd;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

/**
 * @see https://developers.africastalking.com/docs/ussd/overview
 */
class UssdController extends Controller
{
    public function __invoke(Request $request): Response
    {
        try {
            $output = Ussd::make('menu.xml', $request->sessionId)->handle($request->text);
        } catch(FlowBreakException $ex) {
            return response('END ' . $ex->getMessage());
        } catch(\Exception $ex) {
            return response('END ' . get_class($ex));
        }

        return response('CON ' . $output);
    }
}
```

> routes/api.php

```
use App\Http\Controllers\UssdController;
use Illuminate\Support\Facades\Route;

Route::post('/ussd', [UssdController::class, '__invoke']);
```

See more examples in the [demo repo](https://github.com/mtvbrianking/ussd-demo/tree/master/app/Http/Controllers/Api)

### Menu validation

[](#menu-validation)

**The Schema**

You can publish the default schema with the following command:

```
php artisan vendor:publish --provider="Bmatovu\Ussd\UssdServiceProvider" --tag="ussd-schema"
```

To ensure your menu files conform to the schema, you can validate them with the following command:

```
php artisan ussd:validate
```

**VSCode integration**

For real-time XSD validations and suggestions, you can use the [RedHat XML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml) in Visual Studio Code. This extension provides helpful features for working with XML schemas, including syntax highlighting and validation.

```

-
+

```

### Simulator

[](#simulator)

The package includes a CLI USSD simulator that supports several popular aggregators.

To get started, publish the simulator configuration file and update it with your aggregator and USSD service endpoint.

```
php artisan vendor:publish --provider="Bmatovu\Ussd\UssdServiceProvider" --tag="ussd-simulator"
```

Usage:

```
./vendor/bin/ussd --help
./vendor/bin/ussd 256772100103
```

**Aggregators**

- Africastalking
- Comviva (Airtel &amp; MTN)

*If your aggregator is not listed, you can request its addition by contacting us or by submitting a pull request.*

Constructs
----------

[](#constructs)

### Variable

[](#variable)

```
$color = 'blue';
```

```

```

**Note**: This tag has no output

### Question

[](#question)

```
$username = readline('Enter username: ');
```

```

```

### Response

[](#response)

```
exit('Thank you for banking with us.');
```

```

```

**Note**: this tag throws a `FlowBreakException` to mark a break in the normal flow.

### Options

[](#options)

Options are like named grouped `if, else-if` statements that allow a user to navigate to a predefined path.

```
$choice = readline('Choose service [1. Deposit, 2. Withdraw]: ');

if($choice === 1) {
    // deposit...
} elseif($choice === 2) {
    // withdraw...
}
```

```

```

**Disable backward navigation**

By default, a `0) Back` option is added to the rendered options. To disable this behaviour, use the `noback` attribute.

Note: *Top-level options should use the `noback` attribute as there’s no previous level to return to.*

```

```

### If

[](#if)

It can contain any other tags, including nested `` tags.

```
if($role == 'treasurer') {
    // ...
}
```

```

```

### Choose

[](#choose)

This construct is intended to handle scenarios typically covered by `if`, `else if`, `else`, and `switch` statements.

**Example #1**

```
if($role == 'treasurer') {
    // ...
} else {
    // ...
}
```

```

```

**Example #2**

```
if($role == 'treasurer') {
    // ...
} elseif($role == 'member') {
    // ...
} else {

}
```

```

```

**Example #3**

```
switch ($role) {
    case "treasurer":
        // ...
        break;
    case "member":
        // ...
        break;
    default:
        // ...
}
```

```

```

### Action

[](#action)

Action tags enable you to execute more tailored operations.

```
$userInfo = \App\Ussd\Actions\GetUserInfoAction('256732000000');
```

**Arguments**

You can provide arguments for these actions either through attributes or by defining variables.

```

```

**Getting user input**

When the `text` attribute is included in an action tag, it prompts the user for input in the same way that a `` tag would.

```

```

### List

[](#list)

Lists are designed to show dynamic items.

To use this feature, your provider must supply a list where each item includes both an `id` (a unique identifier) and a `label` (the text displayed to the user).

```
$listItems = (new \App\Ussd\Providers\SavingAccountsProvider)->load();

[
    [
        'id' => 4364852, // account_id
        'label' => '01085475262', // account_number
    ],
];
```

```

```

Accessing the selected item on the list

```

```

**Note**: Similar to actions, you can pass arguments to lists via attributes or as variables.

Advanced
--------

[](#advanced)

### Exceptions

[](#exceptions)

The `` tag throws a `FlowBreakException` which MUST be handled in your controller to manage the flow of the USSD interaction.

Additionally, you can catch other exceptions and optionally translate them into user-friendly messages, as demonstrated below...

```
try {
    $output = Ussd::make('menu.xml', $request->session_id)
        ->handle($request->text);
} catch(FlowBreakException $ex) {
    return response('END ' . $ex->getMessage());
} catch(\Exception $ex) {
    // return response('END ' . get_class($ex));
    return response('END ' . trans(get_class($ex)));
}

return response('CON ' . $output);
```

> resources/lang/en.json

```
{
    "RequestException": "Sorry, we failed to process your request.",
    "TimeoutException": "Your request has timed out.",
    "AuthenticationException": "Invalid user credentials.",
    "AuthorizationException": "You are not authorized to perform this action."
}
```

Note: *To minimize logging, the FlowBreakException should not be reported by your application. [Ref](https://laravel.com/docs/11.x/errors#ignoring-exceptions-by-type)*

### Retries

[](#retries)

You can also configure the number of retry attempts and specify a custom error message.

**Question**

Using regex patterns.

```

```

**Options &amp; Lists**

Validation can also be performed based on the available options in the list.

```

      ...

```

```

```

**Note**: Using retries in `` tags is not recommended because these tags do not have visibility into the context provided by preceding tags.

### Comparisons

[](#comparisons)

The `` and `` tags support various types of comparisons.

If a comparison condition (`cond`) is not specified or is unsupported, the default comparison is `eq` (equals)

```

```

TypeConditionsNumbers- lt
- gt
- lte
- gte
- eq
- ne
- btnStrings- str.equals
- str.not\_equals
- str.starts
- str.ends
- str.containsRegex- regex.matchArrays- arr.in
- arr.not\_inDates- date.equals
- date.before
- date.after
- date.betweenTime- time.equals
- time.before
- time.after
- time.between### [Localization](https://laravel.com/docs/11.x/localization)

[](#localization)

Create translation files within your project and reference the keys in your menu files. Here’s an example:

> menus/menu.xml

```

```

> resources/lang/fr.json

```
{
    "AskForName": "Entrez le nom:",
    "GreetGuest": "Boujour {{guest}}"
}
```

> USSD simulation

```
ussd-demo$ vendor/bin/ussd 250723000123
Entrez le nom:
John

Boujour John

```

**Note**:

- use the `set_locale` action to change locale directly from the USSD menu, and
- use `App::setLocale` to change the locale from your controller

### Cache

[](#cache)

This package stores USSD session data in the cache. Each key is prefixed with the `session_id` and will automatically expire based on the configured `ttl` (time-to-live).

**Accessing variables**

```

```

```
$this->store->get('color'); // blue

Cache::store($driver)->get("{$sessionId}color"); // blue
```

**Reusing existing variables**

```

```

### Parser

[](#parser)

**Save default variables**

Here's an example of how to save a variable from an incoming USSD request:

```
Ussd::make($menu, $request->session_id)
    ->save([
        'phone_number' => $request->phone_number,
    ])
    ->handle(...);
```

**Use custom menu entry point**

By default, parsing begins at the first element in your menu file, which corresponds to `/menu/*[1]`.

If you want to start parsing from a different point or use a custom menu structure, you can specify the entry point in your code:

```
Ussd::make($menu, $request->session_id)
    ->entry("/menus/menu[@name='sacco']/*[1]")
    ->handle(...);
```

See: [xpath playground](http://xpather.com)

### Simulation

[](#simulation)

You can enhance the USSD simulator by adding your preferred aggregator.

To do this, register the aggregator in the simulator configuration file. Ensure that the provider class implements the `Bmatovu\Ussd\Contracts\Aggregator` interface.

> simulator.json

```
  {
+     "aggregator": "africastalking",
      "aggregators": {
+         "africastalking": {
+             "provider": "App\\Ussd\\Simulator\\Africastalking",
+             "uri": "http://localhost:8000/api/ussd",
+             "service_code": "*123#"
+         }
      }
  }
```

### JSON

[](#json)

XML is often preferred for constructing configurations that resemble programming logic due to its robust schema validation capabilities and its clear, hierarchical structure. XML’s format is particularly useful for complex configurations and data structures, as it maintains readability and provides straightforward validation against defined schemas.

```

```

```
{
    "@name": "demo",
    "question": {
        "@name": "guest",
        "@text": "Enter Name:"
    },
    "response": {
        "@text": "Hello {{guest}}."
    }
}
```

Testing
-------

[](#testing)

To run the package's unit tests, run the following command:

```
composer test
```

Alternatives
------------

[](#alternatives)

- [sparors/laravel-ussd](https://github.com/sparors/laravel-ussd) offers a different approach to building USSD menus.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance37

Infrequent updates — may be unmaintained

Popularity26

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 99.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~195 days

Recently: every ~244 days

Total

6

Last Release

446d ago

Major Versions

v1.2.0 → v2.0.02024-08-18

PHP version history (2 changes)v1.0.0PHP ^7.4|^8.0

v2.0.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/0cc99b58d12a288f0fd19099cc3c724ff4df84d978df0e7451b650e8182bc919?d=identicon)[bmatovu](/maintainers/bmatovu)

---

Top Contributors

[![mtvbrianking](https://avatars.githubusercontent.com/u/5412360?v=4)](https://github.com/mtvbrianking "mtvbrianking (163 commits)")[![elissaihimbazwe](https://avatars.githubusercontent.com/u/82683808?v=4)](https://github.com/elissaihimbazwe "elissaihimbazwe (1 commits)")

---

Tags

laravelmenuphpussdxmllaravelxmlpackagelumenbuildermenuussd

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/bmatovu-laravel-ussd/health.svg)

```
[![Health](https://phpackages.com/badges/bmatovu-laravel-ussd/health.svg)](https://phpackages.com/packages/bmatovu-laravel-ussd)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k43.5M5.2k](/packages/larastan-larastan)[bmatovu/laravel-xml

Laravel XML Support

91270.4k](/packages/bmatovu-laravel-xml)[erlandmuchasaj/laravel-gzip

Gzip your responses.

40129.3k2](/packages/erlandmuchasaj-laravel-gzip)[ultrono/laravel-sitemap

Sitemap generator for Laravel 11, 12 and 13

36412.6k6](/packages/ultrono-laravel-sitemap)[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)[buzzylab/laradown

A New Markdown parser for Laravel built on parsedown

317.3k](/packages/buzzylab-laradown)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
