前端代码
weChatPay() {
uni.request({
url: 'http://www.xxxx.com/wechat/wxmporder',
data: {id},
dataType: 'json',
method: 'POST'
}).then(response => {
uni.requestPayment({
provider: 'wxpay',
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 => {
},
});
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
console.log('fail:' + JSON.stringify(err));
}
});
})
}
后台代码
router.all('/wxmporder', async function (req, res, next) {
const appid = '小程序appid'
const 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()
res.send({ 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)
}
})
}