Handling Callback
Webhook callbacks provide real-time notifications when payment status changes. This allows you to complete you application logic (eg completing orders)
How Callbacks Work
- Initiate Payment - Include
callback_urlin your STK push request - Payment Processing - Customer enters PIN on their phone
- Status Change - Payment status changes (success/failed)
- Webhook Notification - We send a POST request to your callback URL
- Acknowledgment - Your endpoint responds with HTTP 200 and "ok"
Callback URL Setup
1. Provide Callback URL
Include the callback_url in your STK push request:
{
"phone_number": "254712345678",
"amount": 100,
"external_reference": "order_123",
"callback_url": "https://your-domain.com/api/payments/callback"
}2. Make URL Accessible
Your callback URL must be:
- Publicly accessible (not localhost)
- HTTPS enabled (for security)
- Respond quickly (within 30 seconds)
- Handle POST requests
Callback Payload Structure
Successful Payment Callback
{
"response": {
"Amount": 100,
"ExternalReference": "order_123",
"MerchantRequestID": "12345-67890-12345-67890",
"CheckoutRequestID": "12345-67890-12345-67890",
"MpesaReceiptNumber": "NEF61H8J60",
"Phone": "254712345678",
"ResultCode": 0,
"ResultDesc": "Success. Request accepted for processing",
"Metadata": {
"order_id": "12345",
"customer_name": "John Doe"
},
"Status": "Success"
},
"status": true
}Failed Payment Callback
{
"response": {
"Amount": 100,
"ExternalReference": "order_123",
"MerchantRequestID": "12345-67890-12345-67890",
"CheckoutRequestID": "value",
"MpesaReceiptNumber": "",
"Phone": "254712345678",
"ResultCode": 1,
"ResultDesc": "The initiator information is invalid",
"Metadata": {
"order_id": "12345",
"customer_name": "John Doe"
},
"Status": "Failed"
},
"status": false
}Callback Response Fields
| Field | Type | Description |
|---|---|---|
Amount | Number | Payment amount in Kenyan Shillings |
ExternalReference | String | Your reference ID for tracking |
MerchantRequestID | String | Mpesa merchant request identifier |
CheckoutRequestID | String | Mpesa checkout request identifier |
MpesaReceiptNumber | String | Mpesa transaction code (empty for 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 | Optionan additional data stored with the payment when it was being initiated |
Status | String | Payment status: Success or Failed |
status | Boolean | true for successful payments, false for failed |
Required Response
Your callback endpoint must respond with:
HTTP/1.1 200 OK
Content-Type: text/plain
okSecurity Considerations
Testing Callbacks
1. Use ngrok for Local Development
# Install ngrok
npm install -g ngrok
# Start your local server
node server.js
# In another terminal, expose your local server
ngrok http 3000
# Use the ngrok URL as your callback URL
# https://abc123.ngrok.io/api/payments/callbackTroubleshooting
Common Issues
-
Callback not received
- Check if URL is publicly accessible
- Verify HTTPS is enabled
- Check server logs for errors
-
Duplicate callbacks
- Implement idempotency checks
- Use unique identifiers
- Store processed transaction reference IDs
Support
Need help? Contact our support team via 0768793923/devriz2030@gmail.com or check out our Resources section for additional tools and guides.