对于接触过微信支付的朋友来说,利用小程序调用微信支付接口就容易很多。我在这里简单介绍一下小程序调用微信支付。

一、准备工作

    第一件事当然是开通微信支付功能了。微信小程序暂时不对个人开发支付接口,所以个人的微信小程序是无法使用微信支付的。

    对于开通微信支付功能,有两种方式:

    第一,直接在小程序提交支付申请,但是需要收300大洋(够黑的)。

微信APP支付iOS开发文档 小程序微信支付开发_xml

    第二,可以用已经通过支付申请的公众号申请小程序,然后使用M-A授权。具体怎么操作自行百度,开通微信支付必须开通商户号。开通支付功能之后,需要在商户平台找到商户号,设置Mch_key。

完成以上准备后我们就可以进行微信支付开发了。

二、微信支付开发

    微信开发的大体分为两步:第一步,调用微信统一下单接口。第二步,在小程序内调用微信支付组件。

    1、调用统一下单接口

/*
 * 根据openid 发起微信支付  
 */
function wxpay(req){
  var param = req.query || req.params;
  var openid = req.request.body.openid;
  var total_fee = (req.request.body.total_fee)*100;  // 订单价格 单位是 分
  var spbill_create_ip = req.ip.replace(/::ffff:/, ''); // 获取客户端ip
  var body = '充值'; // 商品描述
  var notify_url = 'https://www.vajssa.cn/api/wxpay' // 支付成功的回调地址  可访问 不带参数
  var nonce_str = createNonceStr(); // 随机字符串
  var out_trade_no = wxConfig.getWxPayOrdrID(); // 商户订单号(按自己需要生成)
  var timestamp = Math.round(new Date().getTime() / 1000); // 当前时间

  var bodyData = '<xml>';
  bodyData += '<appid>' + config.Mch_appid + '</appid>';  // 小程序ID
  bodyData += '<body>' + body + '</body>'; // 商品描述
  bodyData += '<mch_id>' + config.Mch_id + '</mch_id>'; // 商户号
  bodyData += '<nonce_str>' + nonce_str + '</nonce_str>'; // 随机字符串
  bodyData += '<notify_url>' + notify_url + '</notify_url>'; // 支付成功的回调地址 
  bodyData += '<openid>' + openid + '</openid>'; // 用户标识
  bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>'; // 商户订单号
  bodyData += '<spbill_create_ip>' + spbill_create_ip + '</spbill_create_ip>'; // 终端IP
  bodyData += '<total_fee>' + total_fee + '</total_fee>'; // 总金额 单位为分
  bodyData += '<trade_type>JSAPI</trade_type>'; // 交易类型 小程序取值如下:JSAPI
  // 签名
  var sign = paysignjsapi(
    config.Mch_appid,
    body,
    config.Mch_id,
    nonce_str,
    notify_url,
    openid,
    out_trade_no,
    spbill_create_ip,
    total_fee
  );
  bodyData += '<sign>' + sign + '</sign>';
  bodyData += '</xml>';
  // 微信小程序统一下单接口
  var urlStr = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  return new Promise(function (resolve, reject) {
    request({
      url: urlStr,
      method: 'POST',
      body: bodyData
    }, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        var returnValue = {};
        parseString(body, function (err, result) {
          if (result.xml.return_code[0] == 'SUCCESS') {
            returnValue.msg = '操作成功';
            returnValue.status = '100';
            returnValue.out_trade_no = out_trade_no;  // 商户订单号
            returnValue.total_fee = total_fee;  // 交易金额
            // 小程序 客户端支付需要 nonceStr,timestamp,package,paySign  这四个参数
            returnValue.nonceStr = result.xml.nonce_str[0]; // 随机字符串
            returnValue.timestamp = timestamp.toString(); // 时间戳
            returnValue.package = 'prepay_id=' + result.xml.prepay_id[0]; // 统一下单接口返回的 prepay_id 参数值
            returnValue.paySign = paysignjs(config.Mch_appid, returnValue.nonceStr, returnValue.package, 'MD5', timestamp); // 签名
            resolve(JSON.stringify(returnValue)) 
          } else {
            returnValue.msg = result.xml.return_msg[0];
            returnValue.status = '102';
            reject(JSON.stringify(returnValue))
          }
        });
      }
    })
  }).catch(function (error) {//加上catch 
          console.log('error=',error);
		  return error
        })
}

2、小程序调用微信支付组件。

    调用微信统一下单接口后,接口会返回小程序调用组件所需要的参数:nonceStr,timestamp,package,paySign。

将这些参数传到前台小程序,发起微信支付。

wx.requestPayment({
            'timeStamp': payModel.timestamp,
            'nonceStr': payModel.nonceStr,
            'package': payModel.package,
            'signType': 'MD5',
            'paySign': payModel.paySign,
            'success': function (res) {
              wx.showToast({
                title: '支付成功',
                icon: 'success',
                duration: 2000
              });