levizwannah / mpesa-sdk-php
PHP的独立Mpesa SDK。此包为PHP应用程序提供Safaricom Mpesa API的简洁实现。
README
一个用于与Safaricom Daraja API交互的简洁、优雅和独立 PHP SDK。该SDK纯粹面向对象,易于理解和使用。它没有依赖关系,因此可以用于任何PHP项目:普通或基于框架的项目。
需求
- PHP版本 >= 7.4
- 您已阅读Daraja API的文档:此SDK主要为您抽象了一切,使集成M-Pesa变得容易。因此,请确保您已查看Daraja文档。不需要理解它,只需知道正在发送和接收哪些数据即可。这有助于您理解此SDK。
使用Composer获取
composer require levizwannah/mpesa-sdk-php
然后开始使用。
不使用composer
下载代码的zip版本。包括位于下载的src
文件夹中的self-autoload.php
文件。
文档
设置
首先创建一个具有必要配置的Mpesa对象。
消费者密钥、消费者密钥和业务简码始终是必需的。
如果您使用的是收银机号,则需要till
密钥,否则只需要业务简码。
注意:业务简码与Paybill号码相同。对于收银机号码,则不同。
require('path/to/vendor/autoload.php'); use LeviZwannah\MpesaSdk\Mpesa; $config = [ "key" => "consumer-key", // consumer key "secret" => "consumer-secret", // consumer secret "code" => "12345", // business short code "till" => "67891", // optional till number "passkey" => "xxxx", // optional passkey "initiator" => "levizwannah", // optional initiator name "credential" => "levi-cred++==" // optional security credential ] $mpesa = Mpesa::new()->configure($config);
方法链与configure($configure)
$config
数组中的每个键都是对象的setter方法。例如,以下代码与上面的代码等价。
require('path/to/vendor/autoload.php'); use LeviZwannah\MpesaSdk\Mpesa; $mpesa = Mpesa::new(); $mpesa->key("consumer-key") ->secret("consumer-secret") ->code(12345) ->till(67891) // optional ->passkey('stk-passkey') // optional ->initiator("levizwannah") // optional ->credential("levi-cred++=="); // optional
每个用于与特定API交互的对象都扩展了父Mpesa对象。因此,相同的规则也适用于它们。您可以使用配置数组和使用configure方法或仅使用单个setter方法。
警告:不要直接从子类创建对象,始终使用mpesa对象来获取子对象,您将在文档的后面看到。
环境
您可以在$config
数组中使用'env'
键或使用env("env")
方法来设置环境。环境值可以是live
或sandbox
。默认情况下,环境是"live"
。有一个Constant
类可以帮助您避免写入字面字符串。
//...other code use LeviZwannah\MpesaSdk\Helpers\Constant; $mpesa->configure([ 'env' => Constant::SANDBOX, // or 'env' => Constant::LIVE, // default value ]); // or $mpesa->env(Constant::SANDBOX); $mpesa->env(Constant::LIVE); // default value
记住:以下使用的每个setter方法都可以用作
$config
数组中的键,并使用configure($config)
方法设置。
电话号码
SDK将254添加到电话号码。以下格式受支持
0746987654
+254746987654
+2540746987654
254746987654
746987654
异常
在请求期间,如果缺少必要的数据,SDK将抛出异常。例如,在发出Reversal请求之前,需要发起人名称和安全凭证。如果没有找到它们,将抛出一个带有语义信息的异常,告知您问题所在。
处理响应
SDK提供了一种统一的方法来检查Mpesa的即时响应。在与SDK交互的任何API中使用以下代码片段。
//... request made if($client->accepted()) { // ... mpesa accepted the request for processing // This means the ResponseCode == 0 $response = $client->response(); } else { // The response code is not == 0 or there is an error. $error = $client->error(); // get an error object echo "error: $error->code, $error->message"; } // you can always get the latest response using $response = $client->response(); // returns an object $conversationId = $response->ConversationID; $responseCode = $response->ResponseCode; // ...
注意:响应对象中的数据与Daraja文档中的数据相同。没有进行额外的格式化。
处理回调时的安全性
SDK有两个静态辅助方法,可帮助您在回调中处理mpesa响应。
verifyOrigin(): bool
:如果回调响应来自Mpesa,则返回true
,否则返回false
。data($asArray = false): object|array
:从mpesa获取回调数据,并根据其参数将其作为对象或数组返回。
require('path/to/vendor/autoload.php'); use LeviZwannah\MpesaSdk\Mpesa; $isFromMpesa = Mpesa::verifyOrigin(); $result = Mpesa::data(); //...
处理回调负载
注意:
Response
表示您在发起请求时从 Mpesa 获得的内容。Result
是发送到您的回调 URL 的负载。
负载格式
请参阅 Daraja 文档(https://developer.safaricom.co.ke),以了解预期的负载。为了向前兼容,SDK 不会修改 Mpesa 的响应或负载。
令人困惑的部分
在每一个 Response
中,都会存在独特的键。例如,STK 推送响应中的 MerchantRequestID
和 CheckoutRequestID
,以及其他 API 响应中的 OriginatorConversationID
和 ConversationID
。这些键用于标识 Mpesa 上的交易。请将这些键保存在您的数据库或存储中,与待处理的交易一起。
在发送到您的回调的 Result
负载中,这些键将存在。因此,您可以使用它们来更新存储或数据库中相应的交易。
Mpesa Express (STK Push) API
用于发起 STK Push 请求。
要求
确保这些值在设置部分中已设置。
- 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
) - 收银机号 (
till
) 对于收银机号 - 密码 (
passkey
)
用法
//..setup... $stk = $mpesa->stk(); // for till numbers // ensure that the till number is set during setup // or set it up using $stk->till(123455) $stk->phone('0724786543') ->amount(1) ->buygoods() // for till numbers ->paybill() // for paybill numbers ->callback('https://my-domain.com/path/to/callback') ->description('optional description') // optional ->push(); // check if the request was accepted by mpesa. if(!$stk->accepted()) { $error = $stk->error(); echo "error: $error->code, $error->message"; // exit... } // accepted for processing $response = $stk->response(); // returns an object $merchantRequestId = $response->MerchantRequestID; $checkoutRequestId = $response->checkoutRequestID; //...
请注意,使用收银机号和付款单号之间的区别在于在调用 push()
方法之前使用 paybill()
和 buygoods()
方法。同时,在使用收银机号时,请确保已设置 till
值。
Mpesa Express STK 查询
用于查询 STK 推送请求的状态。这与正常的交易状态查询不同。
要求
确保这些值在设置部分中已设置。
- 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
) - 密码 (
passkey
) - 收银机 (
till
) 用于收银机账户
用法
请参阅下面的代码片段
//...setup... $query = $mpesa->stk()->query(); $query->checkoutId('checkout-request-id') ->paybill() // for paybill number ->buygoods() // for till numbers ->make(); // check if it's not accepted if(!$query->accepted()){ $error = $query->error(); echo "$error->code $error->message"; // exit; } $response = $query->response(); $resultCode = $response->ResultCode; $merchantId = $response->MerchantRequestID; // ...
注意:如果您正在查询为付款单号发起的 STK 请求,请使用
paybill()
,否则请使用buygoods()
。默认情况下,它查询为付款单号发起的 STK 请求。
C2B URLs 注册 API
允许您注册您的 C2B URLs。SDK 还为您提供了易于使用的确认和验证脚本响应方法。
不需要
validation url
,除非您明确要求 Mpesa 团队为您启用它。
要求
确保这些值在设置部分中已设置。
- 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
注册
请参阅下面的代码片段。
// ...setup... // c2b url registration $urls = $mpesa->urls(); $urls->confirmation('https://my.url/path/to/confirmation') ->validation('https://my.url/path/to/validation') // optional ->register(); if(!$urls->accepted()) { $error = $urls->error(); echo "Error: $error->code - $error->message"; // exit; }
回调助手
当 Mpesa 将负载发送到您的确认或验证 URL 时,您需要发送格式化的确认或拒绝负载。您可以使用 SDK 的静态方法来完成此操作。请参阅以下内容。
require('path/to/vendor/autoload.php'); use LeviZwannah\MpesaSdk\Mpesa; # confirmation.url // your code ... Mpesa::confirm(); // echos the formatted response // your code... // send SMS ... etc #================# # validation.url // your code ... if(!true) { Mpesa::deny(); } else { Mpesa::confirm(); } // your code ...
注意:您只能在验证处理程序中使用
Mpesa::deny()
。
反向 API
允许您进行 Mpesa 交易的撤销。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
请参阅如何使用此 SDK 的代码片段。
// ...setup... $reversal = $mpesa->reversal(); $reversal->timeoutUrl('https://my.url/path/to/reversal/timeout') ->resultUrl('https://my.url/path/to/reversal/result') ->transId('1X1Y1ZNME') // transaction ID to reverse ->amount(100) // amount paid ->remarks('optional remarks') // optional ->occasion('optional occasion') // optional ->make(); if(!$reversal->accepted()) { $error = $reversal->error(); echo "$error->code - $error->message"; // exit; } // reversal initiated $response = $reversal->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //...
在您的回调脚本中,请确保遵循此文档 安全部分 中的建议。
交易查询 API
交易查询 API 允许您检查发送到或从您的业务简码进行的交易的状态。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
请参阅以下如何使用此 SDK 的代码片段。
// Transaction query $query = $mpesa->query(); $query->transId('1X1Y1ZNME') ->resultUrl('https://my.url/path/to/timeout') ->timeoutUrl('https://my.url/path/to/result') ->remarks('optional remarks') // optional ->occasion('optional occasion') // optional ->make(); if(!$query->accepted()) { $error = $query->error(); echo "$error->code - $error->message"; // exit; } $response = $query->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //...
余额查询 API
余额查询 API 允许您查询业务账户中的余额。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
请参阅代码片段
//...setup... $balance = $mpesa->balance(); $balance->timeoutUrl('https://my.url/path/to/timeout') ->resultUrl('https://my.url/path/to/result') ->remarks('optional remarks') // optional ->check(); if(!$balance->accepted()){ $error = $balance->error(); echo "$error->code $error->message"; // exit; } $response = $balance->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //...
B2B API
B2B API 允许您从您的业务简码向付款单或收银机号进行付款。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
请参阅下面的代码片段
// ...setup... $b2b = $mpesa->b2b(); $b2b->amount(100) ->receiver('123456') // business you are paying to ->resultUrl('https://my.url/path/to/result') ->timeoutUrl('https://my.url/path/to/timeout'); # if receiver is a paybill number $b2b->paybill() ->account('account-number'); # if receiver is a till number $b2b->buygoods(); # optional $b2b->remarks('optional remarks') ->occasion('optional occasion') ->requester('0712345678'); // the customer on // whose behalf the money is // being paid. # make payment $b2b->pay(); if(!$b2b->accepted()) { $error = $b2b->error(); echo "$error->code $error->message"; // exit; } $response = $b2b->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //... //... save to db, etc
B2C API
B2C API 允许您从您的业务简码向手机号码进行付款。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
请参阅下面的代码片段
$b2c = $mpesa->b2c(); $b2c->amount(100) ->phone('0712345678') ->resultUrl('https://my.url/path/to/result') ->timeoutUrl('https://my.url/path/to/timeout'); # set payment purpose $b2c->salary() // for salary payment ->promotion() // for promotion payment ->payment(); // for business payment # optional $b2c->remarks('optional-remarks') ->occasion('optional-occasion'); # pay $b2c->pay(); if(!$b2c->accepted()) { $error = $b2c->error(); echo "$error->code $error->message"; // exit; } $response = $b2c->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //... //... save to db, etc
税务汇款 API
税务汇款 API 允许您向 KRA 进行税务付款。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
请参阅下面的代码片段
// ...setup... $remit = $mpesa->remitTax(); $remit->amount(1000) ->resultUrl('https://my.url/path/to/result') ->timeoutUrl('https://my.url/path/to/timeout') ->remarks('optional-remarks') // optional ->pay(); if(!$remit->accepted()) { $error = $remit->error(); echo "$error->code $error->message"; // exit; } $response = $remit->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //... //... save to db, etc
动态二维码 API
启用您为不同交易生成二维码。请参阅Daraja文档
使用此API生成动态二维码,允许拥有My Safaricom App或M-PESA应用的安全集团M-PESA客户扫描和捕获账单号码和金额,然后授权在选定的LIPA NA M-PESA (LNM)商户网点支付商品和服务。
-- Daraja
要求
确保这些值在设置部分中已设置。
- 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码(
code
)
用法
请参阅以下代码片段
//...setup... $qr = $mpesa->qr(); $qr->size(300) // QR Code size (300x300) ->merchantName('Business Name') ->reference('account-number') // transaction reference ->amount(100); # the receiver of the payment # can be Till Number, Agent number, phone number # paybill number, or business number # Correspond to CPI in the Daraja doc $qr->receiver('123457'); # sets the receiver type # corresponds to TrxCode in the Daraja Doc $qr->buygoods(); // receiver is a till number $qr->paybill(); // receiver is a paybill number $qr->sendMoney(); // receiver is a phone number $qr->withdraw(); // receiver is an agent number $qr->sendToBusiness(); // receiver is a business number # generate code $qr->generate(); if(!$qr->accepted()) { $error = $qr->error(); echo "$error->code $error->message"; // exit; } $response = $qr->response(); $qrCode = $response->QRCode; $requestId = $response->RequestID; //...
业务到批量API
此API允许您将资金从活动账户直接加载到用于B2C支付的公用事业账户。
要求
确保这些值在设置部分中已设置。
- 发起人名称 (
initiator
) - 安全凭证 (
credential
) - 消费者密钥 (
key
) - 消费者密钥 (
secret
) - 业务简码 (
code
)
用法
// ...setup... $btb = $mpesa->btb(); $btb->amount(100) ->receiver('123456') // short code of the receiver ->resultUrl('https://my.url/path/to/result') ->timeoutUrl('https://my.url/path/to/timeout'); # if in the same organization use $btb->amount(100) ->toSelf() // accepts an optional short code param for sub-organizations ->resultUrl('https://my.url/path/to/result') ->timeoutUrl('https://my.url/path/to/timeout'); # optional $btb->remarks('optional remarks') // optional ->requester('0712345678'); // optional - the customer on // whose behalf the transfer is // being made. # make the transfer $btb->transfer(); if(!$btb->accepted()) { $error = $btb->error(); echo "$error->code $error->message"; // exit; } $response = $btb->response(); $originatorId = $response->OriginatorConversationID; $conversationId = $response->ConversationID; //... //... save to db, etc
快速笔记
如果您对处理回调中的结果感到困惑,请参阅此README文件的早期部分。
报告错误
如果在代码中发现错误,请打开一个问题。
表达喜爱
- 收藏此仓库
- 如果您喜欢它,请为我买杯咖啡。