node-微信h5支付功能
#支付条件
1.微信公众号-申请支付 (https://mp.weixin.qq.com)
2.微信商户平台-申请支付(https://pay.weixin.qq.com)
#支付参数
var appid = 'wxxxxxxxxxxxxxxxxxx'; //微信公众号appid
var mchid = '159xxxxxxx' //微信商户平台账号mchid
var mchkey = 'haixxxxxxxxxxxxxxxxxx'; //微信商户平台秘钥
var wxurl = 'http://xxxxxx.com';//支付回调地址
#封装微信转换参数方法
var xmlreader = require("xmlreader"); var wxpay = { //把金额转为分 getmoney: function (money) { return parseFloat(money) * 100; }, // 随机字符串产生函数 createNonceStr: function () { return Math.random().toString(36).substr(2, 15); }, // 时间戳产生函数 createTimeStamp: function () { return parseInt(new Date().getTime() / 1000) + ''; }, //签名加密算法 paysignjsapi: function (appid, body, mch_id, nonce_str, notify_url, out_trade_no, spbill_create_ip, total_fee, trade_type, mchkey) { var ret = { appid: appid, mch_id: mch_id, nonce_str: nonce_str, body: body, notify_url: notify_url, out_trade_no: out_trade_no, spbill_create_ip: spbill_create_ip, total_fee: total_fee, trade_type: trade_type }; //console.log('ret==', ret); var string = raw(ret); var key = mchkey; string = string + '&key=' + key; //console.log('string=', string); var crypto = require('crypto'); return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase(); }, //签名加密算法,第二次的签名 paysignjsapifinal: function (appid,mch_id,prepayid,noncestr,timestamp,mchkey) { var ret = { appid: appid, partnerid: mch_id, prepayid: prepayid, package: 'Sign=WXPay', noncestr: noncestr, timestamp: timestamp, }; //console.log('retretret==', ret); var string = raw(ret); var key = mchkey; string = string + '&key=' + key; //console.log('stringstringstring=', string); var crypto = require('crypto'); return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase(); }, //签名加密算法ss paysignss: function (appid,mch_id,out_trade_no,nonce_str,mchkey) { var ret = { appid: appid, mch_id: mch_id, out_trade_no: out_trade_no, nonce_str : nonce_str }; //console.log('retretret==', ret); var string = raw(ret); var key = mchkey; string = string + '&key=' + key; //console.log('stringstringstring=', string); var crypto = require('crypto'); return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase(); }, getXMLNodeValue: function (xml) { // var tmp = xml.split("<"+node_name+">"); // console.log('tmp',tmp); // var _tmp = tmp[1].split("</"+node_name+">"); // console.log('_tmp',_tmp); // return _tmp[0]; xmlreader.read(xml, function (errors, response) { if (null !== errors) { //console.log(errors) return; } //console.log('长度===', response.xml.prepay_id.text().length); var prepay_id = response.xml.prepay_id.text(); //console.log('解析后的prepay_id==',prepay_id); return prepay_id; }); } } function raw(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; } module.exports = wxpay;
#api接口方法,传入后台订单号和订单金额
1 static async wxpay(sorder,smoney) { 2 //首先拿到前端传过来的参数 3 let orderCode = sorder; 4 let money = smoney; 5 6 //首先生成签名sign 7 let mch_id = mchid; 8 let nonce_str = wxpay.createNonceStr(); 9 let timestamp = wxpay.createTimeStamp(); 10 let body = '微信支付'; 11 let out_trade_no = orderCode; 12 let total_fee = wxpay.getmoney(money); 13 let spbill_create_ip = '49.235.115.11';//终端ip 14 let notify_url = wxurl; 15 let trade_type = 'NATIVE'; 16 let sign = wxpay.paysignjsapi(appid,body,mch_id,nonce_str,notify_url,out_trade_no,spbill_create_ip,total_fee,trade_type,mchkey); 17 //组装xml数据 18 var formData = "<xml>"; 19 formData += "<appid>"+appid+"</appid>"; //appid 20 formData += "<body><![CDATA["+"微信支付"+"]]></body>"; 21 formData += "<mch_id>"+mch_id+"</mch_id>"; //商户号 22 formData += "<nonce_str>"+nonce_str+"</nonce_str>"; //随机字符串,不长于32位。 23 formData += "<notify_url>"+notify_url+"</notify_url>"; 24 formData += "<out_trade_no>"+out_trade_no+"</out_trade_no>"; 25 formData += "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"; 26 formData += "<total_fee>"+total_fee+"</total_fee>"; 27 formData += "<trade_type>"+trade_type+"</trade_type>"; 28 formData += "<sign>"+sign+"</sign>"; 29 formData += "</xml>"; 30 var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; 31 32 let promise = new Promise(function(resolve, reject) { 33 request({url:url,method:'POST',body: formData},function(err,response,body){ 34 if(!err && response.statusCode == 200){ 35 //console.log(body); 36 xmlreader.read(body.toString("utf-8"), function (errors, response) { 37 var code_url = response.xml.code_url.text(); 38 resolve(code_url) 39 }); 40 } 41 }) 42 }); 43 return promise 44 }
#node插件
xmlreader(转义微信生成支付订单回调数据)