1. 程式人生 > >nodejs 微信退款

nodejs 微信退款

基於nodejs 微信退款

說明

只是單純的記錄學習過程
官方文件:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4

準備

1.當然已經有了已支付的訂單
2.退款需要雙向證書,證書下載可見官網
微信商戶平臺(pay.weixin.qq.com)–>賬戶中心–>賬戶設定–>API安全 。

那就開始吧

exports.miniRefund =   function (req,res)
{ let refundData = req.body;//獲取資料 在這裡我獲取的其實就是該訂單支付的時候的資訊,因為當時存起來了,大家根據自己邏輯新增資料 let appid = refundData.appid;//公眾賬號ID let mch_id = refundData.mch_id//商戶號 let nonce_str = refundData.nonce_str//這是隨機字串,為了方便我用的是該訂單在支付的時候的隨機字串 let out_trade_no = refundData.out_trade_no;//支付的訂單號 let out_refund_no = refundData.
out_refund_no;//退款訂單號 let total_fee= refundData.total_fee;//支付金額 let refund_fee = total_fee;//退款金額 因為我的邏輯是全額退款所以退款金額等於支付金額 let refund_desc = refundData.refund_desc;//退款原因 let sign = wechatUtil.refundSign(appid,mch_id,nonce_str,out_trade_no,out_refund_no,total_fee,refund_fee,refund_desc);//最重要的一步 簽名 這是呼叫了我自己封裝的一個方法,後面也會貼出來,關於簽名大家可以到網上看一下就不說了
let formData = "<xml>"; formData += "<appid>"+appid+"</appid>"; formData += "<mch_id>"+mch_id+"</mch_id>"; formData += "<nonce_str>"+nonce_str+"</nonce_str>"; formData += "<out_trade_no>"+out_trade_no+"</out_trade_no>"; formData += "<out_refund_no>"+out_refund_no+"</out_refund_no>"; formData += "<total_fee>"+total_fee+"</total_fee>"; formData += "<refund_fee>"+refund_fee+"</refund_fee>"; formData += "<refund_desc>"+refund_desc+"</refund_desc>"; formData += "<sign>"+sign+"</sign>"; formData += "</xml>"; /*==================================================*/ //接下來我們要用到一個request let request = require('request');//當然我們引用要寫在最上面,但為了看的清楚點就一步一步走吧 request({ //請求地址 url:'https://api.mch.weixin.qq.com/secapi/pay/refund', //還記得準備的證書嗎這裡就用到啦 agentOptions: { cert: fs.readFileSync(path1.join(__dirname,'../../cert/apiclient_cert.pem')), key: fs.readFileSync(path1.join(__dirname,'../../cert/apiclient_key.pem' )) }, method: 'POST', //攜帶這我們拼接好的引數 body:formData }, function (err,body) { //getXMLNodeValue:因為微信返回的結果是xml形式的所以封裝了一個解析的方法,會面會貼出來 let trade_state_desc = wechatUtil.getXMLNodeValue('return_code', body.body.toString('utf-8')); let return_msg = wechatUtil.getXMLNodeValue('return_msg', body.body.toString('utf-8')); let err_code_des = wechatUtil.getXMLNodeValue('err_code_des', body.body.toString('utf-8')); //為什麼要加上這個引數err_code_des....我也很是無奈前兩個引數只能正面是真的訪問成功了,但是我試了一下 瞎寫的訂單號提交 //這兩個引數還是正常的,但會多出 err_code_des這個引數,返回的是提示資訊.所以前兩個引數正確且沒有這個引數的時候我才能知道 //提交的資訊沒有問題,所以就這樣寫了,但肯定不是很好,我會想想解決辦法. if(return_code=='SUCCESS'&&return_msg=='OK'&&err_code_des==undefined){ log.info("退款成功") let data = { result:'1', msg:'已退款成功' }; res.json(data) }else { let data = { result:'0', msg:err_code_des }; res.json(data) } }); }

接下是加簽的方法和解析xml的方法

//解析xml資料
exports.getXMLNodeValue = (node_name,xml)=>{
    log.info(xml);
        let tmp = xml.split("<"+node_name+">");
        if(tmp[1]!=undefined){
            let _tmp = tmp[1].split("</"+node_name+">");
            let tmp1 = _tmp[0].split('[');

            let _tmp1 = tmp1[2].split(']');
            return _tmp1[0];
        }
};
//退款簽名
exports.refundSign=(appid,mch_id,nonce_str,out_trade_no,out_refund_no,total_fee,refund_fee,refund_desc)=>{
    let ret = {
        appid: appid,
        mch_id: mch_id,
        nonce_str:nonce_str,
        out_trade_no:out_trade_no,//注意左邊引數名,
        out_refund_no:out_refund_no,
        total_fee:total_fee,
        refund_fee:refund_fee,
        refund_desc:refund_desc
    };
    log.info("查詢簽名驗證的引數",ret);
    let string = raw(ret);
    let key = "金鑰*************";
    string = string + '&key='+key;
    return crypto.createHash('md5').update(string,'utf8').digest('hex').toUpperCase();
};
//排序PS : key toLowerCase
function raw(args) {
    var keys = Object.keys(args);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (key) {
        newArgs[key.toLowerCase()] = args[key];
    });
    var string = '';
    for (var k in newArgs) {
        string += '&' + k + '=' + newArgs[k];
    }
    string = string.substr(1);
    console.log(string);
    return string;
};

Alt

結束

但還是有很多問題…可以看到商品詳情是undefined,但我在文件中也沒有找到商品詳情的引數,
有點煩,希望儘快解決,當然我們還是少了一步,我們還應該通過查詢退款來做驗證,因為我還沒弄,但感覺難度也不會很大,後面會補上