uniapp+nodejs微信支付h5版

安装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, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
			appId: config.appId, // 必填,公众号的唯一标识
			timestamp: config.timeStamp, // 必填,生成签名的时间戳
			nonceStr: config.nonceStr, // 必填,生成签名的随机串
			signature: config.signature, // 必填,签名
			jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
		});
		jweixin.ready(() => {
			console.log('jweixin ready')
			jweixin.chooseWXPay({
				timestamp: pay.timeStamp, 
				nonceStr: pay.nonceStr, // 支付签名随机串,不长于 32 位
				package: pay.package, // 统一支付接口返回的prepay_id参数值
				signType: pay.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
				paySign: pay.paySign, // 支付签名
				success: function(res) {//支付成功回调
					uni.showModal({
						title: '提示',
						content: '支付成功',
						showCancel: false,
						success: res => {
							
						},
					});
				}
			});
		});
	})
}

后台代码

//微信h5下单
router.all('/h5order', async function (req, res, next) {
  const appid = '公众号appid'
  //该公众号下下单用户openId
  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)
      //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 = "";
      formData += "" + appid + "";  //appid
      formData += " + body + "]]>";
      formData += "" + mch_id + "";  //商户号
      formData += "" + nonce_str + ""; //随机字符串,不长于32位。
      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)
    }
  })
}

你可能感兴趣的:(uniapp,nodejs#微信开发)