PHP code example of botnetdobbs / laravel-mpesa-sdk

1. Go to this page and download the library: Download botnetdobbs/laravel-mpesa-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

botnetdobbs / laravel-mpesa-sdk example snippets


return [
    "consumer_key" => env("MPESA_CONSUMER_KEY"),
    "consumer_secret" => env("MPESA_CONSUMER_SECRET"),
    "lipa_na_mpesa_passkey" => env(
        "MPESA_LIPA_NA_MPESA_PASSKEY",
        "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919"
    ),
    "certificate_path" => env("MPESA_CERTIFICATE_PATH"),
    "environment" => env("MPESA_ENV", "sandbox"),
    "initiator" => [
        'name' => env("MPESA_INITIATOR_NAME"),
        'password' => env("MPESA_INITIATOR_PASSWORD"),
    ],
    "callbacks" => [
        "base_url" => env("MPESA_CALLBACK_BASE_URL", "https://example.com"),
        "paths" => [
            "stk" => [
                "result" => "/api/mpesa/callback/stk",
            ],
            "b2c" => [
                "result" => "/api/mpesa/callback/b2c",
                "timeout" => "/api/mpesa/callback/b2c/timeout",
            ],
            // Add more callback paths here
        ]
    ],
    "business" => [
        "short_codes" => [
            "default" => env("MPESA_SHORT_CODE"),
            "till" => env("MPESA_TILL_NUMBER"),
            "paybill" => env("MPESA_PAYBILL_NUMBER"),
        ],

    ],
    "defaults" => [
        "timeout" => 30,
        "connect_timeout" => 10,
    ]
];

use Botnetdobbs\Mpesa\Contracts\Client;

class PaymentController extends Controller
{
    public function __construct(
        private readonly Client $mpesaClient
    ) {}

    public function initiatePayment()
    {
        $response = $this->mpesaClient->stkPush([...]);
    }
}



$response = $this->mpesaClient->stkPush([
    "BusinessShortCode" => "174379",    // Organization's shortcode  (Paybill or Buygoods - A 5 to 6-digit account number) used to identify an organization and receive the transaction.
    "TransactionType" => "CustomerPayBillOnline",    // or CustomerBuyGoodsOnline
    "Amount" => 1,
    "PhoneNumber" => "254722000000", // The Mobile Number to receive the STK Pin Prompt.
    "CallBackURL" => config('mpesa.callbacks.base_url', "https://example.com") . config('mpesa.callbacks.paths.stk_push.result', "/callback"),    // Valid secure URL that is used to receive notifications from M-Pesa API.
    "AccountReference" => "Test",
    "TransactionDesc" => "Test Payment"
]);


$response = $this->mpesaClient->stkQuery([
    "BusinessShortCode" => "174379",
    "CheckoutRequestID" => "ws_CO_260520211133524545"
]);


$response = $this->mpesaClient->b2c([
    "OriginatorConversationID" => "unique-id",
    "InitiatorName" => "testapi",
    "CommandID" => "BusinessPayment",  // Or "SalaryPayment", "PromotionPayment"
    "Amount" => 100,
    "PartyA" => "600000",      // Your business shortcode
    "PartyB" => "254722000000", // Customer phone number
    "Remarks" => "Test payment",
    "QueueTimeOutURL" => "https://example.com/queue-timeout",   // The URL to be specified in your request that will be used by API Proxy to send notification incase the payment request is timed out while awaiting processing in the queue.
    "ResultURL" => "https://example.com/result",    // The URL to be specified in your request that will be used by M-PESA to send notification upon processing of the payment request.
    "Occasion" => "Test"
]);


$response = $this->mpesaClient->b2b([
    "primaryShortCode" => "000001",    // Sender business shortcode
    "receiverShortCode" => "000002",   // Receiver business shortcode
    "amount" => 100,
    "paymentRef" => "INV001",          // Your reference
    "callbackUrl" => "https://example.com/callback",
    "partnerName" => "Vendor Name",
    "RequestRefID" => "unique-id-123"   // Unique identifier for the request
]);


$response = $this->mpesaClient->c2bRegister([
    "ShortCode" => "600000",
    "ResponseType" => "Completed",      // Or "Cancelled"
    "ConfirmationURL" => "https://example.com/confirmation",    // The URL that receives the confirmation request from API upon payment completion.
    "ValidationURL" => "https://example.com/validation",    // The URL that receives the validation request from the API upon payment submission. The validation URL is only called if the external validation on the registered shortcode is enabled. (By default External Validation is disabled).
]);


$response = $this->mpesaClient->c2bSimulate([
    "ShortCode" => "600000",
    "CommandID" => "CustomerPayBillOnline",  // Or "CustomerBuyGoodsOnline"
    "Amount" => 100,
    "Msisdn" => "254722000000",             // Customer phone number
    "BillRefNumber" => "INV001"             // Optional reference
]);


$response = $this->mpesaClient->accountBalance([
    "Initiator" => "testapi",   // The credential/username used to authenticate the transaction request
    "CommandID" => "AccountBalance",
    "PartyA" => "600000",              // Your business shortcode
    "IdentifierType" => "4",           // 4 for organization shortcode
    "Remarks" => "Balance query",
    "QueueTimeOutURL" => "https://example.com/timeout", // The end-point that receives a timeout message.
    "ResultURL" => "https://example.com/result",    // It indicates the destination URL which Daraja should send the result message to.
]);


$response = $this->mpesaClient->transactionStatus([
    "Initiator" => "testapi",
    "CommandID" => "TransactionStatusQuery",
    "TransactionID" => "OEI2AK4Q16",    // The M-Pesa transaction ID
    "PartyA" => "600000",               // Your business shortcode
    "IdentifierType" => "4",            // 4 for organization shortcode
    "ResultURL" => "https://example.com/result",
    "QueueTimeOutURL" => "https://example.com/timeout",
    "Remarks" => "Status check",
    "Occasion" => "Transaction query",  // Optional parameter
]);


$response = $this->mpesaClient->reversal([
    "Initiator" => "testapi",
    "CommandID" => "TransactionReversal",
    "TransactionID" => "OEI2AK4Q16",     // The M-Pesa transaction ID to reverse
    "Amount" => 100,                      // Amount to reverse
    "ReceiverParty" => "600000",         // Organization receiving the reversal
    "RecieverIdentifierType" => "4",      // 4 for organization shortcode
    "ResultURL" => "https://example.com/result",
    "QueueTimeOutURL" => "https://example.com/timeout",
    "Remarks" => "Reversal request",
    "Occasion" => "Transaction reversal"
]);

// Get the raw response data
$data = $response->getData(): object

// Check if the request was successful
$isSuccessful = $response->isSuccessful(): bool

// Get specific response fields
$code = $response->getResponseCode(): int
$description = $response->getResponseDescription(): string

$resultCode = $response->getResultCode(): int // STK Query
$resultDescription = $response->getResultDescription(): string // STK Query

$response = $this->mpesaClient->stkPush([...]);
$data = $response->getData();

// Access properties using object syntax
$merchantRequestId = $data->MerchantRequestID;
$checkoutRequestId = $data->CheckoutRequestID;

use Botnetdobbs\Mpesa\Exceptions\MpesaException;
try {
    $response = $this->mpesaClient->stkPush([...]);
    if ($response->isSuccessful()) {
        $data = $response->getData();
    }
} catch (MpesaException $e) {
    // Handle the error
    logger()->error("M-Pesa error: " . $e->getMessage());
}

use App\Http\Controllers\MpesaCallbackController;

Route::prefix('mpesa/callback')->group(function () {
    Route::post('stkpush', [MpesaCallbackController::class, 'handleStkCallback']);
});

namespace App\Http\Controllers;

use Botnetdobbs\Mpesa\Contracts\CallbackProcessor;
use Botnetdobbs\Mpesa\Contracts\CallbackResponder;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;

class MpesaCallbackController extends Controller
{
    public function __construct(
        private readonly CallbackProcessor $processor,
        private readonly CallbackResponder $responder
    ) {}

    public function handleStkCallback(Request $request): Response
    {
        try {
            $result = $this->processor->handleStkCallback($request);

            if ($result->isSuccessful()) {
                $data = $result->getData();

                if (isset($data->Body->stkCallback)) {
                    Log::info('STK Push payment successful', [
                        'merchantRequestId' => $data->Body->stkCallback->MerchantRequestID,
                        'checkoutRequestId' => $data->Body->stkCallback->CheckoutRequestID,
                    ]);
                }
                
                // Update your database, trigger events, etc.
                return $this->responder->success('Payment processed');
            } 
            Log::warning('STK Push payment failed', [
                'code' => $result->getResultCode(),
                'description' => $callback->getResultDescription()
            ]);

            return $this->responder->success('Failed payment');
        } catch (\Exception $e) {
            Log::error('Error processing STK callback', [
                'error' => $e->getMessage()
            ]);
            return $this->responder->failed('Internal server error');
        }
    }

    // Implement other callback handlers similarly...
}

$result->getData(): object // Get the raw callback data.
$result->isSuccessful(): bool
$result->getResultCode(): int
$result->getResultDescription(): string
bash
php artisan vendor:publish --tag=mpesa-config