A comprehensive PHP package for integrating with Safaricom's M-Pesa DARAJA API. This package provides a simple, "Identity-First" interface for all M-Pesa API endpoints including STK Push, B2C, B2B, C2B, and more.
- Identity-First Architecture - Explicit control over credentials and callbacks per request or configuration group.
- Complete Transaction Support - Covers STK Push, B2C, B2B, B2Pochi, C2B, Reversal, Account Balance, and Transaction Status.
- Service Properties - Direct, type-hinted access to services (e.g., $mpesa->stk, $mpesa->b2c).
- Smart Validation - Automatic metadata sanitization, field trimming, and parameter normalization.
- Universal Callbacks - Simplified logic for handling STK, C2B, and result notifications.
- Modern PHP - Built for PHP 8.0+ with strict typing and dependency injection.
- Framework Agnostic - Works with any PHP project (Laravel, Symfony, or pure PHP).
- Secure by Default - SSL peer verification enabled with automatic certificate management.
- PHP 8.0 or higher
- cURL extension enabled
- OpenSSL extension enabled
- JSON extension enabled
composer require yourdudeken/mpesa- Download the source code as a zip file.
- Extract it to your project directory.
- Include the autoloader in your code:
<?php
require "{PATHTOTHISLIBFOLDER}/src/autoload.php";
use Yourdudeken\Mpesa\Init as Mpesa;<?php
require "vendor/autoload.php";
use Yourdudeken\Mpesa\Init as Mpesa;
$mpesa = new Mpesa([
'is_sandbox' => true,
// Auth: Required for ALL requests
'auth' => [
'consumer_key' => 'YOUR_CONSUMER_KEY',
'consumer_secret' => 'YOUR_CONSUMER_SECRET',
],
// Initiator: Required for Business APIs (B2C, B2B, etc.)
'initiator' => [
'name' => 'YOUR_INITIATOR_NAME',
'password' => 'YOUR_INITIATOR_PASSWORD',
],
// Service Defaults (Optional)
'stk' => [
'short_code' => '174379',
'passkey' => 'YOUR_LNMO_PASSKEY',
]
]);
try {
// Initiate STK Push
$response = $mpesa->stk->submit([
'amount' => 10,
'phone' => '2547XXXXXXXX',
'reference' => 'Order-001',
'description' => 'Payment for Goods',
'callback_url' => 'https://example.com/mpesa/callback'
]);
echo json_encode($response);
} catch(\Exception $e) {
echo "Error: " . $e->getMessage();
}The package uses a structured, grouped configuration for better organization.
src/config/mpesa.php
return [
'is_sandbox' => true,
// OAuth Credentials
'auth' => [
'consumer_key' => 'your_key',
'consumer_secret' => 'your_secret',
],
// Business Initiator (B2C, B2B, Reversal)
'initiator' => [
'name' => 'testapi',
'password' => 'Safaricom123!!',
],
// Service Specific Defaults
'stk' => [
'short_code' => '174379',
'passkey' => 'bfb27...',
'callback' => 'https://api.com/mpesa/stk', // Note: key is 'callback', not 'callback_url'
'transaction_type' => 'CustomerPayBillOnline',
],
'c2b' => [
'command_id' => 'CustomerPayBillOnline',
'response_type' => 'Completed',
],
// Certificate Paths (Optional override)
'certificate_path_production' => '/path/to/ProductionCertificate.cer',
];$mpesa->stk->submit([
'amount' => 100,
'phone' => '2547XXXXXXXX',
'reference' => 'ORDER-123',
'description' => 'Payment for order'
]);$mpesa->stkStatus->submit([
'checkoutRequestID' => 'ws_CO_191220191020363925'
]);$mpesa->b2c->submit([
'amount' => 500,
'phone' => '2547XXXXXXXX',
'remarks' => 'Salary Payment'
]);$mpesa->b2b->submit([
'amount' => 1000,
'short_code' => '600000',
'remarks' => 'Supplier Payment'
]);$mpesa->b2pochi->submit([
'amount' => 100,
'phone' => '2547XXXXXXXX',
'remarks' => 'Tip'
]);$mpesa->c2b->submit([
'confirmation_url' => 'https://domain.com/confirm',
'validation_url' => 'https://domain.com/validate'
]);$mpesa->c2bSimulate->submit([
'amount' => 100,
'phone' => '2547XXXXXXXX',
'bill_ref' => 'INV-001'
]);$mpesa->balance->submit([
'result_url' => 'https://domain.com/result'
]);$mpesa->status->submit([
'transaction_id' => 'NLJ7RT61SV',
'result_url' => 'https://domain.com/result'
]);$mpesa->reversal->submit([
'transaction_id' => 'NLJ7RT61SV',
'amount' => 100,
'result_url' => 'https://domain.com/result'
]);Detailed documentation for each endpoint is available in the docs folder:
- Lipa na M-Pesa Online (STK Push)
- C2B (Customer to Business)
- B2C (Business to Customer)
- B2B (Business to Business)
- B2Pochi (Business to Pochi)
- Transaction Status
- Reversal
- Account Balance
- Detailed Package Overview
<?php
// Get callback data
$callbackData = file_get_contents('php://input');
$callback = json_decode($callbackData, true);
// Extract result
$resultCode = $callback['Body']['stkCallback']['ResultCode'];
if ($resultCode == 0) {
// Payment successful
$metadata = $callback['Body']['stkCallback']['CallbackMetadata']['Item'];
// Process items (Amount, MpesaReceiptNumber, etc.)
}
// Respond to Safaricom
header('Content-Type: application/json');
echo json_encode(['ResultCode' => 0, 'ResultDesc' => 'Success']);Run unit tests using:
vendor/bin/phpunit- Never commit credentials - Use environment variables or secure vault.
- Use HTTPS - All callback URLs must use HTTPS in production.
- Validate callbacks - Verify payloads are from Safaricom.
- Logic Idempotency - Handle duplicate callback notifications.
- Log Transactions - Maintain local audit trails.
- Email: kenmwendwamuthengi@gmail.com
- Telegram: @yourdudeken
- Issues: GitHub Issues
Inspired by the work of @SmoDav on the mpesa project.
Open-sourced under the MIT license.
Made in Kenya