Nodejs后端实现微信支付退款操作

Nodejs后端实现微信支付退款操作

一、前言

之前写了nodejs后端接入微信支付和微信支付结果异步通知处理的文章,最近比较忙,没时间更新文章,今天有时间写一下nodejs后端实现微信支付退款的操作流程。

二、退款操作

首先贴上上微信官方对于退款操作也有相应的说明,【微信官方支付退款操作说明】。

退款是支付过程中较为常见的操作,同时也是十分敏感的操作,因为他是涉及到双方资金变动的操作,所以相较于支付操作,退款在安全这方面加了新的校验操作,也就是证书。

微信支付接口中,涉及资金回滚的接口会使用到API证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全 。

注意:这里的证书对不同的后端环境有不同的格式,具体参照官方说明,【证书说明

他这里只是单独列出了PHP环境,nodejs可以不用考虑,直接使用apiclient_cert.pem 和 apiclient_key.pem这两个证书文件就可以了。使用方式:在进行退款请求的时候,将证书文件放在请求头中就可以了。

微信支付的退款操作中重要的步骤就是证书的使用,其他操作像加密、签名等等和之前的文章一样,这里不做说明,有问题的可以去看我之前写的文章。

具体代码:

userRefund = (req: Request, res: Response) => {
        const orderCode = req.body.orderCode;	//商户订单号
        const money = req.body.money;		//订单金额
        const refundCode = req.body.orderId;		//商户退款单号,这个是自己定义的,我这里使用的是数据库中的订单_id值,保证是唯一的就可以了
        const refundMoney = req.body.refundMoney;		//退款金额

        const mchId = this.mchId;
        const nonceStr = this.wxpay.createNonceStr();
        const outTradeNo = orderCode;
        const totalFee = this.wxpay.getMoney(money);
        const refundfee = this.wxpay.getMoney(refundMoney);
        const sign = this.wxpay.refundSign(this.appId, mchId, nonceStr, outTradeNo, refundCode, totalFee, refundfee, this.mchKey);

        const formData = `
        <xml>
        <appid><![CDATA[${this.appId}]]></appid>
        <mch_id><![CDATA[${mchId}]]></mch_id>
        <nonce_str><![CDATA[${nonceStr}]]></nonce_str>
        <out_trade_no><![CDATA[${outTradeNo}]]></out_trade_no>
        <out_refund_no><![CDATA[${refundCode}]]></out_refund_no>
        <total_fee><![CDATA[${totalFee}]]></total_fee>
        <refund_fee><![CDATA[${refundfee}]]></refund_fee>
        <sign><![CDATA[${sign}]]></sign>
        </xml>
        `;

        const url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        const certPath = path.resolve("cert_wx");
        request({
            url,
            agentOptions: {
                cert: fs.readFileSync(path.join(certPath, "apiclient_cert.pem")),
                key: fs.readFileSync(path.join(certPath, "apiclient_key.pem"))
            },
            method: "POST",
            body: formData
        }, (err, response, body) => {
            if (!err && response.statusCode == 200) {
                xmlreader.read(body.toString("utf-8"), (error, response) => {
                    if (null !== error) {
                        return;
                    }
                    console.log(response.xml);
                });
            }
        });
    }

三、结语

退款操作这里就结束了,写的比较简单,可以根据自己的需求进行扩展,将退款结果进行保存、发送通知等等。对于退款,最重要的还是安全验证,退款金额的验证,目标金额和传递的金额参数是否一致等等,这些都是需要考虑的,暂时就写这么多,以后有时间了再继续更新吧。希望各位多多关注,感谢支持。

扫描二维码关注公众号,回复: 14653232 查看本文章

猜你喜欢

转载自blog.csdn.net/m0_37857819/article/details/107126602