Handling Callback

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

  1. Initiate Payment - Include callback_url in your STK push request
  2. Payment Processing - Customer enters PIN on their phone
  3. Status Change - Payment status changes (success/failed)
  4. Webhook Notification - We send a POST request to your callback URL
  5. 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

FieldTypeDescription
AmountNumberPayment amount in Kenyan Shillings
ExternalReferenceStringYour reference ID for tracking
MerchantRequestIDStringMpesa merchant request identifier
CheckoutRequestIDStringMpesa checkout request identifier
MpesaReceiptNumberStringMpesa transaction code (empty for failed payments)
PhoneStringCustomer's phone number
ResultCodeNumberPayment result code (0 = success, >0 = error)
ResultDescStringHuman-readable result description
MetadataObjectOptionan additional data stored with the payment when it was being initiated
StatusStringPayment status: Success or Failed
statusBooleantrue for successful payments, false for failed

Required Response

Your callback endpoint must respond with:

HTTP/1.1 200 OK
Content-Type: text/plain

ok

Security 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/callback

Troubleshooting

Common Issues

  1. Callback not received

    • Check if URL is publicly accessible
    • Verify HTTPS is enabled
    • Check server logs for errors
  2. 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.