BACK TO BLOG

The Complete Guide to M-Pesa Integration for Businesses

Learn how to integrate M-Pesa payments into your platform, from API setup to going live with real transactions.

The Complete Guide to M-Pesa Integration for Businesses

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:

  1. Submit your app for review
  2. Switch to production credentials
  3. Update callback URLs to production endpoints
  4. 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.

Learn More on YouTube

Watch tutorials, walkthroughs, and deep dives on the Fortune Dev Academy channel.

@fortunedevacademy

READY TO BUILD
SOMETHING GREAT?

Let's discuss your next project.

START A PROJECT