如何使用Node.js整合B2C M-Pesa API

214 阅读4分钟

如何使用Node.js整合B2C M-Pesa API

M-Pesa可以被描述为一种基于电话的移动银行服务。自2007年由沃达丰集团(Vodafone Group PLC)和Safaricom在肯尼亚启动以来,它已经扩展到非洲的另外八个国家。

API(应用编程接口)是两个软件应用程序之间的中介,使它们能够进行通信。

B2C(企业对消费者)M-Pesa API使软件开发商或商户能够向其客户发送付款。

目标

在这篇文章中,我们将在Node.js RESTful API中整合B2C M-Pesa API。我们将使用Swagger来消费该API。

前提条件

要跟上本文的进度,最好能有以下条件。

  • 在你的电脑上安装Node.js
  • 一些关于JavaScript的基本知识。
  • 安装了一个文本编辑器。最好是VScode

设置开发服务器

本文假设你有一个Safaricom开发者账户。

此外,请确保你已经从你的开发者门户网站上创建了至少一个应用程序。

为了开始工作,我们在骨架上完成所有的基本配置后,我们在文章中的重点将是实现核心功能。

我们首先需要安装以下依赖项。

  • [axios]:用于处理对M-Pesa API的请求。
  • [dotenv]:用于加载环境变量。
  • [express]:为建立RESTful API提供更快、更简单的方法。
  • [ngrok]:用于暴露我们的本地服务器。
  • [swagger-ui-express]:用于将API文档提供给用户界面。

要安装这些包,在你的文本编辑器中打开启动项目。接下来,在你的文本编辑器中启动终端并运行以下命令。

npm install

在安装了依赖关系后,我们可以进入下一个步骤。

请注意,我们将从src/controllers/Mpesa.js 文件开始工作。

获取访问令牌

所有对M-Pesa API的请求必须有一个访问令牌。它构成了认证的基础。

为了实现这一功能,我们将编辑getAccessToken() 方法,如下所示。

//get access token.
async getAccessToken(req,res,next){
    // get data from headers by destructuring
    let {consumerkey,consumersecret} = req.headers;
    // request url
    let url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials";

    // get a base64 encoded string from a buffer
    let buf = new Buffer.from(`${consumerkey}:${consumersecret}`).toString("base64");
    // authentication string
    let auth = `Basic ${buf}`;
    let response;

    try {

        // send a GET request to the URL
        response = await axios.default.get(url,{
            headers:{
                "Authorization":auth
            }
        });

    } catch (error) {

        // in case of an error, get the code and error message
        let err_code = error.response.status;
        let err_msg = error.response.statusText;

        // send response to client
        return res.status(err_code).send({
            message:err_msg
        });

    }

    // get the access token from server response
    let accessToken  = response.data.access_token;

    // set the status code.
    res.status(200);

    // send the access token to client
    return res.send({
        accessToken
    });
};

在上面的代码片断中,我们正在。

  • headers 解构consumerkeyconsumersecret
  • 设置URL 来发送请求。
  • 从一个缓冲区生成一个base64 编码的字符串。
  • 通过在编码字符串前添加Basic 来组成认证字符串。
  • 从一个try/catch 块向M-Pesa API发送请求。如果出现错误,错误将被发送到客户端。否则,如果没有错误,访问令牌将被发送到客户端。

要测试它。

  • 通过在你的文本编辑器的终端运行以下命令来启动开发服务器。
npm run dev
  • 在你的浏览器中,导航到http://localhost:4000/api-docs
  • 点击Mpesa B2C 标签下的/access-token 部分。
  • 点击Try it out 按钮。
  • 要获得你的consumer keyconsumer secret ,访问你的[应用程序页面],选择你的应用程序,从keys 部分,然后将它们分别复制并粘贴到该部分的参数。
  • 点击Execute 按钮。
  • 如果出现错误,请重新审视这些步骤。否则,你的服务器响应应该类似于以下内容。

access_token_response_screenshot

获取访问令牌服务器响应的截图。

B2C API

我们可以使用访问令牌来访问B2C API。

要做到这一点,我们需要修改b2c() 方法,如下所示。

//b2c.
async b2c(req,res,next){
// destructure from headers
let {accesstoken,initiatorname,securitycredential,commandid,amount,partya,partyb,remarks}= req.headers;
// url to send request to.
let url = "https://sandbox.safaricom.co.ke/mpesa/b2c/v1/paymentrequest";
// url to expose our local server
let ngrok_url = process.env.NGROK_URL;
// authentication string
let auth = `Bearer ${accesstoken}`;
let response;

try{

    // send the request
    response = await axios.default.post(url,{
    "InitiatorName": initiatorname,
    "SecurityCredential":securitycredential,
    "CommandID": commandid,
    "Amount": amount,
    "PartyA": partya,
    "PartyB": partyb,
    "Remarks": remarks,
    "QueueTimeOutURL": `${ngrok_url}/timeout`,
    "ResultURL": `${ngrok_url}/cb`,
    "Occasion": remarks
    },{
        headers:{
            "Authorization":auth
        }
    })

}catch(error) {

    // in case of an error, get the code and the message.
    let err_code = error.response.status;
    let err_msg = error.response.data.errorMessage;

    // send to the client
    return res.status(err_code).send({
        message:err_msg
    });
}

// set the status code
res.status(200);

// send to the client
return res.send({
    result:response.data
});
};

在上面的代码片段中,我们正在。

  • 对从headers 发送的数据进行解构。

  • 设置要发送请求的URL。

  • 设置ngrok URL 。要得到它,请确保你已经安装了ngrok。然后在你的文本编辑器的终端打开另一个标签,运行npm run ngrok 命令。然后,复制终端中记录的HTTPS URL ,并将其适当地粘贴到你项目文件夹根部的.env 文件中。

  • 通过在访问令牌前附加Bearer ,设置认证令牌。

  • 从一个try/catch 块中发送请求。如果出现错误,我们将获得状态代码和错误信息,并将其发送给客户端。如果没有错误,我们将状态代码设置为200 ,并将请求的响应发送到客户端。

为了测试它。

  • 我们首先需要实现timeout URL和result URL。要做到这一点,我们将编辑timeout()cb() 方法,如下所示。
//time-out.
async timeOut(req,res,next){
    console.log("--- request timeout ----");
    console.dir(req.body);
    console.log("--- end of request timeout ---");
};

//callback.
async cb(req,res,next){
    console.log("--- callback request ----");
    let response = req.body.Result;

    if(response.ResultParameters) {
        response.ResultParameters = response.ResultParameters.ResultParameter;
    }

    if(response.ReferenceData) {
        response.ReferenceData = response.ReferenceData.ReferenceItem;
    };

    console.log(response)
    console.log("--- end of callback request ---");
};
  • 确保你的开发服务器正在运行。
  • 在你的浏览器中,导航到http://localhost:4000/api-docs 页面,然后进入/b2c 部分。
  • 点击Try it out 按钮。
  • 按以下方式填写参数。
    • 对于AccessToken, 重复前面的过程,复制并粘贴生成的访问令牌。
    • 对于InitiatorName, 从你的测试证书页面复制并粘贴Initiator Name
    • 对于SecurityCredential, 从测试凭证页面复制Security Credential 并粘贴到下面的Initiator Security Password 输入中,然后点击Generate Credentials 。复制并粘贴生成的长文本。
    • 对于CommandID ,从下拉菜单中选择任何。
    • 对于Amount ,输入任何金额。
    • 对于PartyA ,复制并粘贴测试证书页面上的Shortcode 1
    • 对于PartyB ,复制并粘贴测试证书页面上的Test MSISDN
    • 对于Remarks, 输入任何文本。保持简短。
  • 点击Execute 按钮。
  • 如果出现任何错误,请重新审视上述步骤。否则,下面的输出应该类似于你的服务器响应。

b2c_server_response_screenshot

b2c服务器响应的屏幕截图。

在你的控制台中记录的信息应该模仿以下内容。

b2c_console_response_screenshot

一个b2c控制台响应的屏幕截图

结论

在当今竞争激烈的商业环境中,业务流程应该是自动化的,以降低成本。M-Pesa B2C API提供了一个基础设施,以实现从商户到客户的自动化支付。