PHPackages                             uzhlaravel/maishapay - 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. [Payment Processing](/categories/payments)
4. /
5. uzhlaravel/maishapay

ActiveLibrary[Payment Processing](/categories/payments)

uzhlaravel/maishapay
====================

This is a laravel way to interact with maishapay.net providing good design and make it easy to use

v1.0.5(1mo ago)0332MITPHPPHP ^8.3CI passing

Since Sep 9Pushed 1mo agoCompare

[ Source](https://github.com/Uzziahlukeka/maisha-pay)[ Packagist](https://packagist.org/packages/uzhlaravel/maishapay)[ Docs](https://github.com/uzziahlukeka/maisha-pay)[ GitHub Sponsors](https://github.com/uzhlaravel)[ RSS](/packages/uzhlaravel-maishapay/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (5)Dependencies (39)Versions (11)Used By (0)

This is a laravel way to interact with maishapay.com
====================================================

[](#this-is-a-laravel-way-to-interact-with-maishapaycom)

[![Latest Version on Packagist](https://camo.githubusercontent.com/55d36b16585f82a7f2e9355d49527808650ee10edc9e9ed3fcf144026e8ced7b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f757a686c61726176656c2f6d61697368617061792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/uzhlaravel/maishapay)[![GitHub Tests Action Status](https://github.com/uzziahlukeka/maisha-pay/actions/workflows/run-tests.yml/badge.svg)](https://github.com/uzziahlukeka/maisha-pay/actions/workflows/run-tests.yml/badge.svg)[![GitHub Code Style Action Status](https://github.com/uzziahlukeka/maisha-pay/actions/workflows/fix-php-code-style-issues.yml/badge.svg)](https://github.com/uzziahlukeka/maisha-pay/actions/workflows/fix-php-code-style-issues.yml/badge.svg)[![Total Downloads](https://camo.githubusercontent.com/15a4d0c07ee656cc5b0326b6edf99302c9dbcf4931db1e14cbbcf11c06447d05/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f757a686c61726176656c2f6d61697368617061792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/uzhlaravel/maishapay)[![License](https://camo.githubusercontent.com/07a7d0169027aac6d7a0bfa8964dfef5fbc40d5a2075cabb3d8bc67e17be3451/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE.md)

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

[](#installation)

You can install the package via composer:

```
composer require uzhlaravel/maishapay
```

- if you want to have a live account, you need to register at  or
- if you want to have a sandbox account, you need to register at  or
- you need to get your public and secret keys from the dashboard
- you can set the gateway mode to 0 for sandbox and 1 for live

### automated installation

[](#automated-installation)

```
php artisan maishapay:install
```

You can publish and run the migrations with:

```
php artisan vendor:publish --tag="maishapay-migrations"
php artisan migrate
```

You can publish the config file with:

```
php artisan vendor:publish --tag="maishapay-config"
```

This is the contents of the published config file:

```
return [

    'public_key' => env('MAISHAPAY_PUBLIC_KEY'),
    'secret_key' => env('MAISHAPAY_SECRET_KEY'),
    'gateway_mode' => env('MAISHAPAY_GATEWAY_MODE', 0),
    'base_url' => env('MAISHAPAY_BASE_URL', 'https://marchand.maishapay.online/api/collect'),
    'b2c_base_url' => env('MAISHAPAY_B2C_BASE_URL', 'https://marchand.maishapay.online/api/b2c'),
    'callback_url' => env('MAISHAPAY_CALLBACK_URL'),

];
```

Add these to your `.env` file:

```
MAISHAPAY_PUBLIC_KEY=your-public-key
MAISHAPAY_SECRET_KEY=your-secret-key
MAISHAPAY_GATEWAY_MODE=0
MAISHAPAY_CALLBACK_URL=https://yourapp.com/maishapay/callback
# Optional: only needed if the B2C base URL changes
# MAISHAPAY_B2C_BASE_URL=https://marchand.maishapay.online/api/b2c
```

Usage Mobile Money Payment
--------------------------

[](#usage-mobile-money-payment)

```
use Uzhlaravel\Maishapay\Maishapay;
use Uzhlaravel\Maishapay\Models\MaishapayTransaction;
use Uzhlaravel\Maishapay\DataTransferObjects\MobileMoney;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

// you can use it as a parameter to a controller method

  protected $maishapay;

    public function __construct(Maishapay $maishapay)
    {
        $this->maishapay = $maishapay;
    }

    // for MOBILEMONEY payment type

    // validating the request data
    $validatedData = $request->validate([
            'amount' => 'required|numeric',
            'currency' => 'required|string',
            'customerFullName' => 'required|string',
            'customerEmailAddress' => 'required|email',
            'provider' => 'required|string',
            'walletID' => 'required',
            'channel' => 'required|string',
        ]);

    //if you want to keep track of the transaction
     $transaction = MaishapayTransaction::create([
                'payment_type' => 'MOBILEMONEY',
                'provider' => $validatedData['provider'],
                'amount' => $validatedData['amount'],
                'currency' => $validatedData['currency'],
                'customer_full_name' => $validatedData['customerFullName'],
                'customer_email' => $validatedData['customerEmailAddress'],
                'wallet_id' => $validatedData['walletID'],
                'channel' => $validatedData['channel'],
                'transaction_reference'=> 'TXN_' . uniqid(),
                'status' => 'PENDING'
            ]);

     //then do the transactin
     $mobileMoney = new MobileMoney(
                amount: $validatedData['amount'],
                currency: $validatedData['currency'],
                customerFullName: $validatedData['customerFullName'],
                customerEmailAddress: $validatedData['customerEmailAddress'],
                provider: $validatedData['provider'],
                walletId: $validatedData['walletID'],
                transactionReference: $transaction->transaction_reference,
                callbackUrl: route('pricing')
            );

            // Process mobile money payment
            $response = $this->maishapay->processMobileMoneyPayment($mobileMoney);

            // Parse the response
            $responseData = $response->json();

        // or you can use implemetation directly in your controller method

            $maishapay = new Uzhlaravel\Maishapay\Maishapay();

             $response = $this->maishapay->processMobileMoneyPayment($mobileMoney);

             ...(other code)
```

### Automate the database

[](#automate-the-database)

```
use Uzhlaravel\Maishapay\EnhancedMaishapayService;
use Uzhlaravel\Maishapay\Models\MaishapayTransaction;
use Uzhlaravel\Maishapay\DataTransferObjects\MobileMoney;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

// you can use it as a parameter to a controller method

  protected $maishapay;

    public function __construct(
    private EnhancedMaishapayService $enhancedMaishapayService,
    )
    {

    }

    // validating the request data
    $validatedData = $request->validate([
            'amount' => 'required|numeric',
            'currency' => 'required|string',
            'customerFullName' => 'required|string',
            'customerEmailAddress' => 'required|email',
            'provider' => 'required|string',
            'walletID' => 'required',
            'channel' => 'required|string',
        ]);

     //then do the transactin
     $mobileMoney = new MobileMoney(
                amount: $validatedData['amount'],
                currency: $validatedData['currency'],
                customerFullName: $validatedData['customerFullName'],
                customerEmailAddress: $validatedData['customerEmailAddress'],
                provider: $validatedData['provider'],
                walletId: $validatedData['walletID'],
                transactionReference: $transaction->transaction_reference,
                callbackUrl: route('pricing')
            );

            // Process mobile money payment
            $response = $this->enhancedMaishapayService->processMobileMoneyPaymentWithLogging($mobileMoney);

            // Parse the response
            $responseData = $response->json();

        // or you can use implemetation directly in your controller method

            $maishapay = new Uzhlaravel\Maishapay\Maishapay();

             $response = $this->maishapay->processMobileMoneyPayment($mobileMoney);

             ...(other code)
```

Usage Bank Payment
------------------

[](#usage-bank-payment)

```
//importing the class

use Uzhlaravel\Maishapay\Maishapay;
use Uzhlaravel\Maishapay\Models\MaishapayTransaction;
use Uzhlaravel\Maishapay\DataTransferObjects\MobileMoney;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

// you can use it as a parameter to a controller method

// for BANK payment type V2

// validating the request data
$validatedData = $request->validate([
            'amount' => 'required|numeric',
            'currency' => 'required|string',
            'customerFullName' => 'required|string',
            'customerEmailAddress' => 'required|email',
            'provider' => 'required|string',
            'walletID' => 'required',
            'channel' => 'required|string',
        ]);

//  if you want to keep track
$transaction = MaishapayTransaction::query()->create([
                'payment_type' => 'CARD',
                'provider' => $validatedData['provider'], //visa or mastercard
                'amount' => $validatedData['amount'],
                'currency' => $validatedData['currency'],
                'customer_full_name' => $validatedData['customerFullName'],
                'customer_phone' => $validatedData['customerPhoneNumber'],
                'customer_email' => $validatedData['customerEmailAddress'],
                'channel' =>  $validatedData['channel'],
                'transaction_reference'=> 'TXN_' . uniqid(),
                'status' => 'PENDING'
            ]);

            $cardPayment = new CardPayment(
                amount: $validatedData['amount'],
                currency: $validatedData['currency'],
                customerEmailAddress: $validatedData['customerEmailAddress'],
                customerPhoneNumber: $validatedData['customerPhoneNumber'],
                provider: $validatedData['provider'],
                customerFullName: $validatedData['customerFullName'],
                transactionReference: $transaction->transaction_reference,
                callbackUrl: route('your-callback-route') // if different from the one in your .env file
            );

            $response = $this->maishapay->processCardPayment($cardPayment);

            $responseData = $response->json();

            //make sure to redirect to the payment page :

             return redirect($responseData['paymentPage']);
        (other code)
```

Automate the database transactions :
------------------------------------

[](#automate-the-database-transactions-)

```
//importing the class

use Uzhlaravel\Maishapay\Services\EnhancedMaishapayService ;
use Uzhlaravel\Maishapay\DataTransferObjects\CardPayment;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

 private EnhancedMaishapayService $enhancedMaishapayService;

 $cardPayment = new CardPayment(
                amount: $validatedData['amount'],
                currency: $validatedData['currency'],
                customerEmailAddress: $validatedData['customerEmailAddress'],
                customerPhoneNumber: $validatedData['customerPhoneNumber'],
                provider: $validatedData['provider'],
                customerFullName: $validatedData['customerFullName'],
                transactionReference: $transaction->transaction_reference,
                callbackUrl: route('your-callback-route') // if different from the one in your .env file
            );

            $response = $this->enhancedMaishapayService->processCardPaymentWithLogging($cardPayment,true);

            $responseData = $response->json();

            //make sure to redirect to the payment page :
```

Usage B2C (Business to Customer) Payment
----------------------------------------

[](#usage-b2c-business-to-customer-payment)

B2C allows your business to send money directly to a customer's mobile money wallet — useful for payouts, refunds, salaries, or commissions.

```
use Uzhlaravel\Maishapay\Maishapay;
use Uzhlaravel\Maishapay\DataTransferObjects\BusinessToCustomer;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

// Inject via constructor or resolve from container
public function __construct(Maishapay $maishapay)
{
    $this->maishapay = $maishapay;
}

// Validate request
$validatedData = $request->validate([
    'amount'                => 'required|numeric',
    'currency'              => 'required|string',
    'customer_full_name'    => 'required|string',
    'customer_email'        => 'required|email',
    'provider'              => 'required|string',   // AIRTEL, ORANGE, MTN, VODACOM
    'wallet_id'             => 'required|string',   // recipient phone / wallet number
    'motif'                 => 'required|string',   // reason for the transfer
]);

$b2c = new BusinessToCustomer(
    amount:               $validatedData['amount'],
    currency:             $validatedData['currency'],
    customerFullName:     $validatedData['customer_full_name'],
    customerEmailAddress: $validatedData['customer_email'],
    provider:             $validatedData['provider'],
    walletId:             $validatedData['wallet_id'],
    motif:                $validatedData['motif'],
    callbackUrl:          route('your-callback-route') // optional
);

try {
    $response = $this->maishapay->processB2CPayment($b2c);
    $responseData = $response->json();
    // handle success
} catch (MaishapayException $e) {
    // handle error
}
```

### B2C with automatic database logging

[](#b2c-with-automatic-database-logging)

```
use Uzhlaravel\Maishapay\Services\EnhancedMaishapayService;
use Uzhlaravel\Maishapay\DataTransferObjects\BusinessToCustomer;
use Uzhlaravel\Maishapay\Exceptions\MaishapayException;

public function __construct(private EnhancedMaishapayService $enhancedMaishapayService)
{
}

$b2c = new BusinessToCustomer(
    amount:               '5000',
    currency:             'CDF',
    customerFullName:     'Jane Doe',
    customerEmailAddress: 'jane@example.com',
    provider:             'AIRTEL',
    walletId:             '0999000000',
    motif:                'Monthly commission payout',
);

$result = $this->enhancedMaishapayService->processB2CPaymentWithLogging($b2c);

// Unlike collection, a B2C transfer resolves synchronously: the API returns
// the final status (SUCCESS or FAILED) in the same response, and the logged
// transaction is updated accordingly straight away.
if ($result['success']) {
    $transaction = $result['transaction']; // MaishapayTransaction model (SUCCESS)
    $apiResponse  = $result['response'];
} else {
    // $result['status'] is FAILED when the operator declined the transfer,
    // or $result['error'] is set when the request itself could not be sent.
    $status = $result['status'] ?? null;
    $error  = $result['error'] ?? null;
}
```

> **Note:** For B2C, `motif`, `customer_full_name` and `customer_email_address`are optional (the MaishaPay API marks them as not required). `amount`, `currency`, `provider` and `wallet_id` remain required.

### B2C using the static create() helper

[](#b2c-using-the-static-create-helper)

```
$b2c = BusinessToCustomer::create([
    'amount'                => '5000',
    'currency'              => 'CDF',
    'provider'              => 'MTN',
    'wallet_id'             => '0810000000',
    // The following are all optional for B2C:
    'customer_full_name'    => 'Jane Doe',
    'customer_email_address'=> 'jane@example.com',
    'motif'                 => 'Refund for order #1234',
    'callback_url'          => 'https://yourapp.com/maishapay/callback',
]);

$response = $this->maishapay->processB2CPayment($b2c);
```

### B2C database migration

[](#b2c-database-migration)

Run the additional migration to support B2C transactions:

```
php artisan vendor:publish --tag="maishapay-migrations"
php artisan migrate
```

This adds:

- A `motif` column to `maishapay_transactions`
- `B2C` as a valid `payment_type` enum value

### Querying B2C transactions

[](#querying-b2c-transactions)

```
use Uzhlaravel\Maishapay\Models\MaishapayTransaction;

// All B2C transactions
$b2cTransactions = MaishapayTransaction::b2c()->get();

// B2C stats via EnhancedMaishapayService
$stats = $this->enhancedMaishapayService->getTransactionStats();
// $stats['b2c'] => total B2C transaction count
```

Checking transaction status from MaishaPay's servers
----------------------------------------------------

[](#checking-transaction-status-from-maishapays-servers)

Instead of trusting the status stored in your local database, you can query the **live** status of a transaction directly from MaishaPay's **Transaction Lookup**API. This is useful when a callback was missed, delayed, or you simply want to confirm the real state before fulfilling an order. It works for any transaction type — Mobile Money, card, or B2C.

The lookup runs against MaishaPay's dedicated transaction endpoint (`https://marchand.maishapay.online/api/transaction/rest/v2/check`) and supports two modes:

- **By merchant reference** — your own `transactionReference` (sent with `?useRef=1`). This is the default.
- **By MaishaPay transaction ID** — the numeric ID MaishaPay returns in the initial payment response.

### Quick status check (raw response)

[](#quick-status-check-raw-response)

```
use Uzhlaravel\Maishapay\Facades\Maishapay;

// By your merchant reference (returns the raw Illuminate HTTP Response)
$response = Maishapay::checkTransactionStatus('MP_ABC123_1700000000');

// ...or by the MaishaPay transaction ID
$response = Maishapay::checkTransactionById(12345);

$status = $response->json('transactionStatus'); // e.g. "SUCCESS", "PENDING", "FAILED"
```

### Canonical status via EnhancedMaishapayService

[](#canonical-status-via-enhancedmaishapayservice)

```
use Uzhlaravel\Maishapay\Services\EnhancedMaishapayService;

$service = app(EnhancedMaishapayService::class);

// Live status from the endpoint, normalized to PENDING|SUCCESS|FAILED|CANCELLED
$status = $service->getTransactionStatus('MP_ABC123_1700000000');

// Or get the status plus the raw payload
['status' => $status, 'response' => $payload] =
    $service->fetchTransactionStatus('MP_ABC123_1700000000');
```

### Refresh the local record from the server

[](#refresh-the-local-record-from-the-server)

`refreshTransactionStatus()` queries MaishaPay, syncs the matching local `MaishapayTransaction` record (so the database acts as a cache), and fires the `TransactionStatusUpdated` event when the status changes:

```
$transaction = $service->refreshTransactionStatus('MP_ABC123_1700000000');

if ($transaction?->isSuccessful()) {
    // fulfil the order
}
```

### Configuration

[](#configuration)

The Transaction Lookup base URL and endpoint are configurable:

Config keyEnv varDefault`transaction_base_url``MAISHAPAY_TRANSACTION_BASE_URL``https://marchand.maishapay.online/api/transaction``status_endpoint``MAISHAPAY_STATUS_ENDPOINT``/rest/v2/check`The lookup posts `gatewayMode`, `publicApiKey`, `secretApiKey` and `transactionId` (set to your merchant reference, with `?useRef=1`, when looking up by reference). The canonical status is read from MaishaPay's `transactionStatus` field and normalized to `PENDING`, `SUCCESS`, `FAILED` or `CANCELLED`.

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [uzziahlukeka](https://github.com/uzhlaravel)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance91

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

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

Recently: every ~32 days

Total

6

Last Release

44d ago

### Community

Maintainers

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

---

Top Contributors

[![Uzziahlukeka](https://avatars.githubusercontent.com/u/102746022?v=4)](https://github.com/Uzziahlukeka "Uzziahlukeka (49 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (7 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")

---

Tags

laravelmobilemoneypayment-gatewayrdclaravelpaymentgatewaypayment gatewayafricauzhlaravelmaishapaypayment gateway laravelDRCongo

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/uzhlaravel-maishapay/health.svg)

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

###  Alternatives

[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.2k12.6M135](/packages/dedoc-scramble)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3915.5k](/packages/rawilk-profile-filament-plugin)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

46273.9k](/packages/harris21-laravel-fuse)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

25060.1k](/packages/vormkracht10-laravel-mails)[elegantly/laravel-translator

All on one translations management for Laravel

6339.5k](/packages/elegantly-laravel-translator)

PHPackages © 2026

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