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);
                });
            }
        });
    }

三、结语

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

实现微信支付需要以下步骤: 1.注册微信商户号并开通支付功能。 2.在微信商户平台创建支付密钥。 3.在后端使用 Node.js 和 Express 框架,引入微信支付 SDK。 4.在前端页面中显示需要支付的金额和商品信息,并将信息通过 POST 请求发送给后端。 5.后端接收到请求后,调用微信支付 SDK 的 API,生成支付订单。 6.将生成的支付订单信息返回给前端,前端调用微信支付 SDK 的 API,发起支付请求。 7.用户在微信客户端确认支付后,后端会收到微信支付成功的回调通知。 下面是实现微信支付的基本代码示例: 1.引入微信支付 SDK ``` const tenpay = require('tenpay'); const config = { appid: '微信公众号/小程序appid', mchid: '微信商户号', partnerKey: '微信支付密钥', pfx: fs.readFileSync('证书文件路径') }; const api = new tenpay(config); ``` 2.生成支付订单 ``` const order = { out_trade_no: '商户订单号', body: '商品描述', total_fee: '支付金额,单位为分', spbill_create_ip: '客户端IP地址', notify_url: '支付成功后的回调通知地址', trade_type: 'JSAPI/NATIVE/APP', openid: '用户openid(JSAPI支付必须)' }; const result = await api.getPayParams(order); ``` 3.发起支付请求 ``` const payParams = await api.getPayParams(order); const prepay_id = payParams.package.split('=')[1]; const paySign = await api.getPaySign({ prepay_id }); const paymentParams = { timeStamp: paySign.timeStamp, nonceStr: paySign.nonceStr, package: paySign.package, signType: 'MD5', paySign: paySign.sign }; res.send(paymentParams); ``` 4.处理支付回调通知 ``` router.post('/notify', async (req, res) => { const data = await tenpay.middleware(req, res); if(data.return_code === 'SUCCESS' && data.result_code === 'SUCCESS') { // 处理支付成功逻辑 res.success(); } else { // 处理支付失败逻辑 res.fail(); } }); ``` 以上是基本的微信支付代码示例,具体实现还需要根据实际业务场景做出相应的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值