Web Design

How to Integrate MPesa in HTML

MPesa is Kenya’s leading mobile money service. Integrating it into HTML websites boosts payments. This guide explains the process step-by-step. You’ll learn Daraja API basics for beginners. Why Integrate MPesa? MPesa handles C2B payments easily. Customers pay via phone prompts. Websites gain trust with local options. E-commerce sites see higher conversions. It’s secure and fast […]

How to Integrate MPesa in HTML

    MPesa is Kenya’s leading mobile money service. Integrating it into HTML websites boosts payments. This guide explains the process step-by-step. You’ll learn Daraja API basics for beginners.

    Why Integrate MPesa?

    MPesa handles C2B payments easily. Customers pay via phone prompts. Websites gain trust with local options. E-commerce sites see higher conversions. It’s secure and fast for Kenyan users.

    Key benefits include:

    • Instant STK Push notifications.

    • No extra apps needed.

    • Supports small businesses.

    • Tracks transactions live.

    Prerequisites

    Start with basics. You need a Safaricom developer account. Use Daraja API sandbox for tests. HTML alone can’t call APIs. Pair it with PHP, Node.js, or Python backend.

    Gather these:

    • Consumer Key and Secret.

    • Paybill or Till Number.

    • HTTPS server (required).

    • Text editor like VS Code.

    • Local server like XAMPP.

    Step 1: Register on Daraja Portal

    Visit developer.safaricom.co.ke. Sign up free. Log in to Daraja dashboard. Create a new app. Select C2B or LIPA NA MPESA.

    Fill details:

    Field Description
    App Name Your website name 
    Company Business name 
    Products C2B, STK Push, etc. 
    Callback URL Your confirmation endpoint 

    Save keys. Note them securely. Test in sandbox first.

    Step 2: Get OAuth Access Token

    Tokens authenticate requests. They expire hourly. Use PHP or JS to fetch.

    Sample PHP code:

    php
    <?php
    $consumerKey = 'your_key';
    $consumerSecret = 'your_secret';
    $credentials = base64_encode($consumerKey . ':' . $consumerSecret);

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials");
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Basic ' . $credentials));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($curl);
    curl_close($curl);

    $token = json_decode($response)->access_token;
    echo $token;
    ?>

    Copy this to get_token.php. Run it. Save token for STK Push.

    Step 3: Create HTML Payment Form

    Build a simple form. Collect phone and amount. Submit to backend.

    xml
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pay with MPesa</title>
    <style>
    body { font-family: Arial; max-width: 500px; margin: 50px auto; }
    input { width: 100%; padding: 10px; margin: 10px 0; }
    button { background: #00A651; color: white; padding: 15px; border: none; width: 100%; }
    </style>
    </head>
    <body>
    <h1>Buy Now - KSh 500</h1>
    <form action="stk_push.php" method="POST">
    <label>Phone Number:</label>
    <input type="tel" name="phone" placeholder="2547XXXXXXXX" required pattern="254[17][0-9]{8}">
    <label>Amount:</label>
    <input type="number" name="amount" value="500" min="1" required>
    <button type="submit">Pay with MPesa</button>
    </form>
    </body>
    </html>

    This form is mobile-friendly. Validates Kenyan numbers.

    Step 4: Implement STK Push Backend

    Create stk_push.php. Use token from Step 2. Send to MPesa API.

    php
    <?php
    include 'get_token.php'; // Include token logic

    $phone = $_POST['phone'];
    $amount = $_POST['amount'];
    $account = 'your_paybill'; // e.g., 600000
    $transaction = 'TXN' . time();
    $passkey = 'your_lipa_na_mpesa_passkey';
    $shortcode = '174379'; // Sandbox shortcode

    $timestamp = date('YmdHis');
    $password = base64_encode($shortcode . $passkey . $timestamp);

    $data = [
    'BusinessShortCode' => $shortcode,
    'Password' => $password,
    'Timestamp' => $timestamp,
    'TransactionType' => 'CustomerPayBillOnline',
    'Amount' => $amount,
    'PartyA' => $phone,
    'PartyB' => $account,
    'PhoneNumber' => $phone,
    'CallBackURL' => 'https://yourdomain.com/callback.php',
    'AccountReference' => 'YourWebsite',
    'TransactionDesc' => 'Payment for order'
    ];

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $token
    ]);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($curl);
    curl_close($curl);

    echo json_encode(json_decode($result, true));
    ?>

    MPesa sends STK prompt to phone. Check CheckoutRequestID.

    Step 5: Handle Callbacks

    Callbacks confirm payments. Create callback.php. Log results.

    php
    <?php
    $callback = file_get_contents('php://input');
    file_put_contents('callbacks.txt', $callback . "\n", FILE_APPEND);

    $data = json_decode($callback, true);
    $resultCode = $data['Body']['stkCallback']['ResultCode'];

    if ($resultCode == 0) {
    $mpesaReceipt = $data['Body']['stkCallback']['CallbackMetadata'][0]['Value'];
    // Update order status in DB
    echo "Payment successful: " . $mpesaReceipt;
    } else {
    echo "Payment failed";
    }
    ?>

    Store in database for orders. Use MySQL for production.

    Step 6: Check Transaction Status

    Verify payments anytime. Create check_status.php.

    php
    <?php
    $checkoutId = $_POST['checkout_id']; // From STK response
    $data = [
    'BusinessShortCode' => $shortcode,
    'Password' => $password,
    'Timestamp' => $timestamp,
    'CheckoutRequestID' => $checkoutId
    ];

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://sandbox.safaricom.co.ke/mpesa/stkpushquery/v1/query');
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $token
    ]);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($curl);
    echo $result;
    ?>

    Poll every 30 seconds if needed.

    Security Best Practices

    Protect your integration:

    • Never expose keys in HTML/JS.

    • Use HTTPS everywhere.

    • Validate inputs server-side.

    • Rate-limit API calls.

    • Log all transactions.

    • Rotate passkeys regularly.

    Common errors:

    Error Code Meaning Fix
    1 Success 
    2001 Invalid phone Check format 
    1032 Timeout Retry later 

    Testing in Sandbox

    Use test credentials:

    • Shortcode: 174379

    • Passkey: bbf279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919

    • Phone: 254708374149

    Simulate payments. Go live after approval.

    Going Live

    Submit to Safaricom. Get production keys. Update URLs. Apply for Paybill via m-pesaforbusiness.co.ke. Expect 1-2 weeks approval.

    Production endpoints swap “sandbox” for live.

    Frontend Enhancements

    Add JS for better UX:

    javascript
    document.querySelector('form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    const response = await fetch('stk_push.php', { method: 'POST', body: formData });
    const result = await response.json();
    if (result.ResponseCode === '0') {
    alert('Check your phone for MPesa PIN prompt!');
    }
    });

    Shows progress without reloads.

    Common Challenges

    • No STK Prompt: Check token, passkey.

    • Callback Issues: Ensure public HTTPS URL.

    • CORS Errors: Backend handles APIs.

    • Live Approval: Test thoroughly first.

    Alternatives to Daraja

    Consider IntaSend or Africa’s Talking for easier integration. Less setup, but fees apply.

    Conclusion

    MPesa integration transforms HTML sites. Follow these steps for success. Start sandbox today. Scale to live confidently.

    Ready to grow your online presence? Get a custom website & digital marketing solution for your business.
    Call Us
    Share:
    Need a Website?
    Professional web design & digital marketing. Free consultation for Nairobi businesses.
    Our Services
    Contact Us
    Westlands MKT, Mpaka Road, Nairobi
    Mon–Fri: 9:00 AM – 5:00 PM

    Ready to Grow Your Business Online?

    Web design, SEO, social media and digital marketing — all under one roof.