这篇文章主要介绍了node.js实现微信支付退款功能,在微信开发中有有付款就会有退款,这样的功能非常常见,需要的朋友可以参考下
有付款就会有退款
注意,退款支持部分退款
左口袋的钱退到右口袋罗
这次发起的退款请求0.01元是实时到账的,因此,用户在小程序端发起的退款只是一个请求到后台,后台审核人员审核无误后才后微信发起退款操作。
引入第三方module
在package.json 中加入"weixin-pay": "^1.1.7"这一条
代码目录结构
入参
1 2 3 4 5 6 7 8 | { transaction_id: & #39;4200000005201712165508745023', // 交易
out_trade_no: & #39;5b97cba0ae164bd58dfe9e77891d3aaf', // 自己这头的交易号
out_refund_no: & #39;6f3240c353934105be34eb9f2d364cec', // 退款订单,自己生成
total_fee: 1,
nonce_str: & #39;1xSZW0op0KcdKoMYxnyxhEuF1fAQefhU', // 随机串
appid: & #39;wxff154ce14ad59a55', // 小程序 appid
mch_id: & #39;1447716902', // 微信支付商户id
sign: & #39;416FCB62F9B8F03C82E83052CC77524B' // 签名,weixin-pay这个module帮助生成 }
|
然后由wxpay为我们生成其余字段,比如nonce_str,sign,当然还少不了p12证书,
这个早选在wxpay初始代码里已经配置了,pfx: fs.readFileSync(__dirname + '/../../../cert/apiclient_cert.p12'), //微信商户平台证书
lib/wechat/utils/wxpay.js的源码
1 2 3 4 5 6 7 8 9 10 11 | const WXPay = require(& #39;weixin-pay'); // 引入weixin-pay这个第三方模块
const {weapp} = require(& #39;../../../utils/config'); // 我自己的全局配置文件,包括了appid key 等
const fs = require(& #39;fs');
const wxpay = WXPay({
appid: weapp.APPID,
mch_id: weapp.MCHID,
partner_key: weapp.KEY,
pfx: fs.readFileSync(__dirname + & #39;/../../../cert/apiclient_cert.p12'),
});
module.exports = wxpay;
|
另外还有一个util.js工具类
用于验证与错误回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | const wxpay = require(& #39;./wxpay');
const validateSign = results => {
const sign = wxpay.sign(results);
if (sign !== results.sign) {
const error = new Error(& #39;微信返回参数签名结果不正确');
error.code = & #39;INVALID_RESULT_SIGN';
throw error;
};
return results;
};
const handleError = results => {
if (results.return_code === & #39;FAIL') {
throw new Error(results.return_msg);
}
if (results.result_code !== & #39;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调起就可以了,成功就把订单状态改成"退款成功"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | router.post(& #39;/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, & #39;'),
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: & #39;退款失败'
})
);
}
if (result.result_code === & #39;SUCCESS') {
console.log(result);
order.status = & #39;REFUNDED';
order.save((err, response) => {
res.send(
utils.json({
msg: & #39;退款成功'
})
);
});
} 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不匹配'原来是小程序还没绑定公众号微信支付,这真是一个乌龙。
成功退款微信返回的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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”
|
重复退款将返回如下
1 2 3 4 5 6 7 8 9 | 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”
|
最后
如果没有写退款功能或者不想写退款功能怎么办,其实可以从微信支付的后台pay.weixin.qq.com,也是能退款出去的,只是不想忘记了要人工将订单状态置为退款状态。
以上就是本文的全部内容,希望对大家的学习有所帮助。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~