STK Push API (v3)
Initiate M-Pesa STK pushes and receive callbacks.
STK Push Flow
Initiate STK Push
Send payment request to customer's phone
Customer Authorization
Customer enters M-Pesa PIN on their phone
Payment Processing
M-Pesa processes the payment transaction
Callback Notification
Receive real-time payment status updates
Endpoint
service_wallet_balance is sufficient to
cover service fees.
Request Parameters
{ "amount": 1500, "phone_number": "0798765432", "channel_id":
123, // optional "external_reference": "ORDER-1", // optional
"customer_name": "Jane Doe", // optional "callback_url":
"https://example.com/webhooks/payments" // optional }
cURL Example
curl -X POST "http://localhost/pay-app/v3/stk-initiate/" \ -H
"Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type:
application/json" \ -d '{ "amount": 1500, "phone_number":
"0798765432", "external_reference": "ORDER-12345" }'
Success Response
{ "success": true, "status": "INITIATED", "message": "STK Push
sent successfully. Please check your phone.", "reference":
"ORDER-12345", "transaction_id": 12847, "checkout_request_id":
"ws_CO_...", "merchant_request_id": "3202-...", "channel_type":
"paybill", "routing_info": { "party_b": "400200",
"transaction_type": "CustomerPayBillOnline", "description":
"Paybill 400200, Account: ACC12345" } }
Error Responses
{ "success": false, "error": "Rate limit exceeded",
"details": { "message": "Monthly limit of 1000 requests
reached. Upgrade your subscription.", "tier": "Basic",
"requests_used": 1000, "requests_limit": 1000, "upgrade_url":
"https://swiftwallet.co.ke/subscription.php" }, "error_code":
"RATE_LIMIT_EXCEEDED" }
403 Personal KYC Verification Required
Returned when your account requires personal identity verification (user-level KYC).
{
"success": false,
"error": "Personal KYC verification required",
"details": {
"message": "Your account requires personal identity verification to process transactions. Please complete your personal KYC verification.",
"kyc_url": "https://swiftwallet.co.ke/kyc.php",
"personal_kyc_status": "submitted"
},
"error_code": "PERSONAL_KYC_VERIFICATION_REQUIRED"
}
403 Channel Business KYC Verification Required
Returned when the specific payment channel requires business KYC verification (channel-level KYC).
{
"success": false,
"error": "Channel KYC verification required",
"details": {
"message": "This payment channel requires business KYC verification to process transactions. Please complete your business KYC verification.",
"kyc_url": "https://swiftwallet.co.ke/kyc.php",
"channel_id": 123,
"channel_name": "My Business Paybill",
"channel_kyc_status": "submitted",
"channel_type": "paybill"
},
"error_code": "CHANNEL_KYC_VERIFICATION_REQUIRED"
}
402 Insufficient Service Balance
Returned when your service wallet balance is insufficient to cover transaction fees.
{
"success": false,
"error": "Insufficient service wallet balance",
"details": {
"required_fee": 15.00,
"current_balance": 10.50,
"deficit": 4.50
},
"error_code": "INSUFFICIENT_SERVICE_BALANCE"
}
400 Validation Errors
Returned for invalid input data or missing required fields.
{
"success": false,
"error": "Missing required fields: amount, phone_number"
}
{
"success": false,
"error": "Invalid phone number format. Use 254XXXXXXXXX or 07XXXXXXXX"
}
{
"success": false,
"error": "Account number cannot be provided via API. Use payment channel configuration instead.",
"hint": "Configure your account details in the payment channels section"
}
Callback payloads
When you pass a callback_url, we POST callback data to
your endpoint.
Completed
{
"success": true,
"transaction_id": 12847,
"external_reference": "ORDER-12345",
"checkout_request_id": "ws_CO_...",
"merchant_request_id": "3202-...",
"status": "completed",
"timestamp": "2024-01-14T10:35:45+00:00",
"service_fee": 15.00,
"result": {
"ResultCode": 0,
"ResultDesc": "The service request is processed successfully.",
"Amount": 1500,
"MpesaReceiptNumber": "SAE3YULR0Y",
"Phone": "254798765432",
"TransactionDate": "20240114103545"
},
"channel_info": { "channel_type": "paybill" }
}
Failed
{
"success": false,
"transaction_id": 12847,
"external_reference": "ORDER-12345",
"checkout_request_id": "ws_CO_...",
"merchant_request_id": "3202-...",
"status": "failed",
"timestamp": "2024-01-14T10:35:45+00:00",
"service_fee": 15.00,
"result": { "ResultCode": 1032, "ResultDesc": "Request cancelled by user" },
"channel_info": { "channel_type": "paybill" }
}