Transaction Status

Transaction Status

The Transaction Status API allows you to check the status of any M-Pesa transaction using the transaction ID or checkout request ID. This is useful for tracking payments and reconciling transactions.

Basic Usage

try {
    // Initialize configuration
    $config = new Config();
    $config->setEnvironment($settings['environment'])
        ->setBaseUrl($settings['base_url'])
        ->setConsumerKey($settings['consumer_key'])
        ->setConsumerSecret($settings['consumer_secret'])
        ->setShortCode($settings['shortcode'])
        ->setVerifySSL(false); // Note: Always use true in production
 
    // Initialize M-Pesa client
    $mpesa = new Mpesa($config);
 
    // Authenticate
    $mpesa->authenticate();
 
    // Query transaction status using fluent API
    /** @var TransactionStatusResponse $response */
    $response = $mpesa
        ->setStatusInitiator('apitest')
        ->setStatusSecurityCredential('lMhf0UqE4ydeEDwpUskmPgkNDZnA6NLi7z3T1TQuWCkH3/ScW8pRRnobq/AcwFvbC961+zDMgOEYGm8Oivb7L/7Y9ED3lhR7pJvnH8B1wYis5ifdeeWI6XE2NSq8X1Tc7QB9Dg8SlPEud3tgloB2DlT+JIv3ebIl/J/8ihGVrq499bt1pz/EA2nzkCtGeHRNbEDxkqkEnbioV0OM//0bv4K++XyV6jUFlIIgkDkmcK6aOU8mPBHs2um9aP+Y+nTJaa6uHDudRFg0+3G6gt1zRCPs8AYbts2IebseBGfZKv5K6Lqk9/W8657gEkrDZE8Mi78MVianqHdY/8d6D9KKhw==')
        ->setTransactionId('0')
        ->setResultUrl($settings['result_url'])
        ->setQueueTimeOutUrl($settings['timeout_url'])
        ->setRemarks('Transaction Status Query')
        ->setStatusOccasion('Query trans status')
        ->queryTransactionStatus();
 
    // Check if request was successful
    if ($response->isSuccessful()) {
        echo "Transaction status query initiated successfully\n";
 
        // Access specific transaction details using the model methods
        echo "Transaction Status: " . $response->getTransactionStatus() . "\n";
        echo "Amount: " . $response->getAmount() . "\n";
        echo "Transaction Date: " . $response->getTransactionDate() . "\n";
        echo "Phone Number: " . $response->getPhoneNumber() . "\n";
        echo "Receipt Number: " . $response->getReceiptNumber() . "\n";
        echo "Debit Party: " . $response->getDebitPartyName() . "\n";
        echo "Credit Party: " . $response->getCreditPartyName() . "\n";
 
        // Check if transaction is completed
        if ($response->isCompleted()) {
            echo "Transaction is completed\n";
        } else {
            echo "Transaction is not completed\n";
        }
 
        // Get any additional parameter
        $customParam = $response->getResultParameter('CustomKey', 'default value');
        echo "Custom Parameter: " . $customParam . "\n";
 
        // Get all data as array or JSON
        echo "All Data (JSON): " . $response->toJson() . "\n";
    } else {
        echo "Transaction status query failed\n";
        echo "Error Code: " . $response->getResultCode() . "\n";
        echo "Error Description: " . $response->getResultDesc() . "\n";
    }
 
} catch (MpesaException $e) {
    echo "M-Pesa Error: " . $e->getMessage() . "\n";
} catch (\Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

Configuration

Before using Transaction Status API, ensure you have configured:

  1. Shortcode: Your M-Pesa shortcode
  2. Initiator Name: Your M-Pesa initiator name
  3. Initiator Password: Your M-Pesa initiator password
  4. Callback URLs: URLs to receive transaction notifications
  5. Environment: Sandbox or Production

Methods

setTransactionID(string $id)

Sets the transaction ID to check.

$mpesa->setTransactionID("QK4R7GXG");

setCheckoutRequestID(string $id)

Sets the checkout request ID to check.

$mpesa->setCheckoutRequestID("ws_CO_123456789");

setCallbackUrl(string $url)

Sets the callback URL for transaction notifications.

$mpesa->setCallbackUrl("https://your-domain.com/callback");

setQueueTimeOutUrl(string $url)

Sets the queue timeout URL.

$mpesa->setQueueTimeOutUrl("https://your-domain.com/timeout");

setResultUrl(string $url)

Sets the result URL.

$mpesa->setResultUrl("https://your-domain.com/result");

send()

Initiates the transaction status check.

$result = $mpesa->send();

Response Handling

The Transaction Status response includes:

  • TransactionID: Unique identifier for the transaction
  • ConversationID: Unique identifier for the conversation
  • OriginatorConversationID: Original conversation ID
  • ResponseCode: Response code from M-Pesa
  • ResponseDescription: Description of the response
  • TransactionStatus: Current status of the transaction
if ($result->isSuccessful()) {
    echo "Transaction ID: " . $result->getTransactionID();
    echo "Status: " . $result->getTransactionStatus();
    echo "Description: " . $result->getResponseDescription();
} else {
    echo "Error: " . $result->getErrorMessage();
}

Transaction Statuses

Common transaction statuses include:

  • Success: Transaction completed successfully
  • Failed: Transaction failed
  • Pending: Transaction is being processed
  • Cancelled: Transaction was cancelled
  • Invalid: Transaction is invalid

Best Practices

  1. Error Handling

    • Implement comprehensive error handling
    • Log all status checks
    • Monitor failed checks
  2. Callback Processing

    • Process callbacks asynchronously
    • Implement retry mechanisms
    • Validate callback data
  3. Security

    • Use HTTPS for all URLs
    • Implement proper authentication
    • Secure sensitive data
  4. Testing

    • Test in sandbox environment first
    • Test with various transaction IDs
    • Verify callback handling

Example Implementation

Here's a complete example of checking transaction status:

try {
    $result = $mpesa
        ->setTransactionID($transactionId)
        ->setCallbackUrl($callbackUrl)
        ->setQueueTimeOutUrl($timeoutUrl)
        ->setResultUrl($resultUrl)
        ->send();
 
    if ($result->isSuccessful()) {
        $status = $result->getTransactionStatus();
        $description = $result->getResponseDescription();
 
        // Log the status check
        logTransactionStatus($transactionId, $status, $description);
 
        // Update database with status
        updateTransactionStatus($transactionId, $status);
 
        // Handle different statuses
        switch ($status) {
            case 'Success':
                processSuccessfulTransaction($transactionId);
                break;
            case 'Failed':
                processFailedTransaction($transactionId);
                break;
            case 'Pending':
                scheduleStatusCheck($transactionId);
                break;
            default:
                logUnknownStatus($transactionId, $status);
        }
    } else {
        // Handle error
        logError($transactionId, $result->getErrorMessage());
        notifyAdmin($transactionId, $result->getErrorMessage());
    }
} catch (Exception $e) {
    // Handle exception
    logException($transactionId, $e);
    notifyAdmin($transactionId, $e->getMessage());
}

Callback Processing

Create an endpoint to handle transaction status callbacks:

// callback.php
$callbackData = json_decode(file_get_contents('php://input'), true);
 
// Process the callback
processTransactionStatusCallback($callbackData);
 
// Send response
header('Content-Type: application/json');
echo json_encode([
    'ResultCode' => 0,
    'ResultDesc' => 'Success'
]);

Related Topics