当前位置 博文首页 > RunningOnMyWay的博客:nodejs实现微信app支付-创建订单与签名部
var requestlib = require("request");
var urllib = require("url");
var crypto = require('crypto');
var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
var urlObj = urllib.parse(url);
var option = {
"url": urlObj,
"method": "POST"
};
option.headers = {
"Content-Type": "application/x-www-form-urlencoded"
};
//1. 参数部分
var dataobj = {
"appid": "【微信开放平台审核通过的应用APPID】",
"mch_id": "【微信支付分配的商户号】",
"nonce_str": "【随机字符串】",
"body": "商品描述",
"out_trade_no": "【订单号 32字符以内 平台自己的订单号】",
"total_fee": 1,//金额 原金额*100 以分为单位
"spbill_create_ip": "【后台服务器IP地址】",
"notify_url": "【回调接口地址】",
"trade_type": "APP"
};
//2.字典排序用于签名,并同步拼接xml参数
var keys = Object.keys(dataobj)
.sort();
var params = [];
var final = "<xml>";
for (let i = 0; i < keys.length; i++) {
var v = keys[i];
params.push(v + "=" + dataobj[v]);
final += "<" + v + ">" + dataobj[v] + "</" + v + ">";
}
//3.此处注意需要加上支付密钥
params.push("key=【这里是支付密钥】");
var str = params.join("&");
//4.开始MD5签名,注意转大写字母
var sign = crypto.createHash("md5")
.update(str)
.digest('hex')
.toUpperCase();
//5.完成最后的拼接xml参数,并发起请求
final += "<sign>" + sign + "</sign></xml>";
option.body = final;
return when.promise(function(resolve, reject, notify) {
requestlib(option, function(e, r, b) {
if (e) {
reject(e);
}
resolve(b);
});
});
console.log(JSON.stringify(retX));//返回的结果,次数仅处理正确结果
var dataobj = {};
//去掉干扰手动解析项
retX = retX.replace(/<\!\[CDATA\[/g,"").replace(/\]\]>/g,"").replace(/<\!\[CDATA\]>/g,"null");
//提取所需参数的key
var keys = ["appid","nonce_str","mch_id","prepay_id","trade_type"];
for (let i = 0; i < keys.length; i++) {
var v = keys[i];
//拼接正则取值
var re= new RegExp("<"+v+">(.*)</"+v+">");
dataobj[v]=re.exec(retX)[1];
// console.log(re.exec(retX)[1]);
}
//最终的dataobj为返回数据解析结果
var crypto = require('crypto');
// console.log(JSON.stringify(obj));
var dataobj2 = {
"appid": dataobj.appid,
"partnerid": dataobj.mch_id,
"prepayid": dataobj.prepay_id,
"package": "Sign=WXPay",
"noncestr": dataobj.nonce_str, //这里偷懒,直接使用返回值的随机字符串
"timestamp": moment()
.format("X") //使用moment获取时间秒数 注意是秒数
};
//字典排序
var keys = Object.keys(dataobj2)
.sort();
var params = [];
for (let i = 0; i < keys.length; i++) {
var v = keys[i];
params.push(v + "=" + dataobj2[v]);
}
params.push("key=【支付密钥】");
var str = params.join("&");
var sign = crypto.createHash("md5")
.update(str)
.digest('hex')
.toUpperCase();
dataobj2.sign = sign;
//dataobj2 为最终的参数集,可用手机调用支付