Transaction Status
The transaction status endpoint allows you to check the current status of a payment using the transaction reference returned from the STK push initiation. This is useful for polling payment status or verifying payment completion.
Endpoint
GET /payments/status?reference=TRANSACTION_REFERENCERequest Headers
Authorization: Bearer YOUR_API_KEYQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | String | âś… | The transaction reference returned from STK push initiation |
Success Response
Pending Payment
{
"success": true,
"status": "success",
"message": "Payment status: Payment is still being processed",
"customerMessage": "Payment is still being processed",
"data": {
"response": {
"Amount": 100,
"ExternalReference": "order_123",
"MerchantRequestID": "12345-67890-12345-67890",
"MpesaReceiptNumber": "",
"Phone": "254712345678",
"ResultCode": 0,
"ResultDesc": "Payment is still being processed",
"Metadata": {
"order_id": "12345",
"customer_name": "John Doe"
},
"Status": "PENDING",
"TransactionDate": "2024-01-15T10:30:00.000Z"
},
"status": false
},
"timestamp": "2024-01-15T10:30:00.000Z"
}Successful Payment
{
"success": true,
"status": "success",
"message": "Payment status: Payment completed successfully",
"customerMessage": "Payment completed successfully",
"data": {
"response": {
"Amount": 100,
"ExternalReference": "order_123",
"MerchantRequestID": "12345-67890-12345-67890",
"MpesaReceiptNumber": "NEF61H8J60",
"Phone": "254712345678",
"ResultCode": 0,
"ResultDesc": "Payment completed successfully",
"Metadata": {
"order_id": "12345",
"customer_name": "John Doe"
},
"Status": "SUCCESS",
"TransactionDate": "2024-01-15T10:35:00.000Z"
},
"status": true
},
"timestamp": "2024-01-15T10:35:00.000Z"
}Failed Payment
{
"success": true,
"status": "success",
"message": "Payment status: Payment failed",
"customerMessage": "Payment failed",
"data": {
"response": {
"Amount": 100,
"ExternalReference": "order_123",
"MerchantRequestID": "12345-67890-12345-67890",
"MpesaReceiptNumber": "",
"Phone": "254712345678",
"ResultCode": 1,
"ResultDesc": "The initiator information is invalid",
"Metadata": {
"order_id": "12345",
"customer_name": "John Doe"
},
"Status": "FAILED",
"TransactionDate": "2024-01-15T10:32:00.000Z"
},
"status": false
},
"timestamp": "2024-01-15T10:32:00.000Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
Amount | Number | Payment amount in Kenyan Shillings |
ExternalReference | String | Your reference ID for tracking |
MerchantRequestID | String | Internal merchant request identifier |
MpesaReceiptNumber | String | Receipt number (empty for pending/failed payments) |
Phone | String | Customer's phone number |
ResultCode | Number | Payment result code (0 = success, >0 = error) |
ResultDesc | String | Human-readable result description |
Metadata | Object | Additional data stored with the payment |
Status | String | Payment status: PENDING, SUCCESS, or FAILED |
TransactionDate | String | ISO timestamp of last status update |
status | Boolean | true for successful payments, false for failed/pending |
Payment States
PENDING
- Payment has been initiated
- Customer has not yet entered their PIN
- No receipt number available
statusfield isfalse
SUCCESS
- Payment completed successfully
- Customer has entered PIN and payment processed
- Receipt number is available
statusfield istrue
FAILED
- Payment failed for various reasons
- Customer cancelled, insufficient funds, or system error
- No receipt number available
statusfield isfalse
Error Responses
Transaction Not Found
{
"success": false,
"status": "error",
"message": "Transaction not found",
"customerMessage": "Transaction not found",
"error": {
"code": "NOT_FOUND",
"field": "reference",
"location": "query",
"value": "invalid_reference",
"expected": "Valid transaction reference"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}Invalid Reference Format
{
"success": false,
"status": "error",
"message": "Invalid reference format",
"customerMessage": "Please provide a valid transaction reference",
"error": {
"code": "VALIDATION_ERROR",
"field": "reference",
"location": "query",
"value": "",
"expected": "Non-empty transaction reference"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}Code Examples
JavaScript/Node.js
const checkPaymentStatus = async (transactionReference) => {
try {
const response = await fetch(
`https://lipia-api.kreativelabske.com/api/v2/payments/status?reference=${transactionReference}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.LIPIA_API_KEY}`
}
}
);
const result = await response.json();
if (result.success) {
const paymentData = result.data.response;
console.log('Payment Status:', paymentData.Status);
console.log('Amount:', paymentData.Amount);
console.log('Receipt Number:', paymentData.MpesaReceiptNumber);
return paymentData;
} else {
console.error('Status check failed:', result.message);
throw new Error(result.customerMessage);
}
} catch (error) {
console.error('Error checking payment status:', error);
throw error;
}
};
// Usage
const transactionRef = '64f1a2b3c4d5e6f7g8h9i0j1';
checkPaymentStatus(transactionRef);Python
import requests
import os
def check_payment_status(transaction_reference):
api_key = os.getenv('LIPIA_API_KEY')
base_url = os.getenv('LIPIA_BASE_URL')
headers = {
'Authorization': f'Bearer {api_key}'
}
try:
response = requests.get(
f'{base_url}/payments/status',
headers=headers,
params={'reference': transaction_reference}
)
result = response.json()
if result['success']:
payment_data = result['data']['response']
print(f"Payment Status: {payment_data['Status']}")
print(f"Amount: {payment_data['Amount']}")
print(f"Receipt Number: {payment_data['MpesaReceiptNumber']}")
return payment_data
else:
print(f"Status check failed: {result['message']}")
raise Exception(result['customerMessage'])
except requests.exceptions.RequestException as e:
print(f"Error checking payment status: {e}")
raise
# Usage
transaction_ref = '64f1a2b3c4d5e6f7g8h9i0j1'
check_payment_status(transaction_ref)PHP
<?php
function checkPaymentStatus($transactionReference) {
$apiKey = $_ENV['LIPIA_API_KEY'];
$baseUrl = $_ENV['LIPIA_BASE_URL'];
$headers = [
'Authorization: Bearer ' . $apiKey
];
$url = $baseUrl . '/payments/status?reference=' . urlencode($transactionReference);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
if ($result['success']) {
$paymentData = $result['data']['response'];
echo "Payment Status: " . $paymentData['Status'] . "\n";
echo "Amount: " . $paymentData['Amount'] . "\n";
echo "Receipt Number: " . $paymentData['MpesaReceiptNumber'] . "\n";
return $paymentData;
} else {
echo "Status check failed: " . $result['message'] . "\n";
throw new Exception($result['customerMessage']);
}
} else {
throw new Exception("HTTP Error: " . $httpCode);
}
}
// Usage
$transactionRef = '64f1a2b3c4d5e6f7g8h9i0j1';
checkPaymentStatus($transactionRef);
?>Polling Strategy(optional)
Polling is a technique where your application repeatedly checks the transaction status at regular intervals using the transaction reference. This allows you to provide users with real-time feedback on the progress of their payment—whether it is still pending, has succeeded, or has failed.
By implementing polling, you can keep your users informed about their payment status directly within your app or website, without waiting for a callback or manual refresh.
Simple Polling
const pollPaymentStatus = async (transactionReference, maxAttempts = 30) => {
for (let i = 0; i < maxAttempts; i++) {
try {
const status = await checkPaymentStatus(transactionReference);
if (status.Status === 'SUCCESS') {
console.log('Payment successful!');
return status;
} else if (status.Status === 'FAILED') {
console.log('Payment failed:', status.ResultDesc);
throw new Error('Payment failed');
}
// Wait 5 seconds before next check
await new Promise(resolve => setTimeout(resolve, 5000));
} catch (error) {
console.error('Error polling status:', error);
throw error;
}
}
throw new Error('Payment timeout');
};Continue to Handling Callback to learn about callback webhook notifications.