前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs接收微信支付通知结果

nodejs接收微信支付通知结果

作者头像
OECOM
发布2020-07-01 16:53:13
1.4K0
发布2020-07-01 16:53:13
举报
文章被收录于专栏:OECOMOECOMOECOM

2019-09-22 10:38:13

在统一下单中讲到了微信支付的统一下单,统一下单完成后就是客户端的事情了,根据返回的信息来调起微信支付,完成付款。当付款完成后,微信服务器会post支付结果通知我们,此接口需要单独来写,并且需要按照微信文档的要求来返回数据。

接收通知一般会进行如下步骤:

  • 接收post传输的xml格式数据
  • 解析xml,转为json
  • 签名验证
  • 返回结果通知微信服务器接收成功

接收post传输的xml格式数据

接收xml格式的数据和接收json的方式是不一样的,下面我们来看一下该如何接收微信支付通知结果的xml格式数据,我们还是将它写在pay.js文件中:

/**
 * 解析通过post传递过来的xml信息
 * @param req
 * @returns {Promise<any>}
 */
exports.parseReqXmlData = (req)=>{
    let notionData = "";
    req.setEncoding('utf8');
    req.on('data', (chunk)=>{
        notionData += chunk;
    });
    return new Promise((resolve,reject)=>{
        req.on("end",()=>{
            resolve(notionData)
        });
        req.on("error",(e)=>{
            reject(e)
        })
    })


};

我们不能用之前的req.body或req.query来进行接收了,要通过监听data来获取数据,上面我们将其封装成了promise的方式来进行返回数据。

签名验证

接收到数据之后要做的就是解析,解析方法在统一下单中已经写过了,在这不在赘述,解析完成之后需要进行验签操作,以防恶意调用此接口进行支付结果的伪造,验签和签名的步骤差不多,就是对比一下传递过来的参数和签名是否一致,下面我们来看一下具体的实现方法

/**
 * 校验返回结果签名是否正确
 * @param obj 待校验对象
 * @param key  商户平台设置的密钥key
 * @returns {boolean} 返回结果 true为正确,false为不正确
 */
exports.checkPayResultSign = (obj,key)=>{
    try{
        let tempObj = Object.assign({},obj);
        let resultSign = tempObj.sign;
        delete tempObj.sign;
        tempObj = exports.getWechatSign(tempObj,key);
        if(tempObj){
            return resultSign == tempObj.sign
        }else{
            console.log("checkPayResultSign:签名校验异常");
            return false;
        }
    }catch(e){
        console.log(e);
        return  false
    }
};

如上方法就是进行签名校验,其实就是将传递过来的参数保存起来,然后在对参数进行签名,两次对比是否一致,签名方法在统一下单中已经写过了,需要的小伙伴可以看一下。

返回结果通知微信服务器接收成功

验签成功后要做的就是构造xml格式数据,通知微信服务器我们接收成功了。

/**
 * 微信支付成功后,微信服务器主动回调方法,
 */
router.post("/payNotice",async (req,res)=>{
try{
    let key="sdkfnowemcoiwem4"//这里我将key写死在这里了,正常是需要从数据库或配置文件中读取
    let xmlPost = await exports.parseReqXmlData(req)//解析获取xml
    let formatNotion = await exports.parseXml(xmlPost);//将xml格式解析为json格式

    let result= "";
    if(formatNotion.return_code === "SUCCESS"){
        console.log(formatNotion);

        let checkPayResultSign = exports.checkPayResultSign(formatNotion,key);
        console.log("支付返回信息签名校验:"+checkPayResultSign);
        if(checkPayResultSign){
            result = `<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`;
        }else{
            result = `<xml><return_code><![CDATA[FALSE]]></return_code><return_msg><![CDATA[FALSE]]></return_msg></xml>`;
        }
    }else{
        result = `<xml><return_code><![CDATA[FALSE]]></return_code><return_msg><![CDATA[FALSE]]></return_msg></xml>`;
    }
    res.writeHead(200, {'Content-Type': 'text/xml'});
    res.end(result)

}catch(e){
    console.log("回调通知异常:"+JSON.stringify(e));
    res.json({
        success:false
    });
}

catch里面我返回的是json格式,这个其实是为非正常调用返回的,正常微信调用是不会走catch的,所以不用过多考虑它,返回xml格式需要设置header,将Content-Type设置为text/xml,以告诉对方我们发送的是xml格式的数据。

至此如何接收微信支付通知结果就介绍完了,后续会继续介绍订单查询等后续接口

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接收post传输的xml格式数据
  • 签名验证
  • 返回结果通知微信服务器接收成功
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档