laravel-mpesa maintained by ysg
YSG Laravel M-Pesa
Official Laravel integration for Safaricom Daraja M-Pesa built on ysg/payment-core.
ysg/laravel-mpesa provides a production-ready implementation of the shared PaymentProcessor contract, allowing Laravel applications to initiate M-Pesa STK Push payments while remaining decoupled from provider-specific APIs.
Features
- Laravel 11+
- Safaricom Daraja STK Push
- Provider-agnostic payment architecture
- Immutable readonly DTOs
- OAuth token caching with automatic refresh
- Automatic callback routing and parsing
- Strongly typed configuration
- SOLID, service-oriented architecture
- PHPUnit test coverage
- Verified against the Safaricom Daraja Sandbox
Requirements
- PHP 8.3+
- Laravel 11+
Installation
Install the package via Composer.
composer require ysg/laravel-mpesa
The shared ysg/payment-core package will be installed automatically as a dependency.
Publish Configuration
Publish the configuration file.
php artisan vendor:publish --tag=mpesa-config
This creates:
config/mpesa.php
The package also automatically registers the callback endpoint:
POST /mpesa/callback
Configuration
Configure your .env file.
MPESA_DRIVER=daraja
MPESA_ENVIRONMENT=sandbox
MPESA_CONSUMER_KEY=
MPESA_CONSUMER_SECRET=
MPESA_SHORTCODE=
MPESA_PASSKEY=
MPESA_CALLBACK_URL=https://example.com/mpesa/callback
MPESA_TIMEOUT=30
MPESA_RETRY_TIMES=3
MPESA_RETRY_SLEEP=500
Configuration Options
| Key | Description |
|---|---|
driver |
Payment provider implementation. Defaults to daraja. |
environment |
sandbox or production. |
consumer_key |
Daraja Consumer Key. |
consumer_secret |
Daraja Consumer Secret. |
shortcode |
Business shortcode. |
passkey |
STK Push passkey. |
callback_url |
Public callback endpoint. |
timeout |
HTTP request timeout (seconds). |
retry_times |
Number of HTTP retry attempts. |
retry_sleep |
Delay between retries (milliseconds). |
Initiating an STK Push
use Ysg\LaravelMpesa\Processors\MpesaPaymentProcessor;
use Ysg\PaymentCore\DTOs\Money;
use Ysg\PaymentCore\DTOs\Payer;
use Ysg\PaymentCore\DTOs\PaymentRequest;
$processor = app(MpesaPaymentProcessor::class);
$response = $processor->initiatePayment(
new PaymentRequest(
money: new Money('100.00', 'KES'),
payer: new Payer(
phone: '0712345678',
),
reference: 'INV-1001',
description: 'Invoice Payment',
),
);
if ($response->pending()) {
// STK Push accepted by Daraja.
}
Handling Callbacks
Incoming callbacks are automatically received through:
POST /mpesa/callback
The package parses the Daraja payload into a strongly typed CallbackRequest and dispatches it through Laravel's event dispatcher.
Applications can listen for the callback and perform their own payment reconciliation.
use Illuminate\Support\Facades\Event;
use Ysg\LaravelMpesa\DTOs\CallbackRequest;
Event::listen(function (CallbackRequest $callback) {
if ($callback->failed()) {
return;
}
$receipt = $callback->receiptNumber;
$reference = $callback->providerReference();
// Perform your business logic...
});
The package intentionally does not update your database or perform payment reconciliation. Those responsibilities remain within your application.
Payment Core Integration
ysg/laravel-mpesa implements the shared PaymentProcessor contract from ysg/payment-core.
Depending on the shared payment abstractions rather than provider-specific implementations allows applications to introduce additional payment providers in the future without changing their payment workflows.
Testing
Run the test suite.
vendor/bin/phpunit
The package includes:
- Unit tests
- Feature tests
- End-to-end verification against the Safaricom Daraja Sandbox
Contributing
Contributions are welcome.
Please ensure that:
- Code follows PSR-12.
- New functionality includes appropriate tests.
- Public APIs remain backwards compatible where practical.
- The package remains lightweight and provider-agnostic.
License
This package is open-sourced under the MIT License.