nodejs 微信退款

基于nodejs 微信退款

说明

只是单纯的记录学习过程
官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4

准备

1.当然已经有了已支付的订单
2.退款需要双向证书,证书下载可见官网
微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全 。

那就开始吧

exports.miniRefund =   function (req,res) {
	 let refundData = req.body;//获取数据 在这里我获取的其实就是该订单支付的时候的信息,因为当时存起来了,大家根据自己逻辑添加数据
	 let appid = refundData.appid;//公众账号ID
	 let mch_id = refundData.mch_id//商户号
	 let nonce_str = refundData.nonce_str//这是随机字符串,为了方便我用的是该订单在支付的时候的随机字符串
	 let out_trade_no = refundData.out_trade_no;//支付的订单号
	 let out_refund_no = refundData.out_refund_no;//退款订单号
	 let total_fee= refundData.total_fee;//支付金额
	 let refund_fee = total_fee;//退款金额 因为我的逻辑是全额退款所以退款金额等于支付金额
	 let refund_desc = refundData.refund_desc;//退款原因
	 let sign = wechatUtil.refundSign(appid,mch_id,nonce_str,out_trade_no,out_refund_no,total_fee,refund_fee,refund_desc);//最重要的一步 签名 这是调用了我自己封装的一个方法,后面也会贴出来,关于签名大家可以到网上看一下就不说了
	 let    formData  = "<xml>";
		    formData  += "<appid>"+appid+"</appid>"; 
		    formData  += "<mch_id>"+mch_id+"</mch_id>";  
		    formData  += "<nonce_str>"+nonce_str+"</nonce_str>"; 
		    formData  += "<out_trade_no>"+out_trade_no+"</out_trade_no>";
		    formData  += "<out_refund_no>"+out_refund_no+"</out_refund_no>";
		    formData  += "<total_fee>"+total_fee+"</total_fee>";
		    formData  += "<refund_fee>"+refund_fee+"</refund_fee>";
		    formData  += "<refund_desc>"+refund_desc+"</refund_desc>";
		    formData  += "<sign>"+sign+"</sign>";
		    formData  += "</xml>";
	/*==================================================*/
	//接下来我们要用到一个request
	let request = require('request');//当然我们引用要写在最上面,但为了看的清楚点就一步一步走吧
	    request({
	    //请求地址
        url:'https://api.mch.weixin.qq.com/secapi/pay/refund',
        //还记得准备的证书吗这里就用到啦
        agentOptions: {
            cert: fs.readFileSync(path1.join(__dirname,'../../cert/apiclient_cert.pem')),
            key: fs.readFileSync(path1.join(__dirname,'../../cert/apiclient_key.pem' ))
        },
        method: 'POST',
        //携带这我们拼接好的参数
        body:formData
    }, function (err,body) {
    	//getXMLNodeValue:因为微信返回的结果是xml形式的所以封装了一个解析的方法,会面会贴出来
        let trade_state_desc = wechatUtil.getXMLNodeValue('return_code', body.body.toString('utf-8'));
        let return_msg = wechatUtil.getXMLNodeValue('return_msg', body.body.toString('utf-8'));
        let err_code_des = wechatUtil.getXMLNodeValue('err_code_des', body.body.toString('utf-8'));
		//为什么要加上这个参数err_code_des....我也很是无奈前两个参数只能正面是真的访问成功了,但是我试了一下 瞎写的订单号提交 
		//这两个参数还是正常的,但会多出 err_code_des这个参数,返回的是提示信息.所以前两个参数正确且没有这个参数的时候我才能知道 
		//提交的信息没有问题,所以就这样写了,但肯定不是很好,我会想想解决办法.      if(return_code=='SUCCESS'&&return_msg=='OK'&&err_code_des==undefined){
            log.info("退款成功")
            let data = {
                result:'1',
                msg:'已退款成功'

            };
            res.json(data)
        }else {
            let data = {
                result:'0',
                msg:err_code_des

            };
            res.json(data)
        }
    });
}

接下是加签的方法和解析xml的方法

//解析xml数据
exports.getXMLNodeValue = (node_name,xml)=>{
    log.info(xml);
        let tmp = xml.split("<"+node_name+">");
        if(tmp[1]!=undefined){
            let _tmp = tmp[1].split("</"+node_name+">");
            let tmp1 = _tmp[0].split('[');

            let _tmp1 = tmp1[2].split(']');
            return _tmp1[0];
        }
};
//退款签名
exports.refundSign=(appid,mch_id,nonce_str,out_trade_no,out_refund_no,total_fee,refund_fee,refund_desc)=>{
    let ret = {
        appid: appid,
        mch_id: mch_id,
        nonce_str:nonce_str,
        out_trade_no:out_trade_no,//注意左边参数名,
        out_refund_no:out_refund_no,
        total_fee:total_fee,
        refund_fee:refund_fee,
        refund_desc:refund_desc
    };
    log.info("查询签名验证的参数",ret);
    let string = raw(ret);
    let key = "密钥*************";
    string = string + '&key='+key;
    return crypto.createHash('md5').update(string,'utf8').digest('hex').toUpperCase();
};
//排序PS : key toLowerCase
function raw(args) {
    var keys = Object.keys(args);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (key) {
        newArgs[key.toLowerCase()] = args[key];
    });
    var string = '';
    for (var k in newArgs) {
        string += '&' + k + '=' + newArgs[k];
    }
    string = string.substr(1);
    console.log(string);
    return string;
};

Alt

结束

但还是有很多问题…可以看到商品详情是undefined,但我在文档中也没有找到商品详情的参数,
有点烦,希望尽快解决,当然我们还是少了一步,我们还应该通过查询退款来做验证,因为我还没弄,但感觉难度也不会很大,后面会补上

猜你喜欢

转载自blog.csdn.net/weixin_39907636/article/details/83655295