uniapp+nodejs微信支付小程序版

前端代码

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'

//小程序登录用户openId

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)

//MD5签名转大写

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

//组装xml数据

var formData = "<xml>";

formData += "<appid>" + appid + "</appid>"; //appid

formData += "<body><![CDATA[" + 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 += "<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>" + trade_type + "</trade_type>";

formData += "<openid>" + openid + "</openid>";

formData += "<sign>" + sign + "</sign>";

formData += "</xml>";

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)

}

})

}