I visited the Safaricom Daraja portal and learnt that a developer needs to have the consumer key and consumer secret in order to make a request to the MPESA API to request a certain mobile number to make payment to a specific paybill. I have the both keys and can successfully obtain an access token needed for sending the request with the following PHP code
<?php
//here define the mpesa secret key and api key
$consumer_key = "CONSUMER_KEY";
$consumer_secret = "CONSUMER_SECRET";
$str = ['Authorization: Basic '.base64_encode($consumer_key.":".$consumer_secret)];
//echo $str;
//generate the access tokens
$ch = curl_init('https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials');
curl_setopt($ch, CURLOPT_HTTPHEADER,$str);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
//extract the access token from the json response
$accessToken = json_decode($response, true);
if(isset($accessToken['access_token'])){
//get the access token and echo it
$accessToken = $accessToken["access_token"];
?>
I echo the access token and I get a JSON response of the access token and the time the access token will expire in milliseconds. However when I put the access token in the authentication header and use curl to send a request to the server that authenticates the payment then the curl_exec returns false.
//define the end point for processing the transactions
$endpoint = "https://api.safaricom.co.ke/mpesa/stkpush/v1/processrequest";
//get the number the user submitted in the form
$number = $_POST["phone_no"];
//build the payment payload
$payload = [
"ShortCode"=>"290020",
"CommandID"=> "CustomerPayBillOnline",
"Amount"=> "10",
"Msisdn"=>$number,
"BillRefNumber"=>$number
];
//encode the payment payload to json
$payloadJson = json_encode($payload);
//define the authentication headers and append the access token to it
$headers = [
"Content-Type: application/json",
"Authorization: Bearer $accessToken"
];
//initialize the end point
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJson);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//pass the authentication headers to the curl request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
//execute the request
$resp = curl_exec($ch);
if ($resp) {
echo "Response: $resp"; // Display the response for debugging
$responseData = json_decode($resp, true);
if ($responseData !== null) {
// Handle the response data (check for success, get transaction details, etc.)
print_r($responseData);
// Example: Access a specific value from the response
if (isset($responseData['status'])) {
echo "Status: " . $responseData['status'];
}
} else {
// JSON decoding failed
$jsonError = json_last_error();
$jsonErrorMessage = json_last_error_msg();
echo "JSON Decoding Error: $jsonError - $jsonErrorMessage";
}
} else {
// Handle error
echo "An error occurred.";
}
for some reason the curl_exec method returns false as the output an error occurred is the terminal output.
Update
I called this line and am able to get the error message from curl and it states
SSL certificate problem: unable to get local issuer certificate
Looks like it is an SSL problem , is there a way to configure curl to use a locally available certificate or I need to load the localhost website with https protocol? Thanks.