node 微信退款

 基于node 的微信退款

申请微信退款:微信退款

1.在前端页面访问 /refund

 

var request = require('request');
var WxPayRefund = require('./WxPayRefund');
var config = require('./../config');
var axios = require('axios')
    /* 退款 */
const refund = async(ctx, next) => {
    const { request: req, response: res } = ctx
    // 退款 参数
    var RefundInfo = {
        mch_id: config.mch_id, //商户号
        out_refund_no: req.query.out_refund_no, //商户退款单号 //商户系统内部的退款单号(自己生成)
        out_trade_no: req.query.out_trade_no, //商户系统内部订单号
        refund_fee: req.query.refund_fee, //退款金额
        total_fee: req.query.total_fee, //订单金额
    };
    console.log('RefundInfo', RefundInfo);
    // 参数成功回调
    var result = await WxPayRefund.WxPayRefund(RefundInfo).then(function(data) {
        // 成功返回 退款参数
        return JSON.stringify(data);
    });
    ctx.type = 'json';
    ctx.body = result;
}
module.exports = { refund };

 

1.1  WxPayRefund.js

var express = require('express');
var request = require('request');
var Q = require("q");
var crypto = require('crypto');
var ejs = require('ejs');
var fs = require('fs');
// 需要的参数设置 自行定义
var config = require("./../config");
var router = express.Router();

/* 微信 申请 退款 */
var key = config.key; //此处为申请微信支付的API密码
var APPID = config.AppID;
var WxPayRefund = {
    // 生成微信的xml
    getXMLNodeValue: function(node_name, xml) {
        var tmp = xml.split("<" + node_name + ">");
        var _tmp = tmp[1].split("</" + node_name + ">");
        return _tmp[0];
    },

    raw: function(args) {
        var keys = Object.keys(args);
        keys = keys.sort()
        var newArgs = {};
        keys.forEach(function(key) {
            newArgs[key] = args[key];
        });
        var string = '';
        for (var k in newArgs) {
            string += '&' + k + '=' + newArgs[k];
        }
        string = string.substr(1);
        return string;
    },

    paysignjs: function(appid, nonceStr, package, signType, timeStamp) {
        var ret = {
            appId: appid,
            nonceStr: nonceStr,
            package: package,
            signType: signType,
            timeStamp: timeStamp
        };
        var string = this.raw(ret);
        string = string + '&key=' + key;
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
        return sign.toUpperCase();
    },
    //签名
    paysignjsapi: function(appid, mch_id, nonce_str, out_refund_no, out_trade_no, refund_fee, total_fee) {
        var ret = {
            appid: appid,
            mch_id: mch_id,
            nonce_str: nonce_str,
            // notify_url: notify_url,
            out_refund_no: out_refund_no,
            out_trade_no: out_trade_no,
            refund_fee: refund_fee,
            total_fee: total_fee,
        };
        var string = this.raw(ret);
        string = string + '&key=' + key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 
        var crypto = require('crypto');
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
        return sign.toUpperCase();
    },

    // 随机字符串产生函数 
    createNonceStr: function() {
        return Math.random().toString(36).substr(2, 15);
    },

    // 时间戳产生函数 
    createTimeStamp: function() {
        return parseInt(new Date().getTime() / 1000) + '';
    },
    // 此处的attach不能为空值 否则微信提示签名错误 
    WxPayRefund: function(_order) {
        var deferred = Q.defer();
        var appid = APPID;
        var nonce_str = this.createNonceStr();
        var timeStamp = this.createTimeStamp();
        var url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //
        var formData = "<xml>";
        formData += "<appid>" + appid + "</appid>"; // 公众账号ID    appid
        formData += "<mch_id>" + _order.mch_id + "</mch_id>"; // 商户号    mch_id
        formData += "<nonce_str>" + nonce_str + "</nonce_str>"; // 随机字符串
        // formData += "<notify_url>" + _order.notify_url + "</notify_url>"; // 退款结果通知url
        formData += "<out_refund_no>" + _order.out_refund_no + "</out_refund_no>"; // 商户退款单号
        formData += "<out_trade_no>" + _order.out_trade_no + "</out_trade_no>"; //商户系统内部订单号
        formData += "<refund_fee>" + _order.refund_fee + "</refund_fee>"; // 退款金额
        formData += "<total_fee>" + _order.total_fee + "</total_fee>"; // 订单金额
        formData += "<sign>" + this.paysignjsapi(appid, _order.mch_id, nonce_str, _order.out_refund_no, _order.out_trade_no, _order.refund_fee, _order.total_fee) + "</sign>"; // 签名    sign
        formData += "</xml>";
        var self = this;
        request({
            url: url,
            method: 'POST',
            body: formData,
            agentOptions: {
                pfx: fs.readFileSync(__dirname + './../cert/apiclient_cert.p12'),
                passphrase: _order.mch_id
            }
        }, function(err, response, body) {
            if (!err && response.statusCode == 200) {
                console.log('11', body);
                var data = parser(body);
                deferred.resolve(data);
            } else {
                console.log('12', body);
            }
        });
        return deferred.promise;
    },
};

function parser(_da) {
    var xml = _da;
    xml = xml.slice('<xml>'.length, xml.indexOf('</xml>'));
    var tag = xml.match(/<\w+>/g);
    var len = tag.length;
    var obj = new Object(); //将微信 支付成功 返回的 xml 数据处理为json格式
    for (var i = 0; i < len; i++) {
        var node_name = tag[i].replace(/\<|\>/g, '');
        var tmp = xml.split("<" + node_name + ">");
        var _tmp = tmp[1].split("</" + node_name + ">");
        var result = _tmp[0];
        if (result.match(/^(?!.*CDATA)/)) {
            obj[node_name] = result;
        } else {
            obj[node_name] = result.split('[')[2].split(']')[0];
        }
    }
    return obj;
}
module.exports = WxPayRefund;

 

 在这里再次感谢在人生路上帮助我的人!谢谢你们。

如果以上代码对您有用,欢迎打赏!如有错误的地方也请您留言指出。

 

posted @ 2018-05-02 16:04  jimmy.wang123  阅读(748)  评论(0编辑  收藏  举报