Looking to hire Laravel developers? Try LaraJobs

laravel-mpesa maintained by ysg

Description
Official Safaricom Daraja M-Pesa integration for Laravel built on ysg/payment-core.
Author
Last update
2026/07/14 20:58 (dev-main)
License
Links
Downloads
5

Comments
comments powered by Disqus

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.