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