PHP code example of karson / mpesa-php-sdk

1. Go to this page and download the library: Download karson/mpesa-php-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/ */

    

karson / mpesa-php-sdk example snippets


use Karson\MpesaPhpSdk\Mpesa;

// Initialize with your credentials from M-Pesa Developer Console (https://developer.mpesa.vm.co.mz/)
$mpesa = new Mpesa(
    publicKey: 'your_public_key',
    apiKey: 'your_api_key', 
    isTest: true, // false for production
    serviceProviderCode: '171717' // Your service provider code
);

// C2B Transaction (Unified API)
$response = $mpesa->c2b(
    transactionReference: 'TXN001',
    from: '258841234567',
    amount: 100,
    thirdPartReference: 'REF001'
);

if ($response->isTransactionSuccessful()) {
    echo "Transaction ID: " . $response->getTransactionId();
    echo "Conversation ID: " . $response->getConversationId();
    echo "Third Party Reference: " . $response->getThirdPartyReference();
} else {
    echo "Error: " . $response->getResponseDescription();
    echo "Error Code: " . $response->getResponseCode();
}

// Check transaction status
if ($response->isTransactionInitiated()) {
    echo "Transaction initiated. Use Conversation ID for status tracking.";
}

// B2C Transaction (Unified API)
$response = $mpesa->b2c(
    customerMSISDN: '258841234567',
    amount: 100,
    transactionReference: 'TXN002',
    thirdPartReference: 'REF002'
);

if ($response->isTransactionSuccessful()) {
    echo "Transaction ID: " . $response->getTransactionId();
    echo "Conversation ID: " . $response->getConversationId();
    echo "Third Party Reference: " . $response->getThirdPartyReference();
} else {
    echo "Error: " . $response->getResponseDescription();
}

$response = $mpesa->status(
    thirdPartyReference: 'REF001',
    queryReference: 'QUERY001'
);

// Access status information
echo "Transaction Status: " . $response->getTransactionStatus();
echo "Amount: " . $response->getAmount();
echo "Currency: " . $response->getCurrency();

$response = $mpesa->queryCustomerName(
    customerMSISDN: '258841234567',
    thirdPartyReference: 'REF003'
);

if ($response->isSuccessful()) {
    echo "Customer Name: " . $response->getCustomerName();
    echo "First Name: " . $response->getFirstName();
    echo "Last Name: " . $response->getLastName();
}

// B2B Transaction (Unified API)
$response = $mpesa->b2b(
    transactionReference: 'TXN003',
    amount: 100,
    thirdPartReference: 'REF003',
    primaryPartyCode: '171717', // Sender business code
    receiverPartyCode: '979797'  // Receiver business code
);

if ($response->isTransactionSuccessful()) {
    echo "B2B Transaction ID: " . $response->getTransactionId();
    echo "Conversation ID: " . $response->getConversationId();
    echo "Third Party Reference: " . $response->getThirdPartyReference();
} else {
    echo "Error: " . $response->getResponseDescription();
}

$response = $mpesa->reversal(
    transactionID: 'TXN123456',
    securityCredential: 'your_security_credential',
    initiatorIdentifier: 'your_initiator',
    thirdPartyReference: 'REF004',
    reversalAmount: '50' // Optional: partial refund
);

if ($response->isReversalSuccessful()) {
    echo "Refund Transaction ID: " . $response->getReversalTransactionId();
    echo "Refund Amount: " . $response->getReversalAmount();
    
    if ($response->isPartialReversal()) {
        echo "This was a partial refund";
    }
} else {
    echo "Refund failed: " . $response->getResponseDescription();
}

// Common methods available on all responses
$response->getTransactionId();          // Transaction ID
$response->getConversationId();         // Conversation ID for tracking
$response->getResponseCode();           // M-Pesa response code
$response->getResponseDescription();    // Response description
$response->getThirdPartyReference();    // Third party reference
$response->isTransactionSuccessful();   // Check if transaction succeeded
$response->isTransactionInitiated();    // Check if transaction was initiated
$response->getStatusCode();             // HTTP status code
$response->getRawResponse();            // Raw API response
$response->isSuccessful();              // HTTP success check
$response->isApiSuccess();              // M-Pesa API success check

use Karson\MpesaPhpSdk\Mpesa;
use Karson\MpesaPhpSdk\Callback\CallbackHandler;

class PaymentController extends Controller
{
    public function __construct(
        private Mpesa $mpesa,
        private CallbackHandler $callbackHandler
    ) {
    }
    
    public function processPayment(Request $request)
    {
        $response = $this->mpesa->c2b(
            transactionReference: $request->transaction_ref,
            from: $request->phone_number,
            amount: $request->amount,
            thirdPartReference: $request->reference
        );
        
        if ($response->isTransactionSuccessful()) {
            // Handle successful payment
            return response()->json([
                'success' => true,
                'transaction_id' => $response->getTransactionId(),
                'conversation_id' => $response->getConversationId(),
                'third_party_reference' => $response->getThirdPartyReference()
            ]);
        }
        
        return response()->json([
            'success' => false,
            'message' => $response->getResponseDescription(),
            'error_code' => $response->getResponseCode()
        ], 400);
    }
    
    public function handleCallback(Request $request)
    {

            $response = $request->getContent(),
            
          ...
        
    }
}

$response = $mpesa->c2b('TXN001', '258841234567', 100, 'REF001');

// Check HTTP status
if (!$response->isSuccessful()) {
    echo "HTTP Error: " . $response->getStatusCode();
}

// Check transaction status
if (!$response->isTransactionSuccessful()) {
    echo "Transaction Error: " . $response->getResponseDescription();
    echo "Error Code: " . $response->getResponseCode();
}

// Check if transaction was initiated (for async processing)
if ($response->isTransactionInitiated()) {
    echo "Transaction initiated. Conversation ID: " . $response->getConversationId();
}

// Get raw response for debugging
var_dump($response->getRawResponse());

// All transaction types use the same response structure
$c2bResponse = $mpesa->c2b('TXN001', '258841234567', 100, 'REF001');
$b2cResponse = $mpesa->b2c('258841234567', 100, 'TXN002', 'REF002');
$b2bResponse = $mpesa->b2b('TXN003', 100, 'REF003', '171717', '979797');

// All responses have the same methods available
foreach ([$c2bResponse, $b2cResponse, $b2bResponse] as $response) {
    if ($response->isTransactionSuccessful()) {
        echo "Transaction ID: " . $response->getTransactionId();
        echo "Conversation ID: " . $response->getConversationId();
        echo "Third Party Reference: " . $response->getThirdPartyReference();
    }
}

// Initiate transaction
$response = $mpesa->c2b('TXN001', '258841234567', 100, 'REF001');

if ($response->isTransactionInitiated()) {
    $conversationId = $response->getConversationId();
    
    // Later, check the status
    $statusResponse = $mpesa->queryTransactionStatus('REF001', 'QUERY001');
    
    if ($statusResponse->isTransactionCompleted()) {
        echo "Transaction completed successfully";
        echo "Amount: " . $statusResponse->getAmount();
        echo "Currency: " . $statusResponse->getCurrency();
    } elseif ($statusResponse->isTransactionPending()) {
        echo "Transaction is still pending";
    } elseif ($statusResponse->isTransactionFailed()) {
        echo "Transaction failed";
    }
}

use Karson\MpesaPhpSdk\Exceptions\ValidationException;
use Karson\MpesaPhpSdk\Exceptions\AuthenticationException;
use Karson\MpesaPhpSdk\Exceptions\ApiException;
use Karson\MpesaPhpSdk\Exceptions\CallbackException;

try {
    $response = $mpesa->c2b('TXN001', '258841234567', 100, 'REF001');
    
} catch (ValidationException $e) {
    echo "Validation Error: " . $e->getMessage();
    foreach ($e->getErrors() as $error) {
        echo "- " . $error . "\n";
    }
    
} catch (AuthenticationException $e) {
    echo "Authentication failed: " . $e->getMessage();
    
} catch (ApiException $e) {
    echo "API Error: " . $e->getMessage();
    echo "Response Code: " . $e->getResponseCode();
    echo "Response Description: " . $e->getResponseDescription();
    
} catch (CallbackException $e) {
    echo "Callback Error: " . $e->getMessage();
    if ($e->getCallbackData()) {
        echo "Callback Data: " . json_encode($e->getCallbackData());
    }
    
} catch (Exception $e) {
    echo "General Error: " . $e->getMessage();
}

// Get token manager
$tokenManager = $mpesa->getTokenManager();

// Get token (generated automatically if needed)
$token = $mpesa->getToken();
echo "Token: " . substr($token, 0, 20) . "...";

// Clear stored token
$tokenManager->clearToken();

// Get token (automatically generated if needed)
$token = $mpesa->getToken();

// For long-running processes, clear and regenerate periodically
while ($process->isRunning()) {
    // Clear token periodically (e.g., every hour) to force regeneration
    if ($shouldRefreshToken) {
        $tokenManager->clearToken();
    }
    
    // Your API calls here (token will be generated automatically if needed)
    $response = $mpesa->receive(...);
    
    sleep(60);
}

use Karson\MpesaPhpSdk\Validation\ParameterValidator;

// Validate MSISDN format
if (!ParameterValidator::validateMSISDN('258841234567')) {
    echo "Invalid phone number format";
}

// Validate transaction parameters
$params = [
    'transactionReference' => 'TXN001',
    'customerMSISDN' => '258841234567',
    'amount' => 100,
    'thirdPartyReference' => 'REF001',
    'serviceProviderCode' => '171717'
];

$errors = ParameterValidator::validateC2BParameters($params);
if (!empty($errors)) {
    foreach ($errors as $error) {
        echo "Validation Error: " . $error . "\n";
    }
}

use Karson\MpesaPhpSdk\Constants\ResponseCodes;
use Karson\MpesaPhpSdk\Constants\TransactionStatus;

$response = $mpesa->receive('TXN001', '258841234567', 100, 'REF001');

// Check using constants
if ($response->getResponseCode() === ResponseCodes::SUCCESS) {
    echo "Transaction successful!";
}

// Check transaction status using constants
$statusResponse = $mpesa->status('REF001', 'QUERY001');
if (TransactionStatus::isCompleted($statusResponse->getTransactionStatus())) {
    echo "Transaction completed successfully";
} elseif (TransactionStatus::isPending($statusResponse->getTransactionStatus())) {
    echo "Transaction is still pending";
} elseif (TransactionStatus::isFailed($statusResponse->getTransactionStatus())) {
    echo "Transaction failed";
}

// Before v2.0 (multiple response classes)
$c2bResponse = $mpesa->c2b(...); // Returns C2BSyncResponse
$b2cResponse = $mpesa->b2c(...); // Returns B2CSyncResponse  
$b2bResponse = $mpesa->b2b(...); // Returns B2BSyncResponse

// v2.0+ (unified response)
$c2bResponse = $mpesa->c2b(...); // Returns TransactionResponse
$b2cResponse = $mpesa->b2c(...); // Returns TransactionResponse
$b2bResponse = $mpesa->b2b(...); // Returns TransactionResponse

// Before v2.0
$transactionId = $response->getData()['output_TransactionID'];

// v2.0+ (better type safety)
$transactionId = $response->getTransactionId();

// New methods available on all responses
$response->getThirdPartyReference();  // Available on all transaction responses
$response->isTransactionInitiated();  // Check if async transaction started
$response->isApiSuccess();            // Check M-Pesa API success
bash
composer