M-Pesa is not just a payment method in Kenya — it is infrastructure. With over 30 million active users, M-Pesa processes more transactions daily than many African stock markets. If your website cannot accept M-Pesa payments, you are leaving a massive amount of revenue on the table. This guide walks you through integrating Safaricom's Daraja API into your website or web app — clearly and practically.
What is the Daraja API?
Daraja (meaning "bridge" in Swahili) is Safaricom's developer platform that allows businesses to integrate M-Pesa payment functionality into their websites, apps and systems. It exposes several APIs for different payment flows:
- STK Push (Lipa Na M-Pesa Online): The most common integration. You enter an amount, the customer's phone is prompted to enter their M-Pesa PIN, and payment is confirmed automatically. No USSD menus for the customer.
- C2B (Customer to Business): Allows customers to pay your till or paybill number and your system gets notified of the payment in real-time.
- B2C (Business to Customer): Send money from your business to a customer's M-Pesa. Used for refunds, salary payments, commissions.
- Account Balance API: Query your M-Pesa account balance programmatically.
- Transaction Status API: Check the status of any past transaction.
Prerequisites Before You Start
Before writing a single line of code, you need:
- A Safaricom Business Account: Your business must have a registered M-Pesa Paybill or Till number.
- A Daraja Developer Account: Register at developer.safaricom.co.ke. This is free.
- A live, public-facing URL (callback URL): Safaricom sends payment confirmations to a URL you specify. This URL must be publicly accessible — not localhost. Use ngrok for testing locally.
- A developer (or basic coding knowledge): The API is well-documented, but you need to be comfortable making HTTP requests. Libraries exist for PHP, Node.js, Python, Laravel and Django.
Step 1: Create a Daraja App
- Log into developer.safaricom.co.ke
- Navigate to "My Apps" and click "Add a new app"
- Name your app and select the APIs you need (start with M-Pesa Sandbox for testing)
- Note your Consumer Key and Consumer Secret — these are your API credentials
- In the Sandbox, you will also get test credentials including a test Shortcode, Passkey, and test phone numbers
Step 2: Get an Access Token
Every API call requires an access token for authentication. You generate it by sending your Consumer Key and Consumer Secret to the OAuth endpoint:
GET https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials
Authorization: Basic [Base64(ConsumerKey:ConsumerSecret)]
Response:
{
"access_token": "YOUR_ACCESS_TOKEN",
"expires_in": "3599"
} Access tokens expire after 3,600 seconds (1 hour). Build your system to generate a new one when needed rather than caching indefinitely.
Step 3: Implement STK Push
STK Push is the payment flow where the customer's phone receives a prompt to pay. Here is the API call:
POST https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"BusinessShortCode": "174379",
"Password": "[Base64(Shortcode+Passkey+Timestamp)]",
"Timestamp": "20250101120000",
"TransactionType": "CustomerPayBillOnline",
"Amount": "100",
"PartyA": "254712345678",
"PartyB": "174379",
"PhoneNumber": "254712345678",
"CallBackURL": "https://yourdomain.com/mpesa/callback",
"AccountReference": "Order123",
"TransactionDesc": "Payment for Order 123"
} Key fields explained:
- Password: Base64 encoding of Shortcode + Passkey + Timestamp concatenated
- Timestamp: Current datetime in YYYYMMDDHHmmss format
- PartyA: Customer phone number in 254 format (no +, no leading 0)
- CallBackURL: Your server endpoint that receives the payment confirmation
- AccountReference: Your order/transaction reference (shows on customer's M-Pesa message)
Step 4: Handle the Callback
When the customer pays (or declines), Safaricom sends a POST request to your CallBackURL. Your server must respond with HTTP 200 immediately, then process the data:
// Successful payment callback
{
"Body": {
"stkCallback": {
"MerchantRequestID": "29115-34620561-1",
"CheckoutRequestID": "ws_CO_191220191020363925",
"ResultCode": 0,
"ResultDesc": "The service request is processed successfully.",
"CallbackMetadata": {
"Item": [
{"Name": "Amount", "Value": 100},
{"Name": "MpesaReceiptNumber", "Value": "NLJ7RT61SV"},
{"Name": "TransactionDate", "Value": 20191219102115},
{"Name": "PhoneNumber", "Value": 254712345678}
]
}
}
}
} ResultCode 0 = success. Any other code = failure or cancellation. Extract the MpesaReceiptNumber as your payment reference and update your database accordingly.
Step 5: Go Live
Once your integration is working in the Sandbox:
- Log into your Daraja account and click "Go Live"
- Fill in your business details and upload required documents (KRA PIN, Business registration)
- Wait for approval (typically 2–5 business days)
- Replace Sandbox URLs with production URLs (api.safaricom.co.ke instead of sandbox.safaricom.co.ke)
- Update your credentials with the live Consumer Key, Consumer Secret and Shortcode
- Test with a small real payment before going fully live
Always test your callback handler thoroughly in sandbox before going live. Missed or mishandled callbacks mean customers who paid but whose orders were not fulfilled — the worst possible outcome. Log every single callback to your database, even before processing it.
Recommended Libraries
- PHP/Laravel: safaricom/daraja-php, iamkmoney/mpesa-laravel
- Node.js: mpesa-api, daraja-api-node
- Python/Django: python-daraja, django-mpesa
Need a fully tested M-Pesa integration built for your specific platform? Get in touch with our development team — we handle this regularly.
Ready to apply this to your business?
Let our team do the heavy lifting. Book a free strategy session.