安装JSSDK
npm install jweixin-module --save
前端代码
weChatPay() {
uni.request({
url: 'http://www.xxx.com/wechat/h5order',
data: {id},
dataType: 'json',
method: 'POST'
}).then(response => {
let pay = response[1].data.pay
let config = response[1].data.config
console.log(pay, config)
var jweixin = require('jweixin-module')
jweixin.config({
debug: true,
appId: config.appId,
timestamp: config.timeStamp,
nonceStr: config.nonceStr,
signature: config.signature,
jsApiList: ['chooseWXPay']
});
jweixin.ready(() => {
console.log('jweixin ready')
jweixin.chooseWXPay({
timestamp: pay.timeStamp,
nonceStr: pay.nonceStr,
package: pay.package,
signType: pay.signType,
paySign: pay.paySign,
success: function(res) {
uni.showModal({
title: '提示',
content: '支付成功',
showCancel: false,
success: res => {
},
});
}
});
});
})
}
后台代码
router.all('/h5order', async function (req, res, next) {
const appid = '公众号appid'
const openid = 'openid';
const total_fee = 1;
const body = '商品1'
const moment = require('moment')
const out_trade_no = moment(new Date()).format('YYYYMMDDHHmmss')
const notify_url = 'http://www.xxxx.com/wechat/wechatNotify'
const prepay_id = await Unifiedorder(appid, openid, body, total_fee, out_trade_no, notify_url, 'JSAPI')
const stringUtils = require('../utils/stringUtils')
const responseData = {
appId: appid,
timeStamp: new Date().getTime(),
nonceStr: stringUtils.randomString(20),
package: 'prepay_id=' + prepay_id,
signType: 'MD5',
}
const CryptoJS = require('crypto-js');
const resultSignStr = getSignStr(responseData)
responseData.paySign = CryptoJS.MD5(resultSignStr + '&key=' + mch_key).toString().toUpperCase()
const config = {
appId: appid,
timestamp: new Date().getTime(),
nonceStr: stringUtils.randomString(20),
}
const ticket = await getJsapiTicket();
const configSignStr = "jsapi_ticket=" + ticket + "&noncestr=" + config.nonceStr + "×tamp=" + config.timestamp + "&url=http://xxx.xxxx.com/m";
config.signature = CryptoJS.SHA1(configSignStr).toString().toUpperCase()
console.log('前端返回结果:',JSON.stringify({ config, pay: responseData }))
res.send({ config, pay: responseData })
})
拼接签名字符串方法
function getSignStr(map) {
let sortKeys = Object.keys(map).sort((a, b) => {
let index = 0;
while (true) {
let ai = index >= a.length ? 0 : a[index].charCodeAt()
let bi = index >= b.length ? 0 : b[index].charCodeAt()
let sub = ai - bi;
if (sub != 0 || (index >= a.length && index >= b.length)) {
return sub;
}
index++;
}
})
let arr = [];
for (let i in sortKeys) {
let key = sortKeys[i];
let val = map[key];
if (val == null || val == '') {
continue
}
arr.push(key + '=' + val)
}
return arr.join('&')
}
统一下单方法
function Unifiedorder(appid, openid, body, total_fee, orderNo, notify_url, trade_type) {
return new Promise(async (resolve, reject) => {
try {
const out_trade_no = orderNo
const spbill_create_ip = '192.168.3.20';
const stringUtils = require('../utils/stringUtils')
const nonce_str = stringUtils.randomString(20)
let map = {
appid, mch_id, nonce_str, body, out_trade_no, total_fee, spbill_create_ip, notify_url, trade_type, openid
}
const CryptoJS = require('crypto-js');
const signStr = getSignStr(map);
console.log('签名字符串:' + signStr)
const sign = CryptoJS.MD5(signStr + '&key=' + mch_key).toString().toUpperCase()
console.log(sign)
let url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
map.sign = sign
var formData = "";
formData += "" + appid + "";
formData += " + body + "]]>";
formData += "" + mch_id + "";
formData += "" + nonce_str + "";
formData += "" + notify_url + "";
formData += "" + out_trade_no + "";
formData += "" + spbill_create_ip + "";
formData += "" + total_fee + "";
formData += "" + trade_type + "";
formData += "" + openid + "";
formData += "" + sign + "";
formData += "";
console.log('统一下单参数:' + formData)
const http = require('../utils/httpUtils')
let result = await http.post(url, formData)
console.log('统一下单结果:' + result)
var xmlreader = require("xmlreader");
xmlreader.read(result, function (errors, response) {
if (!errors) {
const return_code = response.xml.return_code.text()
if (return_code == 'SUCCESS') {
const prepay_id = response.xml.prepay_id.text()
resolve(prepay_id)
}
} else {
reject(errors)
}
});
} catch (error) {
reject(error)
}
})
}