Close
Get in Touch
BLOG

Mpesa STK Push Integration: Step-by-Step Guide to Integrating Lipa na Mpesa Online in PHP

Mpesa STK Push Integration: Step-by-Step Guide to Integrating Lipa na Mpesa Online in PHP

In this guide, you are going to learn how to develop Mpesa integration to any custom website using PHP. Mpesa is one of the most popular mobile money transfer services in the world.

The innovative product is offered by Safaricom – Kenya’s leading telecommunication company with the strongest and widest network coverage.

With Mpesa, anyone can send money to you in Kenya using their Safaricom sim card and a mobile phone that supports a Sim Tool Kit(STK). 

Safaricom has a ‘Lipa na Mpesa’ service specifically tailored for businesses that want to collect payments through the Mpesa payment gateway for Till and Paybill numbers(short codes).

Lipa na Mpesa offers a lot of convenience to customers and businesses. Text notifications are sent to merchants’ nominated mobile numbers when customers make payments to the business’s short code that is issued for free by Safaricom.

 

Safaricom Developers Account

Now that we have a new Laravel application, the next step is to make sure that we have an account with Safaricom Developers Account. To create an account visit Daraja Safaricom website. If you have an account with Safaricom Daraja you can log in else sign up. 

Daraja Dashboard

The next step is to create a new sandbox app by clicking on the Add a New App button and give it a name. Ensure you select both Lipa na Mpesa Sandbox and Mpesa Sandbox and hit Create App button. You will get the following success message. Awesome! Now that we have our app created successfully. Click on your newly created app. 

Take note of Consumer Key and Consumer Secret, the two should always be kept as a secret.NB: Never Share Your Consumer Key or Consumer Secret with anyone.Learn more about creating M-pesa Sandbox AppGenerating M-pesa Access TokenSafaricom M-pesa API uses OAuth 2.0 Access token, to invoke M-pesa API we need to generate OAuth 2.0 Access Token and Use Bearer as the keyword.



//lipaNaMpesaPassword
$lipa_time = date('YmdHms');
$timestamp =$lipa_time;
$lipa_na_mpesa_password = base64_encode($_POST['shortcode'].$_POST['passkey'].$timestamp);



//generateAccessToken


function generateAccessToken(){
$credentials = base64_encode($consumer_key.":".$consumer_secret);
$url2 = $_POST['credentials_endpoint'];

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url2);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic ".$credentials));
curl_setopt($curl, CURLOPT_HEADER,false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($curl);
$access_token=json_decode($curl_response);
return $access_token->access_token;
}


$url = $payments_endpoint_url;

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.generateAccessToken()));


$curl_post_data = [
'BusinessShortCode' => $shortcode,
'Password' => $lipa_na_mpesa_password,
'Timestamp' => $lipa_time,
'TransactionType' => 'CustomerPayBillOnline',
'Amount' => $amount,
// 'Amount' => 1,
'PartyA' => $tel,
'PartyB' => $shortcode,
'PhoneNumber' => $tel,
'CallBackURL' => $callbackUrl,
'AccountReference' => $merchant_name',
'TransactionDesc' => "Testing stk push on sandbox"
];

$data_string = json_encode($curl_post_data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);

$curl_response = curl_exec($curl);

$response = json_decode($curl_response);

$res = json_decode(json_encode($response), true);

$_SESSION['credentials_endpoint'] = $_POST['credentials_endpoint'];
$_SESSION['consumer_key'] = $_POST['consumer_key'];
$_SESSION['passkey'] = $_POST['passkey'];
$_SESSION['consumer_secret'] = $_POST['consumer_secret'];
$_SESSION['url_success'] = $_POST['x_url_success'];
$_SESSION['url_error'] = $_POST['x_url_error'];
$_SESSION['url_cancel'] = $_POST['x_url_cancel'];
$_SESSION['CheckoutRequestID'] =$res['CheckoutRequestID'];
$_SESSION['BusinessShortCode'] = $_POST['shortcode'];
$_SESSION['timestamp'] = $lipa_time;
$_SESSION['Password'] = $lipa_na_mpesa_password;


if(array_key_exists("ResponseCode",$res) && $res->ResponseCode == 0){
echo "<script>window.open = '".$url_success."'</script>";
}elseif(array_key_exists("ResponseCode",$res) && $res->ResponseCode == 1){
echo "<script>window.open = '".$url_error."'</script>";
}else{
echo "<script>window.open = '".$url_cancel."'</script>";
}

}

**Check if the mpesa payment was successful***

//lipaNaMpesaPassword
$lipa_time = date('YmdHms');
$timestamp =$lipa_time;
$lipa_na_mpesa_password = base64_encode($_SESSION['BusinessShortCode'].$_SESSION['passkey'].$timestamp);



//generateAccessToken
function generateAccessToken(){
$consumer_key= $_SESSION['consumer_key'];
$consumer_secret= $_SESSION['consumer_secret'];
$credentials = base64_encode($consumer_key.":".$consumer_secret);
$url2 = $credentials_endpoint;

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url2);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic ".$credentials));
curl_setopt($curl, CURLOPT_HEADER,false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($curl);
$access_token=json_decode($curl_response);
return $access_token->access_token;
}




$url = 'https://sandbox.safaricom.co.ke/mpesa/stkpushquery/v1/query';

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.generateAccessToken()));

$curl_post_data = array(
'BusinessShortCode' => $BusinessShortCode,
'Password' => $lipa_na_mpesa_password,
'Timestamp' => $timestamp,
'CheckoutRequestID' => $CheckoutRequestID
);

$data_string = json_encode($curl_post_data);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);

$curl_response = curl_exec($curl);

$response = json_decode($curl_response);

$res = json_decode(json_encode($response), true);

if($res['ResultCode'] == 0){
echo "<script type='text/javascript'>window.location.href = '".$_SESSION['url_success']."';</script>";
header('Location:'.$url_success.'');
exit();
}elseif($res['ResultCode'] == 1032){
echo "<script type='text/javascript'>window.location.href = '".$_SESSION['url_cancel']."';</script>";
header('Location:'.$url_cancel.'');
exit();
}else{
echo "<script type='text/javascript'>window.location.href = '".$_SESSION['url_error']."';</script>";
header('Location:'.$_SESSION['url_error'].'');
exit();
}

64Shares
8
14
5
Comments (0)
Leave A Comment
REPLYING... Cancel
Comments Added Successfully!
© Anselm Muchura | All rights reserved.