PHPackages                             smodav/mpesa - 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. [API Development](/categories/api)
4. /
5. smodav/mpesa

ActiveLibrary[API Development](/categories/api)

smodav/mpesa
============

M-Pesa API implementation

v7.0.0(2mo ago)16363.7k—6.6%134[1 PRs](https://github.com/SmoDav/mpesa/pulls)1MITPHPPHP &gt;=8.2

Since Jul 30Pushed 2mo ago21 watchersCompare

[ Source](https://github.com/SmoDav/mpesa)[ Packagist](https://packagist.org/packages/smodav/mpesa)[ RSS](/packages/smodav-mpesa/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (53)Used By (1)

M-PESA API Package
==================

[](#m-pesa-api-package)

[![Build Status](https://camo.githubusercontent.com/17960f8b96d4a0552b939bc4fb7e54cd919f1fc8b5fdbafd410f5b9e49f5d5af/68747470733a2f2f7472617669732d63692e6f72672f536d6f4461762f6d706573612e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/SmoDav/mpesa)[![Total Downloads](https://camo.githubusercontent.com/47e6105fbcd2a6ce5f386e2a5a74c74c9aa9ff0baffb99e03f1ea8823181c5fc/68747470733a2f2f706f7365722e707567782e6f72672f736d6f6461762f6d706573612f642f746f74616c2e737667)](https://packagist.org/packages/smodav/mpesa)[![Latest Stable Version](https://camo.githubusercontent.com/5edba5c1f9f651029c75662d25d4d5dec1271fd5b0eda25390b89a866b397cb2/68747470733a2f2f706f7365722e707567782e6f72672f736d6f6461762f6d706573612f762f737461626c652e737667)](https://packagist.org/packages/smodav/mpesa)[![Latest Unstable Version](https://camo.githubusercontent.com/6644ef424f48e0a6fc0fcb23168c1613c1a65fc1fb79629951d6bf14b922b81f/68747470733a2f2f706f7365722e707567782e6f72672f736d6f6461762f6d706573612f762f756e737461626c652e737667)](https://packagist.org/packages/smodav/mpesa)[![License](https://camo.githubusercontent.com/2978eda1c7544a65a430bec7aedcda719267eef21069f22e816f64e51b00fdad/68747470733a2f2f706f7365722e707567782e6f72672f736d6f6461762f6d706573612f6c6963656e73652e737667)](https://packagist.org/packages/smodav/mpesa)

This is a PHP package for the Safaricom's M-Pesa API. The API allows a merchant to initiate C2B online checkout (paybill via web) transactions. The merchant submits authentication details, transaction details, callback url and callback method.

After request submission, the merchant receives instant feedback with validity status of their requests. The C2B API handles customer validation and authentication via USSD push. The customer then confirms the transaction. If the validation of the customer fails or the customer declines the transaction, the API makes a callback to merchant. Otherwise the transaction is processed and its status is made through a callback.

If you enjoy using this package, please take a moment and [buy me some coffee.](https://rave.flutterwave.com/donate/fiqyumudlt6t)

Installation
------------

[](#installation)

Pull in the package through Composer.

### Native Addon

[](#native-addon)

When using vanilla PHP, modify your `composer.json` file to include:

```
  "scripts": {
    "post-update-cmd": [
        "SmoDav\\Mpesa\\Support\\Installer::install"
    ]
  },
```

This script will copy the default configuration file to a config folder in the root directory of your project. Now proceed to require the package.

### General Install

[](#general-install)

Run `composer require smodav/mpesa` to get the latest stable version of the package.

Migration from previous versions
--------------------------------

[](#migration-from-previous-versions)

v5 of the package changes the implementation and introduces some breaking changes. Please have a look at the [CHANGELOG](https://github.com/SmoDav/mpesa/blob/master/CHANGELOG.md).

v4 of this package uses a new configuration setup. You will need to update your config file in order to upgrade v3 to v4. v2 is still incompatible since it uses the older API version.

### Laravel

[](#laravel)

When using Laravel 5.5+, the package will automatically register. For laravel 5.4 and below, include the service provider and its alias within your `config/app.php`.

```
'providers' => [
    SmoDav\Mpesa\Laravel\ServiceProvider::class,
],

'aliases' => [
    'STK'       => SmoDav\Mpesa\Laravel\Facades\STK::class,
    'Simulate'  => SmoDav\Mpesa\Laravel\Facades\Simulate::class,
    'Registrar' => SmoDav\Mpesa\Laravel\Facades\Registrar::class,
    'Identity'  => SmoDav\Mpesa\Laravel\Facades\Identity::class,
],
```

Publish the package specific config using:

```
php artisan vendor:publish
```

### Other Frameworks

[](#other-frameworks)

To implement this package, a configuration repository is needed, thus any other framework will need to create its own implementation of the `ConfigurationStore` and `CacheStore` interfaces.

### Configuration

[](#configuration)

The package allows you to have multiple accounts. Each account will have its specific credentials and endpoints that are independent of the rest. You will be required to set the default account to be used for all transactions, which you can override on each request you make. The package comes with two default accounts that you can modify.

```
/*
|--------------------------------------------------------------------------
| Default Account
|--------------------------------------------------------------------------
|
| This is the default account to be used when none is specified.
*/

'default' => 'staging',

/*
|--------------------------------------------------------------------------
| File Cache Location
|--------------------------------------------------------------------------
|
| When using the Native Cache driver, this will be the relative directory
| where the cache information will be stored.
*/

'cache_location' => '../cache',

/*
|--------------------------------------------------------------------------
| Accounts
|--------------------------------------------------------------------------
|
| These are the accounts that can be used with the package. You can configure
| as many as needed. Two have been setup for you.
|
| Sandbox: Determines whether to use the sandbox, Possible values: sandbox | production
| Initiator: This is the username used to authenticate the transaction request
| LNMO:
|    shortcode: The till number
|    passkey: The passkey for the till number
|    callback: Endpoint that will be be queried on completion or failure of the transaction.
|
*/

'accounts' => [
    'staging' => [
        'sandbox' => true,
        'key' => 'your development consumer key',
        'secret' => 'your development consumer secret',
        'initiator' => 'your development username',
        'id_validation_callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        'lnmo' => [
            'paybill' => 'your development paybill number',
            'shortcode' => 'your development business code',
            'passkey' => 'your development passkey',
            'callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        ]
    ],

    'paybill_1' => [
        'sandbox' => false,
        'key' => 'your production consumer key',
        'secret' => 'your production consumer secret',
        'initiator' => 'your production username',
        'id_validation_callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        'lnmo' => [
            'paybill' => 'your production paybill number',
            'shortcode' => 'your production business code',
            'passkey' => 'your production passkey',
            'callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        ]
    ],

    'paybill_2' => [
        'sandbox' => false,
        'key' => 'your production consumer key',
        'secret' => 'your production consumer secret',
        'initiator' => 'your production username',
        'id_validation_callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        'lnmo' => [
            'paybill' => 'your production paybill number',
            'shortcode' => 'your production business code',
            'passkey' => 'your production passkey',
            'callback' => 'http://example.com/callback?secret=some_secret_hash_key',
        ]
    ],
],

```

You can add as many accounts as required and switch the connection using the method `usingAccount` on `STK`, `Register` and `Simulate` as shown below.

Also, note the difference between the `business shortcode` and your `paybill number` in the configuration as getting them wrong will cost you a lot of time debugging.

Usage
-----

[](#usage)

For Vanilla PHP you will need to initialize the core engine before any requests as shown below. The package comes with a vanilla php implementation of the cache and configuration store, `NativeCache` and `NativeConfig`.

The `NativeConfig` receives the custom location for the configuration file to be used as the first constructor argument. If no value is passed when creating the instance, it will use the default configuration and look for a configuration file on the root of the project under `configs` directory.

The `NativeCache` receives a custom directory path as the first constructor argument. The path denotes where the cache should store its files. If no path is provided, the default cache location in the config will be used.

```
use GuzzleHttp\Client;
use SmoDav\Mpesa\Engine\Core;
use SmoDav\Mpesa\Native\NativeCache;
use SmoDav\Mpesa\Native\NativeConfig;

require "vendor/autoload.php";

$config = new NativeConfig();
$cache = new NativeCache($config->get('cache_location'));
// or
$cache = new NativeCache(__DIR__ . '/../some/awesome/directory');

$core = new Core(new Client, $config, $cache);
```

### URL Registration

[](#url-registration)

#### submit(shortCode = null, confirmationURL = null, validationURL = null, onTimeout = 'Completed|Cancelled', account = null)

[](#submitshortcode--null-confirmationurl--null-validationurl--null-ontimeout--completedcancelled-account--null)

Register callback URLs

##### Vanilla

[](#vanilla)

```
use SmoDav\Mpesa\C2B\Registrar;

$conf = 'http://example.com/mpesa/confirm?secret=some_secret_hash_key';
$val = 'http://example.com/mpesa/validate?secret=some_secret_hash_key';

$response = (new Registrar($core))->register(600000)
    ->onConfirmation($conf)
    ->onValidation($val)
    ->submit();

/****** OR ********/
$response = (new Registrar($core))->submit(600000, $conf, $val);
```

When having multiple accounts, switch using the `usingAccount` method. We currently have `staging`, `paybill_1` and `paybill_2` with `staging` as the default:

```
$response = (new Registrar($core))
    ->register(600000)
    ->usingAccount('paybill_1')
    ->onConfirmation($conf)
    ->onValidation($val)
    ->submit();

/****** OR ********/
$response = (new Registrar($core))->submit(600000, $conf, $val, null, 'paybill_1');
```

##### Laravel

[](#laravel-1)

```
use SmoDav\Mpesa\Laravel\Facades\Registrar;

$conf = 'http://example.com/mpesa/confirm?secret=some_secret_hash_key';
$val = 'http://example.com/mpesa/validate?secret=some_secret_hash_key';

$response = Registrar::register(600000)
    ->onConfirmation($conf)
    ->onValidation($val)
    ->submit();

/****** OR ********/
$response = Registrar::submit(600000, $conf, $val);
```

Using the `paybill_1` account:

```
use SmoDav\Mpesa\Laravel\Facades\Registrar;

$response = Registrar::register(600000)
    ->usingAccount('paybill_1')
    ->onConfirmation($conf)
    ->onValidation($val)
    ->submit();

/****** OR ********/
$response = Registrar::submit(600000, $conf, $val, null, 'paybill_1');
```

### Simulate Transaction

[](#simulate-transaction)

#### push(amount = null, number = null, reference = null, account = null, command = null)

[](#pushamount--null-number--null-reference--null-account--null-command--null)

Initiate a C2B simulation transaction request.

Note that when initiating a C2B simulation, setting the command type is optional and by default `CustomerPaybillOnline`will be used.

##### Vanilla

[](#vanilla-1)

```
use SmoDav\Mpesa\C2B\Simulate;

$simulate = new Simulate($core)

$response = $simulate->request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->push();

/****** OR ********/
$response = $simulate->push(10, 254722000000, 'Some Reference');
```

Using the `paybill_1` account:

```
$response = $simulate->request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->usingAccount('paybill_1')
    ->push();

/****** OR ********/
$response = $simulate->push(10, 254722000000, 'Some Reference', 'paybill_1');
```

Using the `CustomerBuyGoodsOnline` command:

```
$response = $simulate->request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->setCommand(CUSTOMER_BUYGOODS_ONLINE)
    ->push();

/****** OR ********/
$response = $simulate->push(10, 254722000000, 'Some Reference', null, CUSTOMER_BUYGOODS_ONLINE);
```

##### Laravel

[](#laravel-2)

```
use SmoDav\Mpesa\Laravel\Facades\Simulate;

$response = Simulate::request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->push();

/****** OR ********/
$response = Simulate::push(10, 254722000000, 'Some Reference');
```

Using the `paybill_1` account:

```
use SmoDav\Mpesa\Laravel\Facades\Simulate;

$response = Simulate::request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->usingAccount('paybill_1')
    ->push();

/****** OR ********/
$response = Simulate::push(10, 254722000000, 'Some Reference', 'paybill_1');
```

Using the `CustomerBuyGoodsOnline` command:

```
use SmoDav\Mpesa\Laravel\Facades\Simulate;

$response = Simulate::request(10)
    ->from(254722000000)
    ->usingReference('Some Reference')
    ->setCommand(CUSTOMER_BUYGOODS_ONLINE)
    ->push();

/****** OR ********/
$response = Simulate::push(10, 254722000000, 'Some Reference', null, CUSTOMER_BUYGOODS_ONLINE);
```

### STK PUSH

[](#stk-push)

#### push(amount = null, number = null, reference = null, description = null, account = null, command = null)

[](#pushamount--null-number--null-reference--null-description--null-account--null-command--null)

Initiate a C2B STK Push request.

Note that when initiating an STK Push, setting the command type is optional and by default `CustomerPaybillOnline`will be used.

##### Vanilla

[](#vanilla-2)

```
use SmoDav\Mpesa\C2B\STK;

$stk = new STK($core);

$response = $stk->request(10)
    ->from(254722000000)
    ->usingReference('Some Reference', 'Test Payment')
    ->push();

/****** OR ********/
$response = $stk->push(10, 254722000000, 'Some Reference', 'Test Payment');
```

Using the `paybill_2` account:

```
$response = $stk->request(10)
    ->from(254722000000)
    ->usingAccount('paybill_2')
    ->usingReference('Some Reference', 'Test Payment')
    ->push();

/****** OR ********/
$response = $stk->push(10, 254722000000, 'Some Reference', 'Test Payment', 'paybill_2');
```

Using `CustomerBuyGoodsOnline` command:

```
$response = $stk->request(10)
    ->from(254722000000)
    ->usingReference('Some Reference', 'Test Payment')
    ->setCommand(CUSTOMER_BUYGOODS_ONLINE)
    ->push();

/****** OR ********/
$response = $stk->push(10, 254722000000, 'Some Reference', 'Test Payment', null, CUSTOMER_BUYGOODS_ONLINE);
```

##### Laravel

[](#laravel-3)

```
use SmoDav\Mpesa\Laravel\Facades\STK;

$response = STK::request(10)
    ->from(254722000000)
    ->usingReference('Some Reference', 'Test Payment')
    ->push();

/****** OR ********/
$response = STK::push(10, 254722000000, 'Some Reference', 'Test Payment');
```

Using the `paybill_2` account:

```
use SmoDav\Mpesa\Laravel\Facades\STK;

$response = STK::request(10)
    ->from(254722000000)
    ->usingAccount('paybill_2')
    ->usingReference('Some Reference', 'Test Payment')
    ->push();

$response = STK::push(10, 254722000000, 'Some Reference', 'Test Payment', 'paybill_2');
```

Using the `CustomerGoodsOnline` command:

```
use SmoDav\Mpesa\Laravel\Facades\STK;

$response = STK::request(10)
    ->from(254722000000)
    ->usingReference('Some Reference', 'Test Payment')
    ->setCommand(CUSTOMER_BUYGOODS_ONLINE)
    ->push();

$response = STK::push(10, 254722000000, 'Some Reference', 'Test Payment', null, CUSTOMER_BUYGOODS_ONLINE);
```

### STK PUSH Transaction Validation

[](#stk-push-transaction-validation)

#### validate(merchantReferenceId, account = null)

[](#validatemerchantreferenceid-account--null)

Validate a C2B STK Push transaction.

##### Vanilla

[](#vanilla-3)

```
use SmoDav\Mpesa\C2B\STK;

$stk = new STK($core);

$response = $stk->validate('ws_CO_16022018125');
```

Using the `paybill_2` account:

```
$response = $stk->validate('ws_CO_16022018125', 'paybill_2');
```

##### Laravel

[](#laravel-4)

```
use SmoDav\Mpesa\Laravel\Facades\STK;

$response = STK::validate('ws_CO_16022018125');
```

Using the `paybill_1` account:

```
use SmoDav\Mpesa\Laravel\Facades\STK;

$response = STK::validate('ws_CO_16022018125', 'paybill_2');
```

##### When going live, you should change the `default` value of the config file to the production account.

[](#when-going-live-you-should-change-the-default-value-of-the-config-file-to-the-production-account)

License
-------

[](#license)

The M-Pesa Package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).

###  Health Score

68

—

FairBetter than 100% of packages

Maintenance86

Actively maintained with recent releases

Popularity50

Moderate usage in the ecosystem

Community30

Small or concentrated contributor base

Maturity89

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 80% 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 ~71 days

Recently: every ~279 days

Total

50

Last Release

71d ago

Major Versions

2.0.x-dev → v3.0.02017-10-16

3.0.x-dev → v4.0.02018-08-27

4.1.x-dev → 5.0.x-dev2019-09-26

v5.3.2 → v6.0.02021-08-31

v6.4.0 → v7.0.02026-03-09

PHP version history (4 changes)v1.0.0PHP &gt;=5.4.0

v1.2.3PHP &gt;=5.6.0

v6.4.0PHP &gt;=7.2

v7.0.0PHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/dffc9fa88d88bb577590c2321207aee2fb18cc32d99342d6ddfb5f19731a7e69?d=identicon)[SmoDav](/maintainers/SmoDav)

---

Top Contributors

[![SmoDav](https://avatars.githubusercontent.com/u/2639600?v=4)](https://github.com/SmoDav "SmoDav (88 commits)")[![weezqyd](https://avatars.githubusercontent.com/u/11520842?v=4)](https://github.com/weezqyd "weezqyd (8 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (6 commits)")[![le-yo](https://avatars.githubusercontent.com/u/1670007?v=4)](https://github.com/le-yo "le-yo (2 commits)")[![kulemantu](https://avatars.githubusercontent.com/u/907164?v=4)](https://github.com/kulemantu "kulemantu (1 commits)")[![codingedward](https://avatars.githubusercontent.com/u/15171489?v=4)](https://github.com/codingedward "codingedward (1 commits)")[![ngarawakimani](https://avatars.githubusercontent.com/u/24817014?v=4)](https://github.com/ngarawakimani "ngarawakimani (1 commits)")[![ejimba](https://avatars.githubusercontent.com/u/5405838?v=4)](https://github.com/ejimba "ejimba (1 commits)")[![swimlappy](https://avatars.githubusercontent.com/u/3445492?v=4)](https://github.com/swimlappy "swimlappy (1 commits)")[![DevMaurice](https://avatars.githubusercontent.com/u/7044420?v=4)](https://github.com/DevMaurice "DevMaurice (1 commits)")

---

Tags

mobile-moneympesampesa-apiphpapilaraveltransactionsmpesasafaricom

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/smodav-mpesa/health.svg)

```
[![Health](https://phpackages.com/badges/smodav-mpesa/health.svg)](https://phpackages.com/packages/smodav-mpesa)
```

###  Alternatives

[vluzrmos/slack-api

Wrapper for Slack.com WEB API.

102589.1k3](/packages/vluzrmos-slack-api)[specialtactics/l5-api

Dependencies for the Laravel API Boilerplate package

3672.8k2](/packages/specialtactics-l5-api)[bmatovu/laravel-mtn-momo

Laravel MTN MOMO integration.

14310.9k](/packages/bmatovu-laravel-mtn-momo)[ardakilic/mutlucell

Mutlucell SMS API wrapper for sending sms text messages for Laravel

457.3k](/packages/ardakilic-mutlucell)[dariusiii/tmdb-laravel

Laravel Package for TMDB ( The Movie Database ) API. Provides easy access to the wtfzdotnet/php-tmdb-api library.

1821.1k](/packages/dariusiii-tmdb-laravel)[kabangi/mpesa

M-Pesa API implementation

453.0k2](/packages/kabangi-mpesa)

PHPackages © 2026

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