基于nodejs微信支付
2016-05-25 11:05
477 查看
通过nodejs使用微信支付最重要的就是微信的签名,在这里md5后的字符必须转化为大写
一、回复微信通知消息模版
message.ejs
<xml>
<return_code><![CDATA[<%-return_code%>]]></return_code>
<return_msg><![CDATA[<%=return_msg%>]]></return_msg>
</xml>
二、微信支付model文件代码如下:
wxpay.js
var config = require('../config'); //配置文件 appid 等信息
var Q = require("q");
var request = require("request");
var crypto = require('crypto');
var ejs = require('ejs');
var fs = require('fs');
var key = "此处为申请微信支付的API密码";
var messageTpl = fs.readFileSync(__dirname + '/message.ejs', 'utf-8');
var WxPay = {
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, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) {
var ret = {
appid: appid,
attach: attach,
body: body,
mch_id: mch_id,
nonce_str: nonce_str,
notify_url: notify_url,
openid: openid,
out_trade_no: out_trade_no,
spbill_create_ip: spbill_create_ip,
total_fee: total_fee,
trade_type: trade_type
};
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) + '';
},
三、在express router中调用wxpay
//微信支付demo
router.get('/order', function(req, res, next){
var attach = "1276687601";
var body = "测试支付";
var mch_id = "1111111"; //商户ID
var openid = "111111";
var bookingNo = "201501806125346"; //订单号
var total_fee = 10;
var notify_url = "http://localhost/wxpay/notify"; //通知地址
wxpay.order(attach, body, mch_id, openid, bookingNo, total_fee, notify_url).then(function(data){
res.render('wxpay', {args: data});
});
});
一、回复微信通知消息模版
message.ejs
<xml>
<return_code><![CDATA[<%-return_code%>]]></return_code>
<return_msg><![CDATA[<%=return_msg%>]]></return_msg>
</xml>
二、微信支付model文件代码如下:
wxpay.js
var config = require('../config'); //配置文件 appid 等信息
var Q = require("q");
var request = require("request");
var crypto = require('crypto');
var ejs = require('ejs');
var fs = require('fs');
var key = "此处为申请微信支付的API密码";
var messageTpl = fs.readFileSync(__dirname + '/message.ejs', 'utf-8');
var WxPay = {
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, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) {
var ret = {
appid: appid,
attach: attach,
body: body,
mch_id: mch_id,
nonce_str: nonce_str,
notify_url: notify_url,
openid: openid,
out_trade_no: out_trade_no,
spbill_create_ip: spbill_create_ip,
total_fee: total_fee,
trade_type: trade_type
};
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不能为空值 否则微信提示签名错误 order: function(attach, body, mch_id, openid, bookingNo, total_fee, notify_url) { var deferred = Q.defer(); var appid = config.member_config.appid; var nonce_str = this.createNonceStr(); var timeStamp = this.createTimeStamp(); var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; var formData = "<xml>"; formData += "<appid>" + appid + "</appid>"; //appid formData += "<attach>" + attach + "</attach>"; //附加数据 formData += "<body>" + body + "</body>"; formData += "<mch_id>" + mch_id + "</mch_id>"; //商户号 formData += "<nonce_str>" + nonce_str + "</nonce_str>"; //随机字符串,不长于32位。 formData += "<notify_url>" + notify_url + "</notify_url>"; formData += "<openid>" + openid + "</openid>"; formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"; formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"; formData += "<total_fee>" + total_fee + "</total_fee>"; formData += "<trade_type>JSAPI</trade_type>"; formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"; formData += "</xml>"; var self = this; request({ url: url, method: 'POST', body: formData }, function(err, response, body) { if (!err && response.statusCode == 200) { console.log(body); var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")); var tmp = prepay_id.split('['); var tmp1 = tmp[2].split(']'); //签名 var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp); var args = { appId: appid, timeStamp: timeStamp, nonceStr: nonce_str, signType: "MD5", package: tmp1[0], paySign: _paySignjs }; deferred.resolve(args); } else { console.log(body); } }); return deferred.promise; }, //支付回调通知 notify: function(obj) { var output = ""; if (obj.return_code == "SUCCESS") { var reply = { return_code: "SUCCESS", return_msg: "OK" }; } else { var reply = { return_code: "FAIL", return_msg: "FAIL" }; } output = ejs.render(messageTpl, reply); return output; }, }; module.exports = WxPay;
三、在express router中调用wxpay
//微信支付demo
router.get('/order', function(req, res, next){
var attach = "1276687601";
var body = "测试支付";
var mch_id = "1111111"; //商户ID
var openid = "111111";
var bookingNo = "201501806125346"; //订单号
var total_fee = 10;
var notify_url = "http://localhost/wxpay/notify"; //通知地址
wxpay.order(attach, body, mch_id, openid, bookingNo, total_fee, notify_url).then(function(data){
res.render('wxpay', {args: data});
});
});
//微信回调通知 采用数据流形式读取微信返回的xml数据 此处不在累赘 router.post('/notify', function(req, res, next){ });
相关文章推荐
- 社交巨头三国杀:微信、WhatsApp、Line到底有啥区别?
- 微信悄悄升级群聊功能:个人微信营销号的福音
- 突击部队拼多多
- 我是运营,我没有假期
- 如何做到日消息量100万的微信公众号?
- 论微信取消推送功能的可能性(原创)
- 微信的成功,靠的是QQ导流吗?
- 「Linux 中国」2018 微信文章排行榜
- 马化腾亲自“站台” 企业微信和个人微信互通能带来什么?
- 一个微信群的兴亡
- Ruby on Rails在Ping ++ 平台实现支付
- 使用ruby部署工具mina快速部署nodejs应用教程
- 微信服务号推送模板消息接口
- Google官方支持的NodeJS访问API,提供后台登录授权
- 浅谈Nodejs观察者模式
- nodejs教程之环境安装及运行