Home  >  Article  >  Web Front-end  >  Detailed example of node.js implementing WeChat payment refund function

Detailed example of node.js implementing WeChat payment refund function

小云云
小云云Original
2017-12-20 09:14:232948browse

WeChat development is becoming more and more popular. We know that there are payment and refund functions in WeChat. Such functions are very common. This article mainly introduces node.js to implement the WeChat payment refund function. Friends who need it can refer to it. , hope it can help everyone.

Origin

There will be a refund if payment is made

Note that refunds support partial refunds

The money from the left pocket will be returned to the right pocket

The refund request of 0.01 yuan initiated this time is received in real time. Therefore, the refund initiated by the user on the mini program is just a request to the backend, which will be reviewed by the backend reviewer. Only after everything is correct will WeChat initiate the refund operation.

Introduce third-party module

Add "weixin-pay": "^1.1.7" to package.json

Code directory structure

Enter the parameters

{ 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帮助生成 }

Then wxpay will generate the remaining fields for us, such as nonce_str, sign, and of course the p12 certificate.

This was selected early in wxpay It has been configured in the initial code, pfx: fs.readFileSync(__dirname + '/../../../cert/apiclient_cert.p12'), //WeChat Merchant Platform Certificate

lib/wechat/ The source code of 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;

There is also a util.js tool class

for verification and error callback

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

initiating a refund request

The refund logic is like this. First, find the transaction_id/out_trade_no/total_fee from your Order data table, and then add the out_refund_no refund order number you generated. The partial amount of this refund is refund_fee, and finally weixin -wxpay.refund under the pay module is sufficient. If successful, the order status will be changed to "Refund Successful"

// 退款
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
     })
    );
   }

  });
 });
});

Enter the pit

1. Encountered this time The pitfall is that refund_fee forgets to pass the value, which means that WeChat refund supports partial refund. If it is a full refund, then assign it the same value as total_fee

2. Op_user_id mentioned on the Internet: weapp. The parameter MCHID is optional

3. Just choose one of transaction_id and out_trade_no, so that a refund can be initiated even if the transaction_id is not recorded (for example, a callback for successful payment is not written); the priority is The former is greater than the latter, which was verified in the process of deliberately giving the wrong answer to the former.

4. An error was reported that the appid does not match the merchant number, return_code: 'FAIL', return_msg: 'The merchant number mch_id does not match the appid' It turns out that the mini program has not been bound to the official account WeChat payment. This is really a mistake.

Data returned by WeChat for successful refund

 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”

Repeated refunds will be returned as follows

 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”

Finally

If What should I do if I don’t have a refund function or don’t want to write a refund function? In fact, I can refund money through the backend of WeChat Pay at pay.weixin.qq.com. I just don’t want to forget to manually set the order status to refund status. .

Related recommendations:

How to implement WeChat applet payment and refund in php

##PHP backend UnionPay payment and refund example

10 recommended articles about refunds

The above is the detailed content of Detailed example of node.js implementing WeChat payment refund function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn