参考博客
https://blog.youkuaiyun.com/pengfeng111833/article/details/81989278
因为微信是使用的xml进行的请求,所以最后结果需要使用xml2js进行xml转json,需要使用到的插件是xml2js
安装
npm i xml2js --save
npm i request --save
首先有两个文件需要建立一个是wxpay.js和config.js
config.js文件编写内容 配置为自己需要的内容
'use strict';
module.exports = {
clientIp:"126.77.66.132",
showName:"天天科技",
wishing:"恭喜发财",
mch_id:"1511515151",
wxkey:"tiantiankeji8888", //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
appid:"wxefcc9999999999",//微信支付app的appid
appsecret: "wx8888888888888"//公众号secret
}
wxpay.js文件编写内容
/*拼接微信企业付款字符串 */
let config = require('./config');
let request = require('request'); //用于node 的http请求
let xml2js = require('xml2js');
let fs = require('fs');
let https = require('https');
//生成xml函数
let fnCreateXml = function(json){
let _xml = '';
for(let key in json) {
_xml+= '<'+key+'>'+json[key]+'</'+key+'>';
}
return _xml;
}
/*生成url串用于微信md5校验*/
let fnCreateUrlParam = function(json){
let _str = '';
let _arr = []
for(let key in json){
_arr.push(key+'='+json[key]);
}
return _arr.join('&');
}
/*生成付款xml参数数据*/
let fnGetWeixinBonus = function(option){
console.log("option===",option);
let amount = option.amount || 100; //红包总金额
let openid = option.openid || '可以修改成你自己的openid,这样如果出错就会发送到你的账户上面了';//红包发送的目标用户
let now = new Date();
let showName = config.showName;
let clientIp = config.clientIp; //ip地址
let desc = config.wishing; //企业付款备注
let mch_id = config.mch_id; //商户号
let mch_appid = config.appid; //appid
let wxkey = config.wxkey; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
let date_time = now.getFullYear()+''+(now.getMonth()+1)+''+now.getDate();
let date_no = (now.getTime() +'').substr(-8); //生成8为日期数据,精确到毫秒
let random_no = Math.floor(Math.random()*99);
if(random_no < 10){ //生成位数为2的随机码
random_no = '0'+ random_no;
}
let nonce_str = Math.random().toString(36).substr(2, 15); //生成随机字符串
let partner_trade_no = mch_id + date_time+ date_no + random_no; //生成商户订单号
let contentJson = {};
contentJson.amount = amount;// '100';
contentJson.check_name = "NO_CHECK";// '强制验证名字';FORCE_CHECK
contentJson.desc = desc;//'恭喜发财';
contentJson.mch_appid = mch_appid;//商户appid
contentJson.mchid = mch_id;
contentJson.nonce_str = nonce_str;
contentJson.openid = openid;// 'oovyt4u9yTamaCAxlZ-U2HjH-Z'; //墨色梧桐的openid // 'oovyt4u9yTamaCAxlZ-U2HjH-Z';
contentJson.partner_trade_no = partner_trade_no; //订单号为 mch_id + yyyymmdd+10位一天内不能重复的数字; //+201502041234567893';
// contentJson.re_user_name = showName;
contentJson.spbill_create_ip = clientIp; //IP地址
contentJson.key = wxkey; //微信安全密钥
/*生成url串用于微信md5校验*/
let contentStr = fnCreateUrlParam(contentJson);
console.log('content='+ contentStr);
//生成签名
let crypto = require('crypto');
contentJson.sign = crypto.createHash('md5').update(contentStr, 'utf8').digest('hex').toUpperCase();
//删除 contentJson对象中的key (key不参与签名)
delete contentJson.key;
//生成xml函数
let xmlData = fnCreateXml(contentJson);
let sendData = '<xml>'+ xmlData +'</xml>'; //_xmlTemplate.replace(/{content}/)
console.log('xml='+ sendData);
return sendData;
}
//微信企业支付到零钱
exports.wxcompay = function(requ,callback){
// https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
let amount = requ.amount; //金额
let openid = requ.openid;
let option = {amount,openid};
let sendData = fnGetWeixinBonus(option);
console.log('sendData=====',sendData)
//读取微信生成的证书用作加密
let opt = {
url:"https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers",
body:sendData,
key: fs.readFileSync('./config/apiclient_key.pem'), //将微信生成的证书放入 cert目录下
cert: fs.readFileSync('./config/apiclient_cert.pem'),
// ca:fs.readFileSync('./config/apiclient_cert.p12')
}
request.post(opt,function(err,res,body){
console.log('err==',err);
console.log("body==",body);
let parser = new xml2js.Parser({ trim:true, explicitArray:false, explicitRoot:false });//解析签名结果xml转json
parser.parseString(body,function(err,res){
console.log("res==",res);
if(res.result_code == 'SUCCESS'){
return callback({flag:true})
}else{
return callback({flag:false})
}
})
})
}
接口当中进行编写
//微信企业支付js引用
let wxcompay = require('./wxPay');
app.post('/wxcompay',function(req,routerRes){
let amount = req.body.amount; //金额
let openid = req.body.openid; //用户的openid 如果是用户的userId 那么需要再进行数据库查询用户的openid再来进行支付
wxcompay.wxcompay({amount:amount,openid:openid},function(res){
console.log(res);
})
});
接着就可以在回调中进行你想要的操作了
注意:最核心的地方是wxpay.js文件中的封装的三个函数(fnCreateXml,fnCreateUrlParam,fnGetWeixinBonus),这三个函数实现了xml字段的生成,这个生成的xml字段中包含了签名算法的完成,随机字符串的完成,商户订单号的生成,其他的参数都是可以进行配置的
配置完成xml参数,进行post请求就完成了企业到用户零钱的支付,但是这里有个问题就是进行的post请求一定需要使用微信的证书进行ssl,这样才能够正常完成请求,否则会出现报错