PHPackages                             mesasdk/php-mpesa - 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. mesasdk/php-mpesa

ActiveLibrary

mesasdk/php-mpesa
=================

A comprehensive PHP SDK for integrating with the M-Pesa API in Ethiopia, featuring modern fluent interface design, type-safe responses, and robust error handling

v1.0.0(1y ago)131MITPHPPHP &gt;=7.4

Since Mar 18Pushed 1y ago1 watchersCompare

[ Source](https://github.com/Mesele-shishay/PhpMpesaSDK)[ Packagist](https://packagist.org/packages/mesasdk/php-mpesa)[ GitHub Sponsors](https://github.com/sponsors/Mesele-shishay)[ RSS](/packages/mesasdk-php-mpesa/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (2)Used By (0)

PHP M-Pesa SDK
==============

[](#php-m-pesa-sdk)

A comprehensive PHP SDK for integrating with the M-Pesa API in Ethiopia. This SDK provides a simple and elegant way to interact with M-Pesa's payment services, featuring a modern fluent interface design and robust error handling.

Features
--------

[](#features)

- 🚀 Modern Fluent Interface Design
- 💳 Complete M-Pesa API Integration
    - STK Push (USSD Push)
    - Business to Customer (B2C) Payments
    - Customer to Business (C2B) Payments and Simulation
    - URL Registration and Management
    - Transaction Status Queries
- 🔄 Type-Safe Response Models
- 🛡️ Robust Error Handling and Validation
- 📝 Comprehensive Logging
- 🔒 Secure by Default
- ✨ PSR-4 Compliant
- 📚 Extensive Documentation
- 🧪 Unit Tests

Requirements
------------

[](#requirements)

- PHP 7.4 or higher
- Composer
- Valid M-Pesa API credentials
- HTTPS enabled server for callbacks

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

[](#installation)

Install the package via composer:

```
composer require mesasdk/php-mpesa
```

Quick Start
-----------

[](#quick-start)

```
use MesaSDK\PhpMpesa\Config;
use MesaSDK\PhpMpesa\Mpesa;
use MesaSDK\PhpMpesa\Exceptions\MpesaException;

// Initialize configuration
$config = new Config();
$config->setBaseUrl("https://apisandbox.safaricom.et")
    ->setEnvironment('sandbox')  // Use 'production' for live environment
    ->setConsumerKey('your_consumer_key')
    ->setConsumerSecret('your_consumer_secret')
    ->setShortCode('your_shortcode')
    ->setPassKey('your_passkey')
    ->setVerifySSL(true);  // Always true in production

// Create M-Pesa instance
$mpesa = new Mpesa($config);

try {
    $response = $mpesa->authenticate()
        ->setC2BAmount(110.00)
        ->setC2BMsisdn('251945628580')
        ->setC2BBillRefNumber('091091')
        ->executeC2BSimulation();

    if ($response->isSuccessful()) {
        echo "Transaction initiated successfully!";
        echo "Response Code: " . $response->getResponseCode();
        echo "Conversation ID: " . $response->getConversationId();
    }
} catch (MpesaException $e) {
    echo "Error: " . $e->getMessage();
}
```

Configuration
-------------

[](#configuration)

### Environment Variables

[](#environment-variables)

We recommend using environment variables for sensitive configuration:

```
$config = new Config();
$config->setBaseUrl("https://apisandbox.safaricom.et")  // Add base URL
    ->setEnvironment($_ENV['MPESA_ENVIRONMENT'])
    ->setConsumerKey($_ENV['MPESA_CONSUMER_KEY'])
    ->setConsumerSecret($_ENV['MPESA_CONSUMER_SECRET'])
    ->setShortCode($_ENV['MPESA_SHORTCODE'])
    ->setPassKey($_ENV['MPESA_PASS_KEY'])
    ->setVerifySSL(true);  // Set to false only for sandbox testing
```

### Available Configuration Options

[](#available-configuration-options)

OptionDescriptionRequiredNotesbaseUrlAPI base URLYesUse sandbox URL for testingenvironment'sandbox' or 'production'YesStart with sandboxconsumerKeyYour M-Pesa API consumer keyYesKeep secureconsumerSecretYour M-Pesa API consumer secretYesKeep secureshortCodeYour M-Pesa shortcodeYes-passKeyYour M-Pesa passkeyFor STK Push-verifySSLWhether to verify SSL certificatesOptionalAlways true in productionFeatures Documentation
----------------------

[](#features-documentation)

### STK Push

[](#stk-push)

```
try {
    $mpesa->authenticate()
        ->setPhoneNumber('2517XXXXXXXX')
        ->setAmount(100)
        ->setAccountReference('INV' . time())   // Dynamic reference
        ->setTransactionDesc('Payment for Package')
        ->setCallbackUrl('https://your-domain.com/callback');

    // For sandbox testing only
    if ($config->getEnvironment() === 'sandbox') {
        $mpesa->setTestPassword('your-test-password');
    }

    $response = $mpesa->ussdPush();

    if ($mpesa->isSuccessful()) {
        echo "Transaction Details:\n";
        echo "Merchant Request ID: " . $mpesa->getMerchantRequestID() . "\n";
        echo "Checkout Request ID: " . $mpesa->getCheckoutRequestID() . "\n";
    }
} catch (MpesaException $e) {
    echo "M-Pesa Error: " . $e->getMessage();
}
```

### B2C Payment

[](#b2c-payment)

```
try {
    $result = $mpesa->authenticate()
        ->setInitiatorName('your_initiator')
        ->setSecurityCredential('your_security_credential')
        ->setCommandId('BusinessPayment')  // Options: SalaryPayment, BusinessPayment, PromotionPayment
        ->setAmount(100)
        ->setPartyA('your_shortcode')
        ->setPartyB('2517XXXXXXXX')
        ->setRemarks('Payment description')
        ->setOccasion('Optional reference')
        ->setQueueTimeOutUrl('https://your-domain.com/timeout')
        ->setResultUrl('https://your-domain.com/result')
        ->b2c();

    if ($result && $result->getResponseMessage()) {
        echo "B2C payment initiated successfully!";
        // Store conversation IDs for reconciliation
        $conversationId = $result->getConversationId();
        $originatorConversationId = $result->getOriginatorConversationId();
    }
} catch (MpesaException $e) {
    echo "Error: " . $e->getMessage();
}
```

### C2B Simulation

[](#c2b-simulation)

```
use MesaSDK\PhpMpesa\Models\C2BSimulationResponse;

try {
    /** @var C2BSimulationResponse $response */
    $response = $mpesa->authenticate()
        ->setC2BAmount(110.00)
        ->setC2BMsisdn('251945628580')
        ->setC2BBillRefNumber('091091')
        ->executeC2BSimulation();

    if ($response->isSuccessful()) {
        echo "C2B payment simulation initiated successfully!";
        echo "Response Code: " . $response->getResponseCode();
        echo "Conversation ID: " . $response->getConversationId();
        echo "Customer Message: " . $response->getCustomerMessage();
    } else {
        echo "C2B payment simulation failed: " . $response->getResponseDescription();
    }
} catch (MpesaException $e) {
    echo "Error: " . $e->getMessage();
}
```

### Account Balance Query

[](#account-balance-query)

```
try {
    $response = $mpesa->authenticate()
        ->setSecurityCredential("your-security-credential")
        ->setAccountBalanceInitiator('your_initiator')
        ->setAccountBalancePartyA('your_shortcode')
        ->setAccountBalanceRemarks('Balance check')
        ->setAccountBalanceIdentifierType('4')
        ->setQueueTimeOutUrl('https://your-domain.com/timeout')
        ->setResultUrl('https://your-domain.com/result')
        ->checkAccountBalance();

    // Handle immediate response
    if ($response['ResponseCode'] === '0') {
        echo "Balance query initiated successfully";
    }

    // If this is a result callback
    if (isset($response['Result'])) {
        $balanceInfo = $mpesa->parseBalanceResult($response);
        foreach ($balanceInfo as $account) {
            echo sprintf(
                "Account: %s\nCurrency: %s\nAmount: %s\n",
                $account['account'],
                $account['currency'],
                $account['amount']
            );
        }
    }
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
```

### C2B Validation and Confirmation

[](#c2b-validation-and-confirmation)

First, register your validation and confirmation URLs:

```
$response = $mpesa->authenticate()
    ->registerUrls(
        'https://your-domain.com/mpesa/confirm',
        'https://your-domain.com/mpesa/validate'
    );
```

#### Validation Endpoint

[](#validation-endpoint)

```
