Why M-Pesa Integration Matters
M-Pesa processes over $314 billion in transactions annually across Africa. For businesses operating in Kenya, Tanzania, Uganda, and beyond, integrating M-Pesa isn't optional — it's essential for reaching the majority of your customers.
Understanding the Daraja API
Safaricom's Daraja API is the gateway to M-Pesa integration. It provides endpoints for:
- STK Push: Initiate payments directly from customer phones
- C2B: Customer-to-business payments
- B2C: Business-to-customer disbursements
- Account Balance: Query wallet balances
- Transaction Status: Verify payment status
Step-by-Step Integration
1. Register for Daraja API
Visit the Safaricom Developer Portal and create an account. You'll receive API keys (consumer key and secret) after approval.
2. Get Your Credentials
- Consumer Key: Identifies your application
- Consumer Secret: Authenticates your requests
- Passkey: Used for password generation
- Shortcode: Your business identifier on M-Pesa
3. Generate an Access Token
const axios = require('axios');
async function getAccessToken() {
const response = await axios.get(
'https://sandbox.safaricom.co.ke/oauth/v1/generate',
{
headers: {
Authorization: `Basic ${Buffer.from(`${CONSUMER_KEY}:${CONSUMER_SECRET}`).toString('base64')}`,
},
}
);
return response.data.access_token;
}
4. Initiate an STK Push
async function initiatePayment(phoneNumber, amount) {
const token = await getAccessToken();
const timestamp = new Date().toISOString().replace(/[-T:Z.]/g, '').slice(0, 14);
const password = Buffer.from(`${SHORTCODE}${PASSKEY}${timestamp}`).toString('base64');
const response = await axios.post(
'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest',
{
BusinessShortCode: SHORTCODE,
Password: password,
Timestamp: timestamp,
TransactionType: 'CustomerPayBillOnline',
Amount: amount,
PartyA: phoneNumber,
PartyB: SHORTCODE,
PhoneNumber: phoneNumber,
CallBackURL: 'https://yourdomain.com/callback',
AccountReference: 'YourBusiness',
TransactionDesc: 'Payment for services',
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response.data;
}
Handling Callbacks
M-Pesa sends transaction results to your callback URL. Always verify the transaction status before fulfilling an order:
app.post('/callback', (req, res) => {
const { Body } = req.body;
if (Body.stkCallback.ResultCode === 0) {
// Payment successful
const metadata = Body.stkCallback.CallbackMetadata.Item;
// Process the payment...
}
res.json({ ResultCode: 0, ResultDesc: 'Success' });
});
Testing in Sandbox
Before going live, test thoroughly in the sandbox environment:
- Use test phone numbers provided by Safaricom
- Verify callback responses
- Test error scenarios (insufficient balance, wrong PIN, timeout)
Going Live
Once testing is complete:
- Submit your app for review
- Switch to production credentials
- Update callback URLs to production endpoints
- Monitor transaction logs closely for the first 48 hours
Security Best Practices
- Never expose API keys in client-side code
- Always verify transactions server-side
- Implement rate limiting on payment endpoints
- Log all transactions for audit purposes
- Use HTTPS for all API communications
Need help with M-Pesa integration? Our team has built payment systems processing millions in transactions. Let us handle the technical complexity so you can focus on your business.

