· 5 years ago · May 18, 2020, 12:50 PM
1<?php
2
3/**
4 * Class Mpesa
5 * @package Safaricom\Mpesa
6 */
7class Mpesa
8{
9
10 /**
11 * @var null $consumer_key
12 */
13 private $consumer_key = null;
14
15 /**
16 * @var null $consumer_secret
17 */
18 private $consumer_secret = null;
19
20 /**
21 * @var null $application_status
22 */
23 private $application_status = null;
24
25 /**
26 * @var null $apiUrl
27 */
28 private $apiUrl = null;
29
30 /**
31 * @var null $tokenUrl
32 */
33 private $tokenUrl = null;
34
35 /**
36 * Constructor
37 */
38 public function __construct()
39 {
40 $this->CI = &get_instance();
41 $this->CI->config->load('mpesa', true);
42
43 $mpesa_config = $this->CI->config->item('mpesa');
44
45 if (!isset($mpesa_config['consumer_key']) || !isset($mpesa_config['consumer_secret']) || !isset($mpesa_config['application_status'])) {
46 die("please ensure that your config file has values for all variables");
47 }
48
49 $this->consumer_key = $mpesa_config['consumer_key'];
50 $this->consumer_secret = $mpesa_config['consumer_secret'];
51 $this->application_status = $mpesa_config['application_status'];
52
53 if ($this->application_status == "live") {
54 // live api url
55 $this->apiUrl = $mpesa_config['live_url'];
56 // live token url
57 $this->tokenUrl = $mpesa_config['live_token_url'];
58 } elseif ($this->application_status == "sandbox") {
59 //sandbpx api url
60 $this->apiUrl = $mpesa_config['sandbox_url'];
61 // live token url
62 $this->tokenUrl = $mpesa_config['sandbox_token_url'];
63 } else {
64 die("please ensure that your config file has the right values for all variables");
65 }
66 }
67
68 /**
69 * use this function to generate a token
70 * @return mixed
71 */
72 private function generateToken()
73 {
74 $curl = curl_init();
75 curl_setopt($curl, CURLOPT_URL, $this->tokenUrl);
76 $credentials = base64_encode($this->consumer_key . ':' . $this->consumer_secret);
77 curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Basic ' . $credentials)); //setting a custom header
78 curl_setopt($curl, CURLOPT_HEADER, false);
79 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
80
81 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
82
83 $curl_response = curl_exec($curl);
84
85 return json_decode($curl_response)->access_token;
86 }
87
88 /**
89 * Use this function to initiate a reversal request
90 * @param $CommandID | Takes only 'TransactionReversal' Command id
91 * @param $Initiator | The name of Initiator to initiating the request
92 * @param $SecurityCredential | Encrypted Credential of user getting transaction amount
93 * @param $TransactionID | Unique Id received with every transaction response.
94 * @param $Amount | Amount
95 * @param $ReceiverParty | Organization /MSISDN sending the transaction
96 * @param $RecieverIdentifierType | Type of organization receiving the transaction
97 * @param $ResultURL | The path that stores information of transaction
98 * @param $QueueTimeOutURL | The path that stores information of time out transaction
99 * @param $Remarks | Comments that are sent along with the transaction.
100 * @param $Occasion | Optional Parameter
101 * @return mixed|string
102 */
103 public function reversal($CommandID, $Initiator, $SecurityCredential, $TransactionID, $Amount, $ReceiverParty, $RecieverIdentifierType, $ResultURL, $QueueTimeOutURL, $Remarks, $Occasion)
104 {
105 $url = $this->apiUrl . 'reversal/v1/request';
106 $data = array(
107 'CommandID' => $CommandID,
108 'Initiator' => $Initiator,
109 'SecurityCredential' => $SecurityCredential,
110 'TransactionID' => $TransactionID,
111 'Amount' => $Amount,
112 'ReceiverParty' => $ReceiverParty,
113 'RecieverIdentifierType' => $RecieverIdentifierType,
114 'ResultURL' => $ResultURL,
115 'QueueTimeOutURL' => $QueueTimeOutURL,
116 'Remarks' => $Remarks,
117 'Occasion' => $Occasion,
118 );
119 return $this->_curl_request($url, $data);
120 }
121
122 /**
123 * @param $InitiatorName | This is the credential/username used to authenticate the transaction request.
124 * @param $SecurityCredential | Encrypted password for the initiator to autheticate the transaction request
125 * @param $CommandID | Unique command for each transaction type e.g. SalaryPayment, BusinessPayment, PromotionPayment
126 * @param $Amount | The amount being transacted
127 * @param $PartyA | Organization’s shortcode initiating the transaction.
128 * @param $PartyB | Phone number receiving the transaction
129 * @param $Remarks | Comments that are sent along with the transaction.
130 * @param $QueueTimeOutURL | The timeout end-point that receives a timeout response.
131 * @param $ResultURL | The end-point that receives the response of the transaction
132 * @param $Occasion | Optional
133 * @return string
134 */
135 public function b2c($InitiatorName, $SecurityCredential, $CommandID, $Amount, $PartyA, $PartyB, $Remarks, $QueueTimeOutURL, $ResultURL, $Occasion)
136 {
137
138 $url = $this->apiUrl . 'b2c/v1/paymentrequest';
139 $data = array(
140 'InitiatorName' => $InitiatorName,
141 'SecurityCredential' => $SecurityCredential,
142 'CommandID' => $CommandID,
143 'Amount' => $Amount,
144 'PartyA' => $PartyA,
145 'PartyB' => $PartyB,
146 'Remarks' => $Remarks,
147 'QueueTimeOutURL' => $QueueTimeOutURL,
148 'ResultURL' => $ResultURL,
149 'Occasion' => $Occasion,
150 );
151
152 return $this->_curl_request($url, $data);
153 }
154 /**
155 * Use this function to initiate a C2B transaction
156 * @param $ShortCode | 6 digit M-Pesa Till Number or PayBill number
157 * @param $CommandID | Unique command for each transaction type.
158 * values: CustomerPayBillOnline,CustomerBuyGoodsOnline
159 * @param $Amount | The amount being transacted.
160 * @param $Msisdn | MSISDN (phone number) sending the transaction, start with country code without the plus(+) sign. e.g 254XXXXXXXXX
161 * @param $BillRefNumber | Bill Reference Number (Optional).
162 * @return mixed|string
163 */
164 public function c2b($ShortCode, $CommandID, $Amount, $Msisdn, $BillRefNumber)
165 {
166 $url = $this->apiUrl . 'c2b/v1/simulate';
167 $data = array(
168 'ShortCode' => $ShortCode,
169 'CommandID' => $CommandID,
170 'Amount' => $Amount,
171 'Msisdn' => $Msisdn,
172 'BillRefNumber' => $BillRefNumber,
173 );
174 return $this->_curl_request($url, $data);
175 }
176
177 /**
178 * Use this to initiate a balance inquiry request
179 * @param $CommandID | A unique command passed to the M-Pesa system e.g. AccountBalance.
180 * @param $Initiator | This is the credential/username used to authenticate the transaction request.
181 * @param $SecurityCredential | Encrypted password for the initiator to autheticate the transaction request
182 * @param $PartyA | Type of organization receiving the transaction
183 * @param $IdentifierType |Type of organization receiving the transaction
184 * @param $Remarks | Comments that are sent along with the transaction.
185 * @param $QueueTimeOutURL | The path that stores information of time out transaction
186 * @param $ResultURL | The path that stores information of transaction
187 * @return mixed|string
188 */
189 public function accountBalance($CommandID, $Initiator, $SecurityCredential, $PartyA, $IdentifierType, $Remarks, $QueueTimeOutURL, $ResultURL)
190 {
191
192 $url = $this->apiUrl . 'accountbalance/v1/query';
193 $data = array(
194 'CommandID' => $CommandID,
195 'Initiator' => $Initiator,
196 'SecurityCredential' => $SecurityCredential,
197 'PartyA' => $PartyA,
198 'IdentifierType' => $IdentifierType,
199 'Remarks' => $Remarks,
200 'QueueTimeOutURL' => $QueueTimeOutURL,
201 'ResultURL' => $ResultURL,
202 );
203
204 return $this->_curl_request($url, $data);
205 }
206
207 /**
208 * Use this function to make a transaction status request
209 * @param $Initiator | The name of Initiator to initiating the request.
210 * @param $SecurityCredential | Encrypted password for the initiator to autheticate the transaction request.
211 * @param $CommandID | Unique command for each transaction type, possible values are: TransactionStatusQuery.
212 * @param $TransactionID | Organization Receiving the funds.
213 * @param $PartyA | Organization/MSISDN sending the transaction
214 * @param $IdentifierType | Type of organization receiving the transaction
215 * @param $ResultURL | The path that stores information of transaction
216 * @param $QueueTimeOutURL | The path that stores information of time out transaction
217 * @param $Remarks | Comments that are sent along with the transaction
218 * @param $Occasion | Optional Parameter
219 * @return mixed|string
220 */
221 public function transactionStatus($Initiator, $SecurityCredential, $CommandID, $TransactionID, $PartyA, $IdentifierType, $ResultURL, $QueueTimeOutURL, $Remarks, $Occasion)
222 {
223 $url = $this->apiUrl . 'transactionstatus/v1/query';
224 $data = array(
225 'Initiator' => $Initiator,
226 'SecurityCredential' => $SecurityCredential,
227 'CommandID' => $CommandID,
228 'TransactionID' => $TransactionID,
229 'PartyA' => $PartyA,
230 'IdentifierType' => $IdentifierType,
231 'ResultURL' => $ResultURL,
232 'QueueTimeOutURL' => $QueueTimeOutURL,
233 'Remarks' => $Remarks,
234 'Occasion' => $Occasion,
235 );
236
237 return $this->_curl_request($url, $data);
238 }
239
240 /**
241 * Use this function to initiate a B2B request
242 * @param $Initiator | This is the credential/username used to authenticate the transaction request.
243 * @param $SecurityCredential | Encrypted password for the initiator to autheticate the transaction request.
244 * @param $Amount | Base64 encoded string of the B2B short code and password, which is encrypted using M-Pesa public key and validates the transaction on M-Pesa Core system.
245 * @param $PartyA | Organization’s short code initiating the transaction.
246 * @param $PartyB | Organization’s short code receiving the funds being transacted.
247 * @param $Remarks | Comments that are sent along with the transaction.
248 * @param $QueueTimeOutURL | The path that stores information of time out transactions.it should be properly validated to make sure that it contains the port, URI and domain name or publicly available IP.
249 * @param $ResultURL | The path that receives results from M-Pesa it should be properly validated to make sure that it contains the port, URI and domain name or publicly available IP.
250 * @param $AccountReference | Account Reference mandatory for “BusinessPaybill” CommandID.
251 * @param $commandID | Unique command for each transaction type, possible values are: BusinessPayBill, MerchantToMerchantTransfer, MerchantTransferFromMerchantToWorking, MerchantServicesMMFAccountTransfer, AgencyFloatAdvance
252 * @param $SenderIdentifierType | Type of organization sending the transaction.
253 * @param $RecieverIdentifierType | Type of organization receiving the funds being transacted.
254
255 * @return mixed|string
256 */
257 public function b2b($Initiator, $SecurityCredential, $Amount, $PartyA, $PartyB, $Remarks, $QueueTimeOutURL, $ResultURL, $AccountReference, $commandID, $SenderIdentifierType, $RecieverIdentifierType)
258 {
259 $url = $this->apiUrl . 'b2b/v1/paymentrequest';
260 $data = array(
261 'Initiator' => $Initiator,
262 'SecurityCredential' => $SecurityCredential,
263 'CommandID' => $commandID,
264 'SenderIdentifierType' => $SenderIdentifierType,
265 'RecieverIdentifierType' => $RecieverIdentifierType,
266 'Amount' => $Amount,
267 'PartyA' => $PartyA,
268 'PartyB' => $PartyB,
269 'AccountReference' => $AccountReference,
270 'Remarks' => $Remarks,
271 'QueueTimeOutURL' => $QueueTimeOutURL,
272 'ResultURL' => $ResultURL,
273 );
274
275 return $this->_curl_request($url, $data);
276 }
277
278 /**
279 * Use this function to initiate an STKPush Simulation
280 * @param $BusinessShortCode | The organization shortcode used to receive the transaction.
281 * @param $LipaNaMpesaPasskey | The password for encrypting the request. This is generated by base64 encoding BusinessShortcode, Passkey and Timestamp.
282 * @param $TransactionType | The transaction type to be used for this request. Only CustomerPayBillOnline is supported.
283 * @param $Amount | The amount to be transacted.
284 * @param $PartyA | The MSISDN sending the funds.
285 * @param $PartyB | The organization shortcode receiving the funds
286 * @param $PhoneNumber | The MSISDN sending the funds.
287 * @param $CallBackURL | The url to where responses from M-Pesa will be sent to.
288 * @param $AccountReference | Used with M-Pesa PayBills.
289 * @param $TransactionDesc | A description of the transaction.
290 * @param $Remark | Remarks
291 * @return mixed|string
292 */
293 public function STKPushSimulation($BusinessShortCode, $LipaNaMpesaPasskey, $TransactionType, $Amount, $PartyA, $PartyB, $PhoneNumber, $CallBackURL, $AccountReference, $TransactionDesc, $Remark)
294 {
295 $url = $this->apiUrl . 'stkpush/v1/processrequest';
296
297 $timestamp = '20' . date("ymdhis");
298 $password = base64_encode($BusinessShortCode . $LipaNaMpesaPasskey . $timestamp);
299
300 $data = array(
301 'BusinessShortCode' => $BusinessShortCode,
302 'Password' => $password,
303 'Timestamp' => $timestamp,
304 'TransactionType' => $TransactionType,
305 'Amount' => $Amount,
306 'PartyA' => $PartyA,
307 'PartyB' => $PartyB,
308 'PhoneNumber' => $PhoneNumber,
309 'CallBackURL' => $CallBackURL,
310 'AccountReference' => $AccountReference,
311 'TransactionDesc' => $TransactionDesc,
312 'Remark' => $Remark
313 );
314 return $this->_curl_request($url, $data);
315 }
316
317 /**
318 * Use this function to initiate an STKPush Status Query request.
319 * @param $checkoutRequestID | Checkout RequestID
320 * @param $businessShortCode | Business Short Code
321 * @param $password | Password
322 * @param $timestamp | Timestamp
323 * @return mixed|string
324 */
325 public function STKPushQuery($checkoutRequestID, $businessShortCode, $password, $timestamp)
326 {
327 $url = $this->apiUrl . 'stkpushquery/v1/query';
328 $data = array(
329 'BusinessShortCode' => $businessShortCode,
330 'Password' => $password,
331 'Timestamp' => $timestamp,
332 'CheckoutRequestID' => $checkoutRequestID,
333 );
334 return $this->_curl_request($url, $data);
335 }
336
337 /**
338 *Use this function to confirm all transactions in callback routes
339 */
340 public function finishTransaction()
341 {
342 $resultArray = [
343 "ResultDesc" => "Confirmation Service request accepted successfully",
344 "ResultCode" => "0",
345 ];
346 header('Content-Type: application/json');
347
348 echo json_encode($resultArray);
349 }
350
351 /**
352 *Use this function to get callback data posted in callback routes
353 */
354 public function getDataFromCallback()
355 {
356 $callbackJSONData = file_get_contents('php://input');
357 return json_decode($callbackJSONData);
358// return $callbackJSONData;
359 }
360
361
362
363 private function _curl_request($url, $curl_post_data)
364 {
365 $data_string = json_encode($curl_post_data);
366 $token = $this->generateToken();
367
368 $curl = curl_init();
369 curl_setopt($curl, CURLOPT_URL, $url);
370 curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Authorization:Bearer ' . $token));
371 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
372 curl_setopt($curl, CURLOPT_POST, true);
373 curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
374 curl_setopt($curl, CURLOPT_HEADER, false);
375
376 $curl_response = curl_exec($curl);
377
378 return json_decode($curl_response);
379 }
380
381
382}