基于node.js实现微信支付退款功能


Posted in Javascript onDecember 19, 2017

缘起

有付款就会有退款

注意,退款支持部分退款

左口袋的钱退到右口袋罗

基于node.js实现微信支付退款功能 

这次发起的退款请求0.01元是实时到账的,因此,用户在小程序端发起的退款只是一个请求到后台,后台审核人员审核无误后才后微信发起退款操作。

引入第三方module

在package.json 中加入"weixin-pay": "^1.1.7"这一条

代码目录结构

基于node.js实现微信支付退款功能 

入参

{ 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”

基于node.js实现微信支付退款功能 

最后

如果没有写退款功能或者不想写退款功能怎么办,其实可以从微信支付的后台pay.weixin.qq.com,也是能退款出去的,只是不想忘记了要人工将订单状态置为退款状态。

总结

以上所述是小编给大家介绍的基于node.js实现微信支付退款功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
了解jQuery技巧来提高你的代码(个人觉得那个jquery的手册很不错)
Feb 10 Javascript
js实现双击图片放大单击缩小的方法
Feb 17 Javascript
javascript实现简单计算器效果【推荐】
Apr 19 Javascript
微信小程序使用第三方库Immutable.js实例详解
Sep 27 Javascript
深入学习 JavaScript中的函数调用
Mar 23 Javascript
AngularJS读取JSON及XML文件的方法示例
May 25 Javascript
AngularJS监听ng-repeat渲染完成的两种方法
Jan 16 Javascript
angularjs 的数据绑定实现原理
Jul 02 Javascript
jQuery仿移动端支付宝键盘的实现代码
Aug 15 jQuery
react build 后打包发布总结
Aug 24 Javascript
在 Vue 中使用 JSX 及使用它的原因浅析
Feb 10 Javascript
JavaScript判断数据类型有几种方法及区别介绍
Sep 02 Javascript
React Native之prop-types进行属性确认详解
Dec 19 #Javascript
响应式框架Bootstrap栅格系统的实例
Dec 19 #Javascript
vue.js element-ui validate中代码不执行问题解决方法
Dec 18 #Javascript
AngularJs点击状态值改变背景色的实例
Dec 18 #Javascript
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
Dec 18 #jQuery
JS实现点击复选框变更DIV显示状态的示例代码
Dec 18 #Javascript
Vue下的国际化处理方法
Dec 18 #Javascript
You might like
如何分别全角和半角以避免乱码
2006/10/09 PHP
html中select语句读取mysql表中内容
2006/10/09 PHP
让PHP支持页面回退的两种方法
2008/01/10 PHP
PHP基于phpqrcode生成带LOGO图像的二维码实例
2015/07/10 PHP
PHP判断FORM表单或URL参数来的数据是否为整数的方法
2016/03/25 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
详解CSS样式中的 !important * _ 符号
2021/03/09 HTML / CSS
解决jquery .ajax 在IE下卡死问题的解决方法
2009/10/26 Javascript
javascript对话框使用方法(警告框 javascript确认框 提示框)
2014/01/07 Javascript
JQuery性能优化的几点建议
2014/05/14 Javascript
jQuery实现带渐显效果的人物多级关系图代码
2015/10/16 Javascript
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
基于jquery日历价格、库存等设置插件
2020/07/05 jQuery
JS中利用FileReader实现上传图片前本地预览功能
2018/03/02 Javascript
JS的函数调用栈stack size的计算方法
2018/06/24 Javascript
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python网络编程基于多线程实现多用户全双工聊天功能示例
2018/04/10 Python
python写入已存在的excel数据实例
2018/05/03 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
简单分析python的类变量、实例变量
2019/08/23 Python
python读取Kafka实例
2019/12/23 Python
pytorch实现特殊的Module--Sqeuential三种写法
2020/01/15 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
SVG实现多彩圆环倒计时效果的示例代码
2017/11/21 HTML / CSS
人力资源管理专业应届生求职信
2013/09/28 职场文书
销售文员的岗位职责
2013/11/20 职场文书
竞选班长自荐书范文
2014/03/09 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
2014光棍节单身联谊活动策划书
2014/10/10 职场文书
2014年自愿离婚协议书
2014/10/10 职场文书
暂住证明怎么写
2015/06/19 职场文书
矛盾论读书笔记
2015/06/29 职场文书
2015年社区反邪教工作总结
2015/10/14 职场文书
2016廉洁教育心得体会
2016/01/20 职场文书
Python使用MapReduce进行简单的销售统计
2022/04/22 Python