### [关于node.js实现微信支付退款的功能](https://www.prosaas.cn/article/17315) **Published:** 2018-06-27T02:11:45 **Author:** 5201314 **Excerpt:** 这篇文章主要介绍了node.js实现微信支付退款功能,在微信开发中有有付款就会有退款,这样的功能非常常见,需要… 这篇文章主要介绍了node.js实现微信支付退款功能,在微信开发中有有付款就会有退款,这样的功能非常常见,需要的朋友可以参考下 **缘起** 有付款就会有退款 注意,退款支持部分退款 左口袋的钱退到右口袋罗 ![](https://img.php.cn/upload/article/000/000/009/3600e9c76cb748b2a4e422882b4bf55b-0.jpg)  这次发起的退款请求0.01元是实时到账的,因此,用户在小程序端发起的退款只是一个请求到后台,后台审核人员审核无误后才后微信发起退款操作。 **引入第三方module** 在package.json 中加入"weixin-pay": "^1.1.7"这一条 **代码目录结构**  ![](https://img.php.cn/upload/article/000/000/009/3cc59804bdb05786ca30da4486569a14-1.png) **入参** { transaction\_id: '4200000005201712165508745023', // 交易 out\_trade\_no: '5b97cba0ae164bd58dfe9e77891d3aaf', // 自己这头的交易号 out\_refund\_no: '6f3240c353934105be34eb9f2d364cec', // 退款订单,自己生成 total\_fee: 1, // 退款总额 nonce\_str: '1xSZW0op0KcdKoMYxnyxhEuF1fAQefhU', // 随机串 appid: 'wxff154ce14ad59a55', // 小程序 appid mch\_id: '1447716902', // 微信支付商户id sign: '416FCB62F9B8F03C82E83052CC77524B' // 签名,weixin-pay这个module帮助生成 } 然后由wxpay为我们生成其余字段,比如nonce\_str,sign,当然还少不了p12证书, 这个早选在wxpay初始代码里已经配置了,pfx: fs.readFileSync(\_\_dirname + '/../../../cert/apiclient\_cert.p12'), //微信商户平台证书 **lib/wechat/utils/wxpay.js的源码** const WXPay = require('weixin-pay'); // 引入weixin-pay这个第三方模块 const {weapp} = require('../../../utils/config'); // 我自己的全局配置文件,包括了appid key 等 const fs = require('fs'); const wxpay = WXPay({ appid: weapp.APPID, mch\_id: weapp.MCHID, partner\_key: weapp.KEY, //微信商户平台 API secret,非小程序 secret pfx: fs.readFileSync(\_\_dirname + '/../../../cert/apiclient\_cert.p12'), }); module.exports = wxpay; **另外还有一个util.js工具类** 用于验证与错误回调 const wxpay = require('./wxpay'); const validateSign = results => { const sign = wxpay.sign(results); if (sign !== results.sign) { const error = new Error('微信返回参数签名结果不正确'); error.code = 'INVALID\_RESULT\_SIGN'; throw error; }; return results; }; const handleError = results => { if (results.return\_code === 'FAIL') { throw new Error(results.return\_msg); } if (results.result\_code !== 'SUCCESS') { const error = new Error(results.err\_code\_des); error.code = results.err\_code; throw error; } return results; }; module.exports = { validateSign, handleError, }; **发起退款请求** 退款逻辑是这样的,先从自己这边的Order数据表中查出transaction\_id/out\_trade\_no/total\_fee,再拼上自己生成的out\_refund\_no退款单号,本次退款部分金额refund\_fee,最后由weixin-pay这个模块下的wxpay.refund调起就可以了,成功就把订单状态改成"退款成功" // 退款 router.post('/refund', function(req, res) { Order.findById(req.body.\_id, (err, order) => { if (err) { console.log(err); } console.log(order); // 生成微信设定的订单格式 var data = { transaction\_id: order.transactionId, out\_trade\_no: order.tradeId, out\_refund\_no: uuid().replace(/-/g, ''), total\_fee: order.amount, refund\_fee: order.amount }; console.log(data); // 先查询订单,再退订单 wxpay.refund(data, (err, result) => { if (err) { console.log(err); res.send( utils.json({ code: 500, msg: '退款失败' }) ); } // 返回退款请求成功后,要将订单状态改成REFUNDED if (result.result\_code === 'SUCCESS') { console.log(result); order.status = 'REFUNDED'; order.save((err, response) => { res.send( utils.json({ msg: '退款成功' }) ); }); } else { res.send( utils.json({ code: 500, msg: result.err\_code\_des }) ); } }); }); }); **入参的坑** 1.这次遇到的坑是refund\_fee忘记传值,也就是说微信退款是支持部分退款的,如果是全额退款,那么将它赋值为total\_fee相同 2.网上说的op\_user\_id: weapp.MCHID这个参数是非必选的 3.transaction\_id 与 out\_trade\_no 二选一即可,这样在没有记录transaction\_id的情况(比如没有写支付成功的callback)下,也能发起退款;其中优先级前者大于后者,在我在分别前其一故意给错的过程中得到了验证。 4.报了一个appid与商户号不匹配的报错,return\_code: 'FAIL', return\_msg: '商户号mch\_id与appid不匹配'原来是小程序还没绑定公众号微信支付,这真是一个乌龙。 **成功退款微信返回的数据** appid:"wxff154ce14ad59a55" cash\_fee:"1" cash\_refund\_fee:"1" coupon\_refund\_count:"0" coupon\_refund\_fee:"0" mch\_id:"1447716902" nonce\_str:"c44wOvB6a4bQJfRk" out\_refund\_no:"9ace1466432a4d548065dc8df95d904a" out\_trade\_no:"5b97cba0ae164bd58dfe9e77891d3aaf" refund\_channel:"" refund\_fee:"1" refund\_id:"50000705182017121702756172970" result\_code:"SUCCESS" return\_code:"SUCCESS" return\_msg:"OK" sign:"5C2E67B3250054E8A665BF1AE2E9BDA3" total\_fee:"1" transaction\_id:”4200000005201712165508745023” **重复退款将返回如下** appid:"wxff154ce14ad59a55" err\_code:"ERROR" err\_code\_des:"订单已全额退款" mch\_id:"1447716902" nonce\_str:"KP1YWlU7a5viZEgK" result\_code:"FAIL" return\_code:"SUCCESS" return\_msg:"OK" sign:”C2A7DED787BEA644C325E37D96E9F41C” ![](https://img.php.cn/upload/article/000/000/009/3cc59804bdb05786ca30da4486569a14-2.png)  **最后** 如果没有写退款功能或者不想写退款功能怎么办,其实可以从微信支付的后台pay.weixin.qq.com,也是能退款出去的,只是不想忘记了要人工将订单状态置为退款状态。 以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网! 相关推荐: 如何利用JS实现仿微信支付弹窗功能 在微信小程序中如何实现自定义toast 以上就是关于node.js实现微信支付退款的功能的详细内容,更多请关注知企PROSAAS其它相关文章! **Categories:** 后端开发 ---