drh / mpesa
Mpesa Payments Library
Requires
- php: ^8.2
- ext-json: *
- ext-openssl: *
- guzzlehttp/guzzle: ^7.9
- illuminate/cache: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/container: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/routing: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
- myclabs/deep-copy: ^1.13
Requires (Dev)
- orchestra/testbench: ^8.35|^9.0|^10.0|^11.0
- pestphp/pest: ^2.36|^3.0|^4.0
- pestphp/pest-plugin-laravel: ^2.4|^3.0|^4.0
- phpstan/phpstan: ^1.12|^2.0
- phpunit/phpunit: ^10.5|^11.0|^12.0
- squizlabs/php_codesniffer: ^3.12
- dev-main
- v4.2.0
- v4.1.1
- v4.1.0
- v4.0.3
- v4.0.2
- v4.0.1
- V4.0.0
- v3.3.0
- v3.2.5
- v3.2.4
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.0
- v3.0.0
- v2.6.2
- v2.6.1
- v2.6.0
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.4.6
- v2.4.5
- v2.4.4
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.x-dev
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.1
- v1.0.0
- dev-feature/laravel-13-support
- dev-chore/bump-dependencies
- dev-red.dev
- dev-bulk_refactor
This package is auto-updated.
Last update: 2026-03-21 18:42:35 UTC
README
A Laravel package for integrating with Safaricom's M-Pesa payment APIs. Supports STK Push, C2B, B2C, B2B payments, transaction status queries, and identity verification.
Inspired by Mobile Money Library by Agweria: https://mobile-money.agweria.com
Requirements
- PHP 8.2+
- Laravel 8.x - 13.x
Installation
composer require drh/mpesa
The package auto-discovers its service provider and facades. Publish the configuration file:
php artisan vendor:publish --provider="DrH\Mpesa\MpesaServiceProvider"
Run migrations to create the payment tracking tables:
php artisan migrate
Configuration
Add these environment variables to your .env file:
# General MPESA_SANDBOX=true # C2B / STK Push MPESA_KEY=your-consumer-key MPESA_SECRET=your-consumer-secret MPESA_C2B_SHORTCODE=174379 MPESA_C2B_PASS_KEY=your-passkey MPESA_C2B_TRANSACTION_TYPE=CustomerPayBillOnline # B2C (Business to Customer) MPESA_B2C_KEY=your-b2c-key MPESA_B2C_SECRET=your-b2c-secret MPESA_B2C_SHORTCODE=603021 MPESA_B2C_INITIATOR=apiop37 # B2B (Business to Business) MPESA_B2B_KEY=your-b2b-key MPESA_B2B_SECRET=your-b2b-secret MPESA_B2B_SHORTCODE=600584 MPESA_B2B_INITIATOR=apiop37
See the published config/drh.mpesa.php for all available options including callback URLs, retry settings, multi-tenancy, and logging.
Usage
STK Push (Lipa Na M-Pesa Online)
use DrH\Mpesa\Facades\STK; // Simple push $result = STK::push(amount: 100, phone: '254712345678', ref: 'Order001', description: 'Payment for order'); // Fluent API $result = STK::amount(100) ->from('254712345678') ->usingReference('Order001', 'Payment for order') ->push(); // Check STK transaction status $status = STK::status($checkoutRequestId);
C2B (Customer to Business)
Register your validation and confirmation URLs with M-Pesa:
use DrH\Mpesa\Facades\Registrar; Registrar::shortcode(174379) ->onConfirmation('https://example.com/payments/callbacks/c2b-confirmation') ->onValidation('https://example.com/payments/callbacks/c2b-validation') ->submit();
B2C (Business to Customer)
use DrH\Mpesa\Facades\B2C; // Send payment $result = B2C::send(number: '254712345678', amount: 500, remarks: 'Salary payment'); // Fluent API $result = B2C::to('254712345678') ->amount(500) ->withRemarks('Salary payment') ->send(); // Check balance $balance = B2C::balance(); // Check transaction status $status = B2C::status($transactionId);
B2B (Business to Business)
use DrH\Mpesa\Facades\B2B; // Send payment $result = B2B::pay( type: 'BusinessPayBill', shortcode: '600000', amount: 1000, reference: 'INV001', phone: '254712345678' ); // Check transaction status $status = B2B::status($request);
Identity Verification
use DrH\Mpesa\Facades\Identity; $result = Identity::validate('254712345678');
Events
The package dispatches events for payment lifecycle hooks. Listen for these in your EventServiceProvider or via Event::listen():
| Event | Description |
|---|---|
StkPushRequestedEvent |
STK push request initiated |
StkPushPaymentSuccessEvent |
STK push payment completed successfully |
StkPushPaymentFailedEvent |
STK push payment failed |
C2bConfirmationEvent |
C2B payment confirmed |
B2cPaymentSuccessEvent |
B2C payment completed successfully |
B2cPaymentFailedEvent |
B2C payment failed |
B2bPaymentSuccessEvent |
B2B payment completed successfully |
B2bPaymentFailedEvent |
B2B payment failed |
TransactionStatusSuccessEvent |
Transaction status query succeeded |
TransactionStatusFailedEvent |
Transaction status query failed |
QueueTimeoutEvent |
Queue timeout occurred |
All events are in the DrH\Mpesa\Events namespace.
Artisan Commands
# Register C2B validation and confirmation URLs php artisan mpesa:register_c2b_urls # Check status of pending STK transactions php artisan mpesa:query_stk_status # Check status of pending B2C transactions php artisan mpesa:b2c_transaction_status # Check status of pending B2B transactions php artisan mpesa:b2b_transaction_status
Callback Routes
The package automatically registers callback routes under /payments/callbacks/:
POST /payments/callbacks/stk-callback- STK push callbackPOST /payments/callbacks/c2b-validation- C2B validationPOST /payments/callbacks/c2b-confirmation- C2B confirmationPOST /payments/callbacks/result/- B2C/B2B resultPOST /payments/callbacks/timeout/- B2C/B2B timeout
A pesa.cors middleware alias is available for CORS handling on callback routes.
Testing
composer run-script test
License
MIT