├── Tutorial 10
├── B2CResultURL.php
└── b2c.php
├── Tutorial 11
├── B2BResultURL.php
└── b2b.php
├── Tutorial 12 - Balance Query
├── bal_callback_url.php
└── bal.php
├── Tutorial 9
├── callback_url.php
└── stk_initiate.php
├── Reversal API
├── reverse_ResultURL.php
└── reverse_transaction.php
├── Transaction Status
├── ResultURL.php
└── transaction_status_query.php
├── sample_response.txt
├── Turorial 1
└── confirmation_url.php
├── access_token.php
├── Tutorial 2
├── mobile_payments.sql
├── confirmation_url.php
└── config.php
├── validation_url.php
├── LICENSE
├── simulate.php
├── register_url.php
└── README.md
/Tutorial 10/B2CResultURL.php:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/access_token.php:
--------------------------------------------------------------------------------
1 | access_token;
20 |
21 | echo $access_token;
22 |
23 | curl_close($curl);
24 | ?>
25 |
--------------------------------------------------------------------------------
/Tutorial 2/mobile_payments.sql:
--------------------------------------------------------------------------------
1 |
2 | -- Copy this code to your SQL query box and run. Ensure you have selected the database on config.php
3 | -- Database not optimised for now.
4 | -- Custom fields can also be added
5 |
6 | CREATE table mobile_payments(
7 | transLoID int AUTO_INCREMENT not null,
8 | TransactionType varchar(10) not null,
9 | TransID varchar(10) not null,
10 | TransTime varchar(14) not null,
11 | TransAmount varchar(6) not null,
12 | BusinessShortCode varchar(6) not null,
13 | BillRefNumber varchar(6) not null,
14 | InvoiceNumber varchar(6) not null,
15 | OrgAccountBalance varchar(10) not null,
16 | ThirdPartyTransID varchar(10) not null,
17 | MSISDN varchar(14) not null,
18 | FirstName varchar(10),
19 | MiddleName varchar(10),
20 | LastName varchar(10),
21 | PRIMARY KEY (transLoID),
22 | UNIQUE(TransID)
23 | ) Engine=innoDB;
24 |
--------------------------------------------------------------------------------
/validation_url.php:
--------------------------------------------------------------------------------
1 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Ben Njunge
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/simulate.php:
--------------------------------------------------------------------------------
1 | $ShortCode,
17 | 'CommandID' => 'CustomerPayBillOnline',
18 | 'Amount' => $amount,
19 | 'Msisdn' => $msisdn,
20 | 'BillRefNumber' => $billRef
21 | );
22 |
23 | $data_string = json_encode($curl_post_data);
24 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
25 | curl_setopt($curl, CURLOPT_POST, true);
26 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
27 | $curl_response = curl_exec($curl);
28 | print_r($curl_response);
29 |
30 | echo $curl_response;
31 | ?>
32 |
--------------------------------------------------------------------------------
/register_url.php:
--------------------------------------------------------------------------------
1 | $shortCode,
21 | 'ResponseType' => 'Completed',
22 | 'ConfirmationURL' => $confirmationUrl,
23 | 'ValidationURL' => $validationUrl
24 | );
25 |
26 | $data_string = json_encode($curl_post_data);
27 |
28 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
29 | curl_setopt($curl, CURLOPT_POST, true);
30 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
31 |
32 | $curl_response = curl_exec($curl);
33 | print_r($curl_response);
34 |
35 | echo $curl_response;
36 | ?>
37 |
--------------------------------------------------------------------------------
/Reversal API/reverse_transaction.php:
--------------------------------------------------------------------------------
1 | access_token;
16 | curl_close($curl);
17 |
18 | /* Reversal Request */
19 | $reversal_url = 'https://sandbox.safaricom.co.ke/mpesa/reversal/v1/request';
20 |
21 | $curl = curl_init();
22 | curl_setopt($curl, CURLOPT_URL, $reversal_url);
23 | curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.$access_token)); //setting custom header
24 |
25 | $curl_post_data = array(
26 | //Fill in the request parameters with valid values
27 | 'Initiator' => '',
28 | 'SecurityCredential' => '',
29 | 'CommandID' => 'TransactionReversal',
30 | 'TransactionID' => '',
31 | 'Amount' => '',
32 | 'ReceiverParty' => '',
33 | 'RecieverIdentifierType' => '',
34 | 'ResultURL' => '',
35 | 'QueueTimeOutURL' => '',
36 | 'Remarks' => 'OUT OF STOCK',
37 | 'Occasion' => ''
38 | );
39 |
40 | $data_string = json_encode($curl_post_data);
41 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
42 | curl_setopt($curl, CURLOPT_POST, true);
43 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
44 | $curl_response = curl_exec($curl);
45 | print_r($curl_response);
46 | echo $curl_response;
47 |
48 | ?>
49 |
--------------------------------------------------------------------------------
/Tutorial 2/confirmation_url.php:
--------------------------------------------------------------------------------
1 | $jsonMpesaResponse['TransactionType'],
22 | ':TransID' => $jsonMpesaResponse['TransID'],
23 | ':TransTime' => $jsonMpesaResponse['TransTime'],
24 | ':TransAmount' => $jsonMpesaResponse['TransAmount'],
25 | ':BusinessShortCode' => $jsonMpesaResponse['BusinessShortCode'],
26 | ':BillRefNumber' => $jsonMpesaResponse['BillRefNumber'],
27 | ':InvoiceNumber' => $jsonMpesaResponse['InvoiceNumber'],
28 | ':OrgAccountBalance' => $jsonMpesaResponse['OrgAccountBalance'],
29 | ':ThirdPartyTransID' => $jsonMpesaResponse['ThirdPartyTransID'],
30 | ':MSISDN' => $jsonMpesaResponse['MSISDN'],
31 | ':FirstName' => $jsonMpesaResponse['FirstName'],
32 | ':MiddleName' => $jsonMpesaResponse['MiddleName'],
33 | ':LastName' => $jsonMpesaResponse['LastName']
34 | );
35 |
36 | // write to file
37 | $log = fopen($logFile, "a");
38 | fwrite($log, $mpesaResponse);
39 | fclose($log);
40 |
41 | echo $response;
42 |
43 | // this will insert to database.
44 | insert_response($transaction);
45 | ?>
46 |
--------------------------------------------------------------------------------
/Transaction Status/transaction_status_query.php:
--------------------------------------------------------------------------------
1 | access_token;
16 | curl_close($curl);
17 |
18 |
19 | /* making the request */
20 | $tstatus_url = 'https://sandbox.safaricom.co.ke/mpesa/transactionstatus/v1/query';
21 |
22 | $curl = curl_init();
23 | curl_setopt($curl, CURLOPT_URL, $tstatus_url);
24 | curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.$access_token)); //setting custom header
25 |
26 | $curl_post_data = array(
27 | //Fill in the request parameters with valid values
28 | 'Initiator' => '',
29 | 'SecurityCredential' => '',
30 | 'CommandID' => 'TransactionStatusQuery',
31 | 'TransactionID' => '',
32 | 'PartyA' => '', // shortcode 1
33 | 'IdentifierType' => '4',
34 | 'ResultURL' => '',
35 | 'QueueTimeOutURL' => '',
36 | 'Remarks' => '',
37 | 'Occasion' => ''
38 | );
39 |
40 | $data_string = json_encode($curl_post_data);
41 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
42 | curl_setopt($curl, CURLOPT_POST, true);
43 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
44 | $curl_response = curl_exec($curl);
45 | print_r($curl_response);
46 | echo $curl_response;
47 | ?>
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MPESA-API-Tutorial
2 | This is a Daraja API MPESA tutorial repo.
3 | Find Video Tutorials https://www.youtube.com/playlist?list=PLcKuwRUZRXZL36Lb3e5eryz8K4mmrqgqs
4 |
5 |
6 | ## NOTE
7 | This is a tutorial version, issues to do with security have not been addresed and may or may not be addressed on this repo,
8 | however, we have the premium version that is bundled and constantly updated and maintained to meet the daily needs that you may
9 | have. Contact us for more details.
10 |
11 | # Ready Made
12 | ## Go Premium?
13 | Daraja Premium Code(DPC) is a library we have developed inhouse, that consumes Daraja API, and more of plug n' play. The code is available for purchase at KES 10,000 and if you need to monitor your transactions live on an android device/iOS Mobile, we have the apps ready integrated with our DPC at an addition of KES 5,000
14 | - This code is suitable for:
15 | - non-coders
16 | - Those who don't want to re-invent the wheel
17 |
18 | ## SurvPay Woocommerce
19 | We also have WordPress Plugin for KopoKopo and Daraja API that works on your WooCommerce Website. The code is priced at a one time fee of KE 5,000.
20 |
21 | ## Support
22 | - We no longer support the FREE Versions of Daraja codes we provide. If you need any support with a non premium code, we recommend checking our YouTube channel under the comments sections as most of the questions have been addressed.
23 | - For premium Code, our team is ready to assist any moment.
24 |
25 | ## Outsource API Services using our MpaaS(Mpesa as a service platform)
26 | - Gives you all the flexibility
27 | - Expert Support
28 | - 100% Uptime and Secure
29 | - 3 minutes. Time it takes to integrate and start using your live shortcode, yeah, we timed it.
30 | - Free 100 Transactions every month
31 | - No contracts.
32 | - Use your own branding and URL
33 | - Access to other services(Africas' Talking SMS platform, WhatsApp API, Airtime & KPLC APIs)
34 |
35 | Checkout more here https://dpc.survtechnologies.co.ke
36 |
37 | ## Why buy DPC?
38 | - No Coding Skills Required
39 | - Security inbuilt
40 | - Clean industry standard code
41 | - FREE Upgrades/Updates & Support
42 | - Monitor on Android/iOS
43 |
44 | Requests/Questions?
45 | Email: billing@survtechnologies.co.ke
46 | Messanger/Facebook Page fb.me/survtechKE/
47 |
--------------------------------------------------------------------------------
/Tutorial 12 - Balance Query/bal.php:
--------------------------------------------------------------------------------
1 | access_token;
17 | curl_close($curl);
18 |
19 | /* main request */
20 | $bal_url = 'https://sandbox.safaricom.co.ke/mpesa/accountbalance/v1/query';
21 |
22 | $curl = curl_init();
23 | curl_setopt($curl, CURLOPT_URL, $bal_url);
24 | curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.$access_token)); //setting custom header
25 |
26 | $curl_post_data = array(
27 | //Fill in the request parameters with valid values
28 | 'Initiator' => '', # initiator name -> For test, use Initiator name(Shortcode 1)
29 | 'SecurityCredential' => '', #Base64 encoded string of the Security Credential, which is encrypted using M-Pesa public key
30 | 'CommandID' => 'AccountBalance', # Command ID, Possible value AccountBalance
31 | 'PartyA' => '', # ShortCode 1, or your Paybill(During Production)
32 | 'IdentifierType' => '4',
33 | 'Remarks' => '', # Comments- Anything can go here
34 | 'QueueTimeOutURL' => '', # URL where Timeout Response will be sent to
35 | 'ResultURL' => '' # URL where Result Response will be sent to
36 | );
37 |
38 | $data_string = json_encode($curl_post_data);
39 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
40 | curl_setopt($curl, CURLOPT_POST, true);
41 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
42 | $curl_response = curl_exec($curl);
43 | print_r($curl_response);
44 | echo $curl_response;
45 | ?>
46 |
--------------------------------------------------------------------------------
/Tutorial 10/b2c.php:
--------------------------------------------------------------------------------
1 | access_token;
35 | curl_close($curl);
36 |
37 | /* Main B2C Request to the API */
38 | $b2cHeader = ['Content-Type:application/json','Authorization:Bearer '.$access_token];
39 | $curl = curl_init();
40 | curl_setopt($curl, CURLOPT_URL, $b2c_url);
41 | curl_setopt($curl, CURLOPT_HTTPHEADER, $b2cHeader); //setting custom header
42 |
43 | $curl_post_data = array(
44 | //Fill in the request parameters with valid values
45 | 'InitiatorName' => $InitiatorName,
46 | 'SecurityCredential' => $SecurityCredential,
47 | 'CommandID' => $CommandID,
48 | 'Amount' => $Amount,
49 | 'PartyA' => $PartyA,
50 | 'PartyB' => $PartyB,
51 | 'Remarks' => $Remarks,
52 | 'QueueTimeOutURL' => $QueueTimeOutURL,
53 | 'ResultURL' => $ResultURL,
54 | 'Occasion' => $Occasion
55 | );
56 |
57 | $data_string = json_encode($curl_post_data);
58 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
59 | curl_setopt($curl, CURLOPT_POST, true);
60 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
61 | $curl_response = curl_exec($curl);
62 | print_r($curl_response);
63 | echo $curl_response;
64 | ?>
65 |
--------------------------------------------------------------------------------
/Tutorial 2/config.php:
--------------------------------------------------------------------------------
1 | getMessage());
37 | }
38 |
39 | # 1.1.2 Insert Response to Database
40 | try{
41 | $insert = $con->prepare("INSERT INTO `mobile_payments`(`TransactionType`, `TransID`, `TransTime`, `TransAmount`, `BusinessShortCode`, `BillRefNumber`, `InvoiceNumber`, `OrgAccountBalance`, `ThirdPartyTransID`, `MSISDN`, `FirstName`, `MiddleName`, `LastName`) VALUES (:TransactionType, :TransID, :TransTime, :TransAmount, :BusinessShortCode, :BillRefNumber, :InvoiceNumber, :OrgAccountBalance, :ThirdPartyTransID, :MSISDN, :FirstName, :MiddleName, :LastName)");
42 | $insert->execute((array)($jsonMpesaResponse));
43 |
44 | # 1.1.2o Optional - Log the transaction to a .txt or .log file(May Expose your transactions if anyone gets the links, be careful with this. If you don't need it, comment it out or secure it)
45 | $Transaction = fopen('Transaction.txt', 'a');
46 | fwrite($Transaction, json_encode($jsonMpesaResponse));
47 | fclose($Transaction);
48 | }
49 | catch(PDOException $e){
50 |
51 | # 1.1.2b Log the error to a file. Optionally, you can set it to send a text message or an email notification during production.
52 | $errLog = fopen('error.txt', 'a');
53 | fwrite($errLog, $e->getMessage());
54 | fclose($errLog);
55 |
56 | # 1.1.2o Optional. Log the failed transaction. Remember, it has only failed to save to your database but M-PESA Transaction itself was successful.
57 | $logFailedTransaction = fopen('failedTransaction.txt', 'a');
58 | fwrite($logFailedTransaction, json_encode($jsonMpesaResponse));
59 | fclose($logFailedTransaction);
60 | }
61 | }
62 | ?>
63 |
--------------------------------------------------------------------------------
/Tutorial 11/b2b.php:
--------------------------------------------------------------------------------
1 | access_token;
17 | curl_close($curl);
18 |
19 | /* variables from Test Credentials on your developer account */
20 | $Initiator = ''; # Initiator Name (Shortcode 1)
21 | $SecurityCredential = ''; # SBase64 encoded string of the Security Credential, which is encrypted using M-Pesa public key
22 | $CommandID = ''; # possible values are: BusinessPayBill, MerchantToMerchantTransfer, MerchantTransferFromMerchantToWorking, MerchantServicesMMFAccountTransfer, AgencyFloatAdvance
23 | $SenderIdentifierType = '4'; # Type of organization sending the transaction.
24 | $Amount = '';
25 | $PartyA = ''; # Shortcode 1
26 | $PartyB = ''; # Shortcode 2
27 | $AccountReference = ''; # Account Reference mandatory for “BusinessPaybill” CommandID.
28 | $Remarks = ''; # Anything Goes here/string/int/varchar
29 | $QueueTimeOutURL = ''; # QueueTimeOutURL
30 | $ResultURL = ''; # ResultURL
31 | $b2bHeader = ['Content-Type:application/json','Authorization:Bearer '.$access_token];
32 |
33 | /* Main B2B API Call Section */
34 | $b2b_url = 'https://sandbox.safaricom.co.ke/mpesa/b2b/v1/paymentrequest';
35 | $curl = curl_init();
36 | curl_setopt($curl, CURLOPT_URL, $b2b_url);
37 | curl_setopt($curl, CURLOPT_HTTPHEADER, $b2bHeader); //setting custom header
38 |
39 | $curl_post_data = array(
40 | //Fill in the request parameters with valid values
41 | 'Initiator' => $Initiator,
42 | 'SecurityCredential' => $SecurityCredential,
43 | 'CommandID' => $CommandID,
44 | 'SenderIdentifierType' => $SenderIdentifierType,
45 | 'RecieverIdentifierType' => $SenderIdentifierType,
46 | 'Amount' => $Amount,
47 | 'PartyA' => $PartyA,
48 | 'PartyB' => $PartyB,
49 | 'AccountReference' => $AccountReference,
50 | 'Remarks' => $Remarks,
51 | 'QueueTimeOutURL' => $QueueTimeOutURL,
52 | 'ResultURL' => $ResultURL
53 | );
54 |
55 | $data_string = json_encode($curl_post_data);
56 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
57 | curl_setopt($curl, CURLOPT_POST, true);
58 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
59 | $curl_response = curl_exec($curl);
60 | print_r($curl_response);
61 | echo $curl_response;
62 | ?>
63 |
--------------------------------------------------------------------------------
/Tutorial 9/stk_initiate.php:
--------------------------------------------------------------------------------
1 | 20181004151020
29 | $Timestamp = date('YmdHis');
30 |
31 | # Get the base64 encoded string -> $password. The passkey is the M-PESA Public Key
32 | $Password = base64_encode($BusinessShortCode.$Passkey.$Timestamp);
33 |
34 | # header for access token
35 | $headers = ['Content-Type:application/json; charset=utf8'];
36 |
37 | # M-PESA endpoint urls
38 | $access_token_url = 'https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials';
39 | $initiate_url = 'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest';
40 |
41 | # callback url
42 | $CallBackURL = 'http://kidonda.us/projects/MPESA_API/callback_url.php';
43 |
44 | $curl = curl_init($access_token_url);
45 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
46 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
47 | curl_setopt($curl, CURLOPT_HEADER, FALSE);
48 | curl_setopt($curl, CURLOPT_USERPWD, $consumerKey.':'.$consumerSecret);
49 | $result = curl_exec($curl);
50 | $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
51 | $result = json_decode($result);
52 | $access_token = $result->access_token;
53 | curl_close($curl);
54 |
55 | # header for stk push
56 | $stkheader = ['Content-Type:application/json','Authorization:Bearer '.$access_token];
57 |
58 | # initiating the transaction
59 | $curl = curl_init();
60 | curl_setopt($curl, CURLOPT_URL, $initiate_url);
61 | curl_setopt($curl, CURLOPT_HTTPHEADER, $stkheader); //setting custom header
62 |
63 | $curl_post_data = array(
64 | //Fill in the request parameters with valid values
65 | 'BusinessShortCode' => $BusinessShortCode,
66 | 'Password' => $Password,
67 | 'Timestamp' => $Timestamp,
68 | 'TransactionType' => 'CustomerPayBillOnline',
69 | 'Amount' => $Amount,
70 | 'PartyA' => $PartyA,
71 | 'PartyB' => $BusinessShortCode,
72 | 'PhoneNumber' => $PartyA,
73 | 'CallBackURL' => $CallBackURL,
74 | 'AccountReference' => $AccountReference,
75 | 'TransactionDesc' => $TransactionDesc
76 | );
77 |
78 | $data_string = json_encode($curl_post_data);
79 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
80 | curl_setopt($curl, CURLOPT_POST, true);
81 | curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
82 | $curl_response = curl_exec($curl);
83 | print_r($curl_response);
84 |
85 | echo $curl_response;
86 | ?>
87 |
--------------------------------------------------------------------------------