一、小程序開(kāi)通微信支付、服務(wù)端域名認(rèn)證步驟省略
二蔗蹋、創(chuàng)建工具函數(shù)
1何荚、創(chuàng)建utils.js
2、加密算法使用插件:執(zhí)行 npm install --save crypto
const wxconfig = {
//把金額轉(zhuǎn)為分
getmoney: function (money) {
return parseFloat(money) * 100;
},
// 隨機(jī)字符串產(chǎn)生函數(shù)
createNonceStr: function () {
return Math.random().toString(36).substr(2, 15);
},
// 時(shí)間戳產(chǎn)生函數(shù)
createTimeStamp: function () {
return parseInt(new Date().getTime() / 1000) + '';
},
//簽名加密算法
paysignjsapi: function (appid,openid, 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,
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);
var key = mchkey;
string = string + '&key=' + key;
var crypto = require('crypto');
return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase();
},
// 小程序簽名
paysignjsapix: function (appId, nonceStr, package, signType, timestamp, mchkey) {
var ret = {
appId: appId,
nonceStr: nonceStr,
package: package,
signType: signType,
timeStamp: timestamp,
};
var string = this.raw(ret);
var key = mchkey;
string = string + '&key=' + key;
var crypto = require('crypto');
return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase();
},
// 對(duì)象序列化猪杭,key=value&key1=value1
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;
}
}
三餐塘、nodejs生成接口
var request = require('request');
var xmlreader = require("xmlreader");
var wxpay = require('./utils');
var appid = "xxx"http:// 小程序的appid
var appsecret ="xxx"http:// 小程序的appSecret
var mch_id = "xxx"; // 微信商戶號(hào)
var mchkey = "xxx"; // 微信商戶的key 32位
var notify_url = "https://www.xxx.com" //通知地址
var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//微信支付統(tǒng)一調(diào)用接口
router.post("/wxpay",function(req,res){
let out_trade_no = new Date().getTime()
let money = req.body.money
let openid = req.body.openid
let nonce_str = wxpay.createNonceStr();
let timestamp = wxpay.createTimeStamp();
let body ='測(cè)試微信支付';
let total_fee = wxpay.getmoney(money);
let spbill_create_ip = req.connection.remoteAddress; // 服務(wù)ip
let trade_type = 'JSAPI' // 小程序: 'JSAPI'
let sign = wxpay.paysignjsapi(appid,openid,body,mch_id,nonce_str,notify_url,out_trade_no,spbill_create_ip,total_fee,trade_type,mchkey)
//組裝xml數(shù)據(jù)
var formData = "<xml>";
formData += "<appid>" + appid + "</appid>";
formData += "<body><![CDATA[" + "測(cè)試微信支付" + "]]></body>";
formData += "<mch_id>" + mch_id + "</mch_id>";
formData += "<nonce_str>" + nonce_str + "</nonce_str>";
formData += "<notify_url>" + notify_url + "</notify_url>";
formData += "<openid>" + openid + "</openid>";
formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>";
formData += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";
formData += "<total_fee>" + total_fee + "</total_fee>";
formData += "<trade_type>JSAPI</trade_type>";
formData += "<sign>" + sign + "</sign>";
formData += "</xml>";
// 請(qǐng)求微信統(tǒng)一支付接口
request({ url: url, method: 'POST', body: formData }, function (err, response, body) {
if (!err && response.statusCode == 200) {
xmlreader.read(body.toString("utf-8"), function (errors, response) {
if (null !== errors) {
return;
}
var prepay_id = response.xml.prepay_id.text();
let package = "prepay_id=" + prepay_id;
let signType = "MD5";
let minisign = wxpay.paysignjsapix(appid, nonce_str, package, signType, timestamp, mchkey);
// 返回?cái)?shù)據(jù)到前端
res.send(data:{
status: '200',
data: {
'appId': appid,
'mchid': mch_id,
'prepayId': prepay_id,
'nonceStr': nonce_str,
'timeStamp': timestamp,
'package':package,
'paySign': minisign
}
});
});
}
});
})
四、小程序發(fā)起請(qǐng)求
pay: function () {
let data = {
openid: "xxxxxxxx",
money: 0.01
}
wx.request({
url: "https://xxx.com/wxpay",
data: data,
method: "POST",
dataType: "json",
success: (res) => {
let data = res.data.data
wx.requestPayment({
"timeStamp": data.timeStamp,
"package": "prepay_id=" + data.prepayId,
"nonceStr": data.nonceStr,
"signType": "MD5",
"paySign": data.paySign,
'success': function (res) {
console.log( "支付成功", res)
},
'fail': function (res) { },
'complete': function (res) { }
})
}
})
},