Laravel package for integrating with Safaricom's M-Pesa payment gateway. Supports STK Push, B2C, B2B, balance queries, transaction status checks, and payment reversals.
# Laravel M-Pesa Integration Package
A thin, dependency-injection friendly SDK for Safaricom's M-Pesa Daraja API.
STK Push, B2C, B2B Express Checkout, C2B, account balance, transaction status,
and reversals.
No models, migrations, or routes are forced on you. The package handles the
integration layer: OAuth tokens and caching, the STK password and timestamp,
initiator credential encryption, request validation, and callback parsing.
Your app owns the payment records, queues, and business logic.
For upstream API changes, always refer to the
Safaricom Developer Portal.
## Requirements
- PHP 8.2+
| Laravel Version |
|------------------|
| Laravel 11.x |
| Laravel 12.x |
| Laravel 13.x |
---
## Installation
```bash
composer require botnetdobbs/laravel-mpesa-sdk
```
Publish the config file:
```bash
php artisan vendor:publish --tag=mpesa-config
```
Set your credentials in `.env`. Get them from the My Apps page on the Daraja portal:
```env
MPESA_ENV=sandbox
MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secret
```
That is enough for STK Push in sandbox. B2C, balance, status, and reversal also
need initiator credentials and a certificate. Details:
- Getting Started: first call, how authentication works
- Configuration: every option and the go-live checklist
---
## Quick Look
### Initiate a payment
Inject the `Client` contract. There is no facade.
```php
use Botnetdobbs\Mpesa\Contracts\Client;
use Botnetdobbs\Mpesa\Exceptions\MpesaException;
class PaymentController extends Controller
{
public function __construct(private Client $mpesa)
{
}
public function checkout(Order $order)
{
try {
$response = $this->mpesa->stkPush([
'BusinessShortCode' => config('mpesa.business.short_codes.paybill'),
'Amount' => $order->total,
'PhoneNumber' => $order->customer_phone, // 2547XXXXXXXX
'CallBackURL' => route('mpesa.stk.callback'),
'AccountReference' => $order->reference, // shown on the customer's prompt
]);
} catch (Mpesa …