• Home
  • About
    • Overview
    • Our Experience
    • Join our team
  • What we do
    • Communications & PR
    • Marketing & Advertising
    • Design, branding & printing
    • Events Management
    • Digital Solutions
    • Film & Video Production
    • Professional Photography
  • Our Work
  • Our Blog
  • Contacts
  • Request a Quote
  • Privacy Policy
  • Terms of use
✕
Why my website is not showing in google search (How to Fix It)
February 9, 2022
Netflix Scholarship in Kenya 2022: Call For Applications!
April 1, 2022

MPESA C2B API Integration to your PHP Website

March 17, 2022
Categories
  • Integrations
  • Web Development
Tags

In our previous MPESA integration with PHP article (see here), we introduced mpesa C2B integration. We said that Customer-to-Business Integration (C2B) allows businesses to receive payments from their customers directly. Therefore, in this article, we are going to show you mpesa C2B API integration for your PHP Website.

C2B Transaction Process

Firstly, let us understand the mpesa C2B Transaction flow.

When a customer initiates a payment request to your Pay Bill or Buy Goods (Till Number) from their phone,  M-PESA receives the request. Secondly, it validates the customer’s PIN, Account Balance, Pay Bill entered, etc. In addition, M-PESA also checks if you have enabled External Validation for the C2B. If External Validation is disabled, M-PESA completes the transaction. After that, it sends a Confirmation notification to the Confirmation URL registered. This only happens when the payment is successful.

If External Validation is enabled:

  1. M-PESA Holds the Funds tentatively from the customer’s wallet.
  2. M-PESA then sends a Validation request to the Validation URL registered.
  3. The partner validates the payment request and responds back to M-PESA.
  4. M-PESA receives the response, processes, and completes the transaction then a notification of the payment is sent to your registered confirmation URL.

Finally, M-PESA then sends an SMS notification to both the customer and C2B registered phone number. Learn more here



Integration

First, as usual, we will use pure PHP to integrate the C2B API. We hope you have created an account on Safaricom daraja website and have an active sandbox API.

MPESA C2B API Integration to your PHP Website

Secondly, obtain an access token that you will be used when calling the Mpesa C2B API. For you to obtain this access_token, you use the consumer key and secret that will be obtained from your developer account.

The next step is to register validation and confirmation URLs(links). Why do we do this? The major reason for integrating Mpesa C2B API with your systems is to allow for communication and the exchange of information between the two systems.

A validation URL is a link where MPESA sends the transaction details to allow you to verify that they are what you intended after your customer initiates an Mpesa transaction using your pay bill number. For example, you might want to validate the amount being paid. Once you have verified, then you can either decline or accept the payment.

A confirmation URL is a link where MPESA sends the details of a completed transaction if you accepted the transaction in the validation stage. At this stage, you might save the data in the database, or perform any other logic for example in e-commerce where you might allow one to access premium products.

Therefore, what does this Mpesa C2B API integration look like in terms of code? Let’s start with vanilla PHP.

First of all, let’s look at the initiating stk push code. We saw this in the previous tutorial but let me just post it here again. Here is what initiateSTK.php looks like:



<?php
header("Content-Type:application/json");

/*Call function with these configurations*/
    $env="sandbox";
    $shortcode = '600988'; 
    $key = ""; //Put your key here
    $secret = "";  //Put your secret here
    $initiatorName = "testapi";
    $initiatorPassword = "Safaricom978!";
    $results_url = "https://mydomain.com/TransactionStatus/result/"; //Endpoint to receive results Body
    $timeout_url = "https://mydomain.com/TransactionStatus/queue/"; //Endpoint to to go to on timeout
/*End  configurations*/

/*Ensure transaction code is entered*/
    if (!isset($_GET["transactionID"])) {
        echo "Technical error";
        exit();
    }
/*End transaction code validation*/

    $transactionID = $_GET["transactionID"]; 
    //$transactionID = "OEI2AK4Q16";
    $command = "TransactionStatusQuery";
    $remarks = "Transaction Status Query"; 
    $occasion = "Transaction Status Query";
    $callback = null ;

    
    $access_token = ($env == "live") ? "https://api.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials" : "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials"; 
    $credentials = base64_encode($key . ':' . $secret); 
    
    $ch = curl_init($access_token);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Basic " . $credentials]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    $response = curl_exec($ch);
    curl_close($ch);
    
    $result = json_decode($response); 

    //echo $result->{'access_token'};
    
    $token = isset($result->{'access_token'}) ? $result->{'access_token'} : "N/A";

    $publicKey = file_get_contents(__DIR__ . "/mpesa_public_cert.cer"); 
    $isvalid = openssl_public_encrypt($initiatorPassword, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING); 
    $password = base64_encode($encrypted);

    //echo $token;

    $curl_post_data = array( 
        "Initiator" => $initiatorName, 
        "SecurityCredential" => $password, 
        "CommandID" => $command, 
        "TransactionID" => $transactionID, 
        "PartyA" => $shortcode, 
        "IdentifierType" => $type, 
        "ResultURL" => $results_url, 
        "QueueTimeOutURL" => $timeout_url, 
        "Remarks" => $remarks, 
        "Occasion" => $occasion,
    ); 

    $data_string = json_encode($curl_post_data);

    //echo $data_string;

    $endpoint = ($env == "live") ? "https://api.safaricom.co.ke/mpesa/transactionstatus/v1/query" : "https://sandbox.safaricom.co.ke/mpesa/transactionstatus/v1/query"; 

    $ch2 = curl_init($endpoint);
    curl_setopt($ch2, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer '.$token,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch2, CURLOPT_POST, 1);
    curl_setopt($ch2, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
    $response     = curl_exec($ch2);
    curl_close($ch2);

    //echo "Authorization: ". $response;

    $result = json_decode($response); 
    
    $verified = $result->{'ResponseCode'};
    if($verified === "0"){
        echo "Transaction verified as TRUE";
    }else{
        echo "Transaction doesnt exist";
    }

The above code initiates the stk push on the user’s phone. However, note that the response on the transaction status (whether the customer PAID, CANCELED, or if there was an ERROR) is sent by Safaricom API to your callback URL. To implement this practice, the callback URL is supposed to receive this response from safaricom. Therefore, you need to set up the code in the callback URL such that it receives the response in form of JSON data and then stores it in your database. If your Callback URL is https://mydomain.com/TransactionStatus/response, response.php should be something like this:

<?php
header("Content-Type:application/json");

$content = file_get_contents('php://input'); //Recieves the response from MPESA as a string

$res = json_decode($content, false); //Converts the response string to an object

$dataToLog = array(
    date("Y-m-d H:i:s"), //Date and time
    $res
); //Sets up the log format: Date, time and the response
$data = implode(" - ", $dataToLog);

$data .= PHP_EOL; //Add an end of line to the transaction log

file_put_contents('transaction_log', $data, FILE_APPEND); Appends the response to the log file transaction_log

$con = mysqli_connect("localhost","root","","mpesa"); //Connets to the dashboard

$sql = "INSERT INTO `responses` (`Response`) VALUES ('$content')";
$rs = mysqli_query($con, $sql); //Record the response to the database
if($rs)
{
    echo "Records Inserted";
}

?>

Your database will have the following columns: MerchantRequestID, CheckoutRequestID, ResultCode (0 means successful processing and any other code means an error occurred or the transaction failed.), ResultDesc, MpesaCode, TransactionDate, and PhoneNumber.



Share
97
Anselm Muchura
Anselm Muchura
Software developer and Graphic designer

Related posts

Integrating-Woocommerce-MPESA-payment-to-your Wordpress website
September 24, 2022

How to integrate MPESA stk push in woocommerce WordPress website


Read more
August 1, 2022

Integrate MPESA Payment API to your Laravel Website


Read more
April 20, 2022

Lipa na MPESA STK-PUSH Integration to your PHP Website [UPDATED]


Read more

1 Comment

  1. Adam says:
    May 6, 2022 at 1:06 PM

    Nice one,,i needed a way customers can withdraw funds from the business till or paybill

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

More Blog

  • 0
    Introduction to Email and Web Security – Examples and Best Practices
    January 30, 2023
  • Brand Launch 3 tips to a Successful Brand Launch for all Businesses0
    Brand Launch: 3 tips to a Successful Brand Launch for all Businesses
    November 24, 2022
  • How to make an Impactful Documentary films - A Step By Step Guide0
    How to make Impactful Documentary film – A Step By Step Guide
    November 1, 2022
  • 0
    Netflix announces 46 beneficiaries of its Creative Equity Scholarship Fund in East Africa
    October 11, 2022
  • Integrating-Woocommerce-MPESA-payment-to-your Wordpress website1
    How to integrate MPESA stk push in woocommerce WordPress website
    September 24, 2022
  • 1
    How to Start a Blog and Make Money Online – The Ultimate Beginner’s Guide
    September 6, 2022
  • 0
    How to build an effective branded marketing caravan campaign
    August 23, 2022
  • 1
    Integrate MPESA Payment API to your Laravel Website
    August 1, 2022

Request a Quote

Give us a bit more detail here. Links to examples are very helpful. Feel free to include any questions you might have.

Quick links

  • Who we are
  • What we do
  • Our Work
  • Our Blog
  • Join our team
  • SDGs

Our Services

  • Communications & PR
  • Events Management
  • Design, Branding & Printing
  • Digital Solutions
  • Transformative Storytelling
  • Marketing & Advertising

Stalk us

  • Linkedin page
  • Facebook
  • Twitter
  • Instagram
  • Youtube
  • Medium


Hotline:

+254 777665548

© 2018-2023 MediaForce Communications | All Rights Reserved
  • Privacy Policy
  • Terms of use