Git Product home page Git Product logo

mpesa-php-sdk's Introduction

Introduction

This package seeks to help php developers implement the various Mpesa APIs without much hustle. It is based on the REST API whose documentation is available on https://developer.safaricom.co.ke.

Installation using composer
composer require safaricom/mpesa

Configuration
At your project root, create a .env file and in it set the consumer key and consumer secret as follows
MPESA_CONSUMER_KEY= [consumer key]
MPESA_CONSUMER_SECRET=[consumer secret]
MPESA_ENV=[live or sandbox]
For Laravel users, open the Config/App.php file and add \Safaricom\Mpesa\MpesaServiceProvider::class under providers and 'Mpesa'=> \Safaricom\Mpesa\MpesaServiceProvider::class under aliases.

Remember to edit the consumer_key and consumer_secret values appropriately when switching between sandbox and live

Usage

Confirmation and validation urls

B2C Payment Request

This creates transaction between an M-Pesa short code to a phone number registered on M-Pesa.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$b2cTransaction=$mpesa->b2c($InitiatorName, $SecurityCredential, $CommandID, $Amount, $PartyA, $PartyB, $Remarks, $QueueTimeOutURL, $ResultURL, $Occasion);

Account Balance Request

This is used to enquire the balance on an M-Pesa BuyGoods (Till Number)

$mpesa= new \Safaricom\Mpesa\Mpesa();

$balanceInquiry=$mpesa->accountBalance($CommandID, $Initiator, $SecurityCredential, $PartyA, $IdentifierType, $Remarks, $QueueTimeOutURL, $ResultURL);

Transaction Status Request This is used to check the status of transaction.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$trasactionStatus=$mpesa->transactionStatus($Initiator, $SecurityCredential, $CommandID, $TransactionID, $PartyA, $IdentifierType, $ResultURL, $QueueTimeOutURL, $Remarks, $Occasion);

B2B Payment Request

This is used to transfer funds between two companies.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$b2bTransaction=$mpesa->b2b($ShortCode, $CommandID, $Amount, $Msisdn, $BillRefNumber );

C2B Payment Request

This is used to Simulate transfer of funds between a customer and business.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$b2bTransaction=$mpesa->c2b($ShortCode, $CommandID, $Amount, $Msisdn, $BillRefNumber );

Also important to note is that you should have registered validation and confirmation urls where the callback responses will be sent.

STK Push Simulation

This is used to initiate online payment on behalf of a customer.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$stkPushSimulation=$mpesa->STKPushSimulation($BusinessShortCode, $LipaNaMpesaPasskey, $TransactionType, $Amount, $PartyA, $PartyB, $PhoneNumber, $CallBackURL, $AccountReference, $TransactionDesc, $Remarks);

STK Push Status Query

This is used to check the status of a Lipa Na M-Pesa Online Payment.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$STKPushRequestStatus=$mpesa->STKPushQuery($checkoutRequestID,$businessShortCode,$password,$timestamp);

Callback Routes M-Pesa APIs are asynchronous. When a valid M-Pesa API request is received by the API Gateway, it is sent to M-Pesa where it is added to a queue. M-Pesa then processes the requests in the queue and sends a response to the API Gateway which then forwards the response to the URL registered in the CallBackURL or ResultURL request parameter. Whenever M-Pesa receives more requests than the queue can handle, M-Pesa responds by rejecting any more requests and the API Gateway sends a queue timeout response to the URL registered in the QueueTimeOutURL request parameter.

Obtaining post data from callbacks This is used to get post data from callback in json format. The data can be decoded and stored in a database.

$mpesa= new \Safaricom\Mpesa\Mpesa();

$callbackData=$mpesa->getDataFromCallback();

Finishing a transaction After obtaining the Post data from the callbacks, use this at the end of your callback routes to complete the transaction

$mpesa= new \Safaricom\Mpesa\Mpesa();

$callbackData=$mpesa->finishTransaction();

If validation fails, pass false to finishTransaction()

$mpesa= new \Safaricom\Mpesa\Mpesa();

$callbackData=$mpesa->finishTransaction(false);

mpesa-php-sdk's People

Contributors

ialeke avatar jamesvanwaza avatar mossey avatar ngarawakimani avatar nicholaskimuli avatar sadick254 avatar urandu avatar wangai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mpesa-php-sdk's Issues

TransactionCallbacks result for c2b has the same value for both key and value

This is the result: { "20190630070754":"20190630070754", "100.00":"100.00", "603005":"603005", "acb":"acb", "254708374149":"254708374149", "NFU51H9FM1":"NFU51H9FM1" }

This is the code from the callbacks:
$result=[$transTime=>$transTime, $transAmount=>$transAmount, businessShortCode=>$businessShortCode, $billRefNumber=>$billRefNumber, $invoiceNumber=>$invoiceNumber, $orgAccountBalance=>$orgAccountBalance, $thirdPartyTransID=>$thirdPartyTransID, $MSISDN=>$MSISDN, $firstName=>$firstName, $lastName=>$lastName, $middleName=>$middleName, $transID=>$transID, $transactionType=>$transactionType ];

The keys should be enclosed in a string

Security Credential

Do you have a clear way of how SecurityCredential is generated? I have tried but keeps failing.

$certFile = 'mpesa_public_cert.cer';
$certContent = file_get_contents($certFile);
$publicKey = openssl_pkey_get_public($certContent);
$encrypted = '';
openssl_public_encrypt($plaintext, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING);
return base64_encode($encrypted);

Understanding the response of c2b transaction.

Hi,
I am using mpsea-php-sdk which is great but I am not able to understand what does the c2b transaction returns in response. I am getting below response.
"{ "ConversationID": "AG_20180402_00004a92452ef78e864d", "OriginatorCoversationID": "12362-3240472-1", "ResponseDescription": "Accept the service request successfully." } "

What does this mean?? I am not able to fetch success code or something like that. Am i missing something ?

mpesa payment b2c

Fatal error: Call to undefined function Safaricom\Mpesa\env() in
env() error.

env variables returning null if config is cached

Hi! good work on this however, there's a slight issue with how you get the env variables in the Mpesa class. Once the config is cached, via config:cache, the .env file is no longer loaded and calls to the env function return null. I'd suggest you create a config file for the sdk where the consumer keys and secret or any other variable can be set.

Assigning variable values as keys in array

From Line 164 of the TransactionCallbacks.php

$result=[
$transTime=>$transTime,
$transAmount=>$transAmount,
$businessShortCode=>$businessShortCode,
$billRefNumber=>$billRefNumber,
$invoiceNumber=>$invoiceNumber,
$orgAccountBalance=>$orgAccountBalance,
$thirdPartyTransID=>$thirdPartyTransID,
$MSISDN=>$MSISDN,
$firstName=>$firstName,
$lastName=>$lastName,
$middleName=>$middleName,
$transID=>$transID,
$transactionType=>$transactionType
];

The code above should be:
$result=[
"transTime"=>$transTime,
''transAmount"=>$transAmount,
"businessShortCode"=>$businessShortCode,
"billRefNumber"=>$billRefNumber,
"invoiceNumber"=>$invoiceNumber,
"orgAccountBalance"=>$orgAccountBalance,
"thirdPartyTransID"=>$thirdPartyTransID,
"MSISDN"=>$MSISDN,
"firstName"=>$firstName,
'"lastName"=>$lastName,
"middleName"=>$middleName,
"transID"=>$transID,
"transactionType"=>$transactionType
];

How to register new urls

is there a way to register new urls
registering new urls responds with

{ ConversationID: '',
  OriginatorCoversationID: '',
  ResponseDescription: 'Validation and Confirmation URLs are already registered' }

Composer autoload path not working: ../vendor/autoload.php

Warning: include_once(../vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/mpesa/src/Mpesa.php on line 10

I get this error message whenever I am trying to use your PHP SDK. I think this is a bug for your relative paths to composer autoload file. I have also run composer install but issue is still persistent.

I am using your PHP SDK version 1.0.8. Please help as it does not work out of the box and I am stuck on this error
mpesa-autoload-failure
.

Thank you.

Mismatch between comment and actual method

There is a misleading comment in the mpesa class . The comment says that the function should be called for a B2C transaction while the actual function is a c2b.

/**
 * Use this function to initiate a B2C transaction
 * @param $ShortCode | 6 digit M-Pesa Till Number or PayBill Number
 * @param $CommandID | Unique command for each transaction type.
 * @param $Amount | The amount been transacted.
 * @param $Msisdn | MSISDN (phone number) sending the transaction, start with country code without the plus(+) sign.
 * @param $BillRefNumber | 	Bill Reference Number (Optional).
 * @return mixed|string
 */
public  static  function  c2b($ShortCode, $CommandID, $Amount, $Msisdn, $BillRefNumber ){
    $environment=env("MPESA_ENV");

    if( $environment =="live"){
        $url = 'https://api.safaricom.co.ke/mpesa/c2b/v1/simulate';
        $token=self::generateLiveToken();
    }elseif ($environment=="sandbox"){
        $url = 'https://sandbox.safaricom.co.ke/mpesa/c2b/v1/simulate';
        $token=self::generateSandBoxToken();
    }else{
        return json_encode(["Message"=>"invalid application status"]);
    }



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

    $curl_post_data = array(
        'ShortCode' => $ShortCode,
        'CommandID' => $CommandID,
        'Amount' => $Amount,
        'Msisdn' => $Msisdn,
        'BillRefNumber' => $BillRefNumber
    );

    $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_HEADER, false);
    $curl_response = curl_exec($curl);
    return $curl_response;

}

please check it out

STK PUSH Minor Bug

Kindly guys, I love the work u guys are doing. However, there is a bug on stkPush part.
public function STKPushSimulation($BusinessShortCode, $LipaNaMpesaPasskey, $TransactionType, $Amount, $PartyA, $PartyB, $PhoneNumber, $CallBackURL, $AccountReference, $TransactionDesc, $Remark){ $live=env("application_status"); if( $live =="true"){ $url = 'https://api.safaricom.co.ke/mpesa/stkpush/v1/processrequest'; $token=self::generateLiveToken(); }elseif ($live=="sandbox"){ $url = 'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest'; $token=self::generateSandBoxToken(); }else{ return json_encode(["Message"=>"invalid application status"]); }

Under if( $live =="true"){
true should be live.

Validation and Confirmation URL Artisan Command

Hey, this SDK is really great. I have been able to successfully integrate. Just a thought: is it possible to add an artisan cli command to register validation and confirmation urls? The developer can run this artisan command once at application startup and can either specify those urls or the sdk automatically pick from env('APP_URL').
Thanks.

AccountBalance API returns "The initiator information is invalid."

I've followed the documentation for the AccountBalance but keep ending up with the same message, that the Initiator information is invalid. I'm assuming this could be one of two possibilites, either the $Initiator value is wrong or the $SecurityCredential.

This is how I'm computing the $securityCredential

    $plainTextPwd = 'somePassword';
    $pubKeyFile =  __DIR__ . "/cert/cert.cer";
    $publicKey = '';
    if(\is_file($pubKeyFile)){
        $publicKey = file_get_contents($pubKeyFile);
        openssl_public_encrypt($plainTextPwd, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING);
        $securityCredential = base64_encode($encrypted);
        echo $securityCredential; // This is my $SecurityCredential value
    }else{
        throw new \Exception("Please provide a valid public key file");
    }

Which gives me a $securityCredential which is 344 characters long.

As for the $Initiator
This is what the documentation says at https://developer.safaricom.co.ke/account-balance/apis/post/query

Initiator
This is the credential/username used to authenticate the transaction request

My confusion is - what is credential/username given that there is an initiator username and there is an initiator credential (assuming credential means password)?

I've tried using either but still get the same message though - "Initiator information is invalid.". What could be happening?

A small correction in TransactionCallbacks.php

line 255 of TransactionCallbacks.php reads
$amount=$callbackData->stkCallback->Body->CallbackMetadata->Item[0]->Value;

it should be

$amount=$callbackData->Body->stkCallback->CallbackMetadata->Item[0]->Value;

Trying to understand the $SecurtyCredential parameter in AccountBalance API

I've been trying to figure out what exactly the $SecurityCredential is in the AccountBalance api request. From the documentation, it defines this parameter as

"Base64 encoded string of the M-Pesa short code and password, which is encrypted using M-Pesa public key and validates the transaction on M-Pesa Core system."

So my question is:

$SecurityCredential = base64_encode($shortCode.$password);

From the above statement, what exactly is $password? Is it the passkey given in the portal? Is $shortCode the short code 1 given in the portal in test credentials or is it the lipa na mpesa online short code?

It seems if I pass a variety of combinations to that parameter, I get the same result:

object(stdClass)#5 (4) {
  ["OriginatorConversationID"]=>
  string(14) "4137-1548347-1"
  ["ConversationID"]=>
  string(32) "AG_20191002_000055f9b17ae44e2f9e"
  ["ResponseCode"]=>
  string(1) "0"
  ["ResponseDescription"]=>
  string(40) "Accept the service request successfully."
}

Wrong implementation of stk push function

The implementation of stk push function does not match the documentation in the developer portal
Timestamp parameter is missing and there is an added remarks parameter that does not exist in the documentation

this is what the documentation says:
<?php

$curl_post_data = array(
//Fill in the request parameters with valid values
'BusinessShortCode' => ' ',
'Password' => ' ',
'Timestamp' => ' ',
'TransactionType' => 'CustomerPayBillOnline',
'Amount"' => ' ',
'PartyA' => ' ',
'PartyB' => ' ',
'PhoneNumber' => ' ',
'CallBackURL' => 'https://ip_address:port/callback',
'AccountReference' => ' ',
'TransactionDesc' => ' '
);

$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);
print_r($curl_response);

echo $curl_response;
?>

Unable to install the package

After running composer require safaricom/mpesa i get the errror.

Could not find package safaricom/mpesa at any version for your minimum-stability (stable). Check the package spelling or your minimum-stability

question

in the reversal api does anyone has an idea what is the initiators id and password

Possible typo on:

RecieverIdentifierType —— Should be —— ReceiverIdentifierType

How to check for callback responses?

Hi,
Thanks for this sdk.
I would like to know how to check for callback responses to determine if m route needs to be debugged.
The curl requests are processed successfully but i am not receiving any callback responses.

laravel issue on config:cache

When using this SDK inside a laravel project, the package fails to read the env variables if you run the config:cache command.

It's only able to pick the MPESA secret and keys after running config:clear Which is weird because we need to be able to cache our configurations to improve on performance.

I have used the package in a couple of projects, great work. I always run config:cache and it messes me up big time.

STKPushQuery() has a bug

Kindly update the public static function STKPushQuery() to exclude the $live or $environment parameter as this creates confusion when using this function. The user ends with an error similar to the one below:

"Type error: Too few arguments to function Safaricom\Mpesa\Mpesa::STKPushQuery(), 4 passed in /home/vagrant/code/myProject/app/Http/Controllers/PaymentsController.php on line 73 and exactly 5 expected"

After amending the aforementioned function, my code is now working as expected

function to get data from callback is returning a non object

Hi,
I totally love how this package has simplified the API and I've been using it for a while now. However, I noted that there was an issue with the result returned by the getDataFromCallback method.

What is expected is a JSON object, but for some reason, the result is a "non-object" that brings up that common error of "trying to get property 'x' of non-object". Upon logging the result, I could swear it looked like an object with accessible properties. Here is an example of a logged result:

{ "TransactionType": "Pay Bill", "TransID": "NCD81H87FU", "TransTime": "20190313163806", "TransAmount": "100.00", "BusinessShortCode": "600364", "BillRefNumber": "0000", "InvoiceNumber": "", "OrgAccountBalance": "129635.00", "ThirdPartyTransID": "", "MSISDN": "254708374149", "FirstName": "John", "MiddleName": "J.", "LastName": "Doe" }

I ended up taking the posted request as it was (an array) and handling it from my controller directly before using the finishTransaction method to send a response to the API.

Could you tell me a way to make it stop bringing up that said error? I'm impartial about retrieving the values from an array due to efficiency issues(even though it works). Any help would be appreciated. Thanks!

Callback value

Is there a way to pass some value when initializing transactions and the same value will be return as callback values?

e.g

return [
‘invoice’ : ‘inv100837’
];

and the callback value will be like:

{
"Body": {
"stkCallback": {
"MerchantRequestID": "29115-34620561-1",
"CheckoutRequestID": "ws_CO_191220191020363925",
"ResultCode": 0,
"ResultDesc": "The service request is processed successfully.",
"CallbackMetadata": {
"Item": [{
"Name": "Amount",
"Value": 1.00
},
{
"Name": "MpesaReceiptNumber",
"Value": "NLJ7RT61SV"
},
{
"Name": "TransactionDate",
"Value": 20191219102115
},
{
"Name": "PhoneNumber",
"Value": 254708374149
}],

     return [
          “invoice”: “inv100837”
                 ]
     }        
  }    

}
}

the invoice number can be use to verify the transactions.

load environment configs from database

Would be great if there was a way to set the environment configs on every request, like load the required values from a database before calling e.g. like
//Example
`$mpesa->setConfigs( [
MPESA_CONSUMER_KEY= [consumer key]
MPESA_CONSUMER_SECRET=[consumer secret]
MPESA_ENV=[live or sandbox]
];
);

$mpesa->STKPushSimulation();`

Using IIS to host the app

Hi,
I noticed that when using IIS, the server will try to verify SSL on both the host and the peer.
If you are using IIS, I recommend adding these lines to each post request you make from the package (c2b, stk, b2b, etc):

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

cheers :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.