在小程序中不能使用之前在浏览器中配置的支付功能,只能调用小程序专属的api进行支付。

因为需要在现在实现的基础上,再添加在小程序中调用微信支付功能,所以我的思路是这样的

1.在点击支付按钮时,判断是不是在小程序中

2.调用小程序支付的页面,并传过去需要的值

3.在小程序支付的js文件中进行调用

实现:

首先需要引入wx的解析文件

下载地址:https://github.com/wangvv9264/jweixin

<script type="text/javascript" src="/index/js/jweixin-1.3.2.js"></script>

判断是不是在小程序中

var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
   //ios的ua中无miniProgram,但都有MicroMessenger(表示是微信浏览器)
  wx.miniProgram.getEnv((res)=>{   
    if (res.miniprogram) {
      console.log(\'在小程序内\')
      wx.miniProgram.navigateTo({                                
        url: "/pages/prowxpay/prowxpay?info="+queryParam       //小程序的支付地址,queryParam是需要传递的商品id等数据
      });
      return false;
   }else{
     console.log(\'在微信内,但是不在小程序内\')
     return false;
   }
 })
}else{
  console.log(\'在微信外\')
  return false;
}    

在小程序支付的js文件中进行调用

var app = getApp();
Page({
  data: {
    bt: \'bt\'
  },

  onLoad: function (options) {
    var that = this;
    if (options.goods_id) {
      that.setLoading(options);
    } else { wx.navigateBack();}
  },

  setLoading: function(a) {
    var that = this
    wx.login({
      success: function(res) {
        // 成功会返回:
        // {errMsg: "login:ok", code: "获取用户OpenID的ticket"}
        that.getOpenId(res.code,a)
      }
    })
  },
  getOpenId: function (jsCode,a) {
    var that = this
    wx.request({
      url: baseURL + \'/index/Xcxpay/login\',  //baseURL引入的https地址
      data: {
        js_code: jsCode // wx.login()时得到的ticket
      },
      success: function (res) {
        that.getPrePayId(res.data.openid,a)
      },
      fail: function (res) {
        console.log(res)
        that.setData({
          bt: \'\'
        }), 
        wx.showModal({ title: "网络超时", content: "刷新重试", showCancel: !1 });
      }
    })
  },
  getPrePayId: function (openId, a) {var that = this
   wx.request({
     url: baseURL + \'/index/Xcxpay/index?openid=\'+openId+\'&goods_id=\' + a.goods_id  ,
     success: function (res) {
       console.log(res.data);
       if(res.data.status == 1) {
          that.pay(res.data.data,a);
       } else {
         var msg = String(res.data.msg);
        wx.showModal({
          title: "提醒",
          content: msg,
          showCancel: !1,
          success(res) {            
            if(res.confirm) {
              wx.navigateBack({
                delta: 1
              })
            }
          }
        })
        return false;
       }
     },
     fail:function (res) {
       console.log(res);
       that.setData({
         bt: \'\'
       })
     }
   })
 },
  // data是服务端返回的JSON
  // 加上success、fail回调后,正好符合wx.requestPayment()参数的格式
  pay: function (res, a) {
    console.log(res)
    wx.requestPayment({                //成功之后,调用小程序微信支付
      \'timeStamp\': res.timeStamp,
      \'nonceStr\': res.nonceStr,
      \'package\': res.package,
      \'signType\': \'MD5\',
      \'paySign\': res.paySign,
      success: function (res) {
        console.log(res)
        wx.request({
          url: baseURL + \'/index/Xcxpay/callback?goods_id=\' + a.goods_id + \'&msg=\' + res.errMsg,
          success: function(res){
            console.log(res.data.status)
            if(res.data.status == 1) {
              wx.showToast({
                title: \'支付成功\',
                icon: \'success\',
                duration: 2000
              })
              setTimeout(()=>{
                wx.redirectTo({
                  url: \'/pages/order/order\',
                })
              },2001)              
            }
            
          },
          fail: function(){}
        })
        
      }, 
      fail: function (res) {
        console.log(\'付款失败\');
        console.log(res)
        wx.showModal({
          title: \'提醒\',
          content: \'付款失败\',
          showCancel: false,
          success:function(res){
            if(res.confirm) {
              wx.navigateBack({
                delta: 1
              })
            }
          }
        })
        return
      },
    })
  },

  wdxreload: function(){
    var pages = getCurrentPages();
    var currentPage = pages[pages.length - 1]; //获取当前页面的对象
    var url = currentPage.route; //当前页面url
    var options = currentPage.options; //如果要获取url中所带的参数可以查看options
    wx.navigateTo({ url: "/pages/wxpay/wxpay?goods_id=" + options.goods_id});
  }
  
})

 我对接的后台是php,下面附上代码

public function login() {
        $appid=\'微信小程序的appId\';
        $secret=\'微信小程序的密钥\';

        $params = array(
          \'appid\' => $appid,
          \'secret\' => $secret,
          \'js_code\' => $_GET[\'js_code\'], // 小程序传来的ticket
          \'grant_type\' => \'authorization_code\',
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, \'https://api.weixin.qq.com/sns/jscode2session\');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        $output = curl_exec($ch);

        if (false === $output) {
          echo \'CURL Error:\' . curl_error($ch);
        }
        echo $output;
        
    }

    //https://blog.csdn.net/u010505805/article/details/76861853
    public function index(){
        $order_id = isset($_GET[\'goods_id\']) ? intval($_GET[\'goods_id\']) : \'\';
        $openid = $_GET[\'openid\'];

        $this->pub_index($openid,$order_id);

    }
    public function pub_index($openid,$order_id){
        $appid=\'小程序appId\';
        $secret=\'微信小程序的密钥\';
        $url="https://api.mch.weixin.qq.com/pay/unifiedorder";

        $mch_id = \'\';//受理商ID(即微信支付商户号)
        $mch_key = \'\';//商户支付密钥Key
        $order = $orderinfo=Db::name(\'order_info\')->where(\'order_code="\'.$order_id.\'"\')->find();
        $total_fee=$order[\'order_amount\'] * 100;

        $params = array(
          \'appid\' => $appid,  // 小程序appid
          \'mch_id\' => $mch_id,
          \'nonce_str\' => (string)mt_rand(10000, 99999),   // 随机串,32字符以内
          \'body\' => \' \',   // 商品名
          \'out_trade_no\' => $order[\'order_code\'], 
          //\'out_trade_no\' => substr( $order[\'order_code\'].\'A\'.($order[\'order_amount\']*100).\'B\' ,0,32),  
          //订单号32字符以内。串接后取前32位。多次支付时如果重复的话,微信会返回“重复下单”
          \'spbill_create_ip\' => $_SERVER[\'REMOTE_ADDR\'],
          \'notify_url\' => \'\',  // 支付成功后的回调地址,由腾讯服务端回调
          \'trade_type\' => \'JSAPI\',
          \'openid\' => $openid,  // 小程序传来的OpenID
          \'total_fee\' =>(string)$total_fee,  // 订单费用,单位:分
        );

        //var_dump($params);die;
        // 按照要求计算sign
        ksort($params);
        $sequence = \'\';
        foreach ($params as $key => $value) {
          $sequence .= "$key=$value&";
        }

        $sequence = $sequence . "key=".$mch_key;
        //echo $sequence;die;
        $params[\'sign\'] = strtoupper(md5($sequence));

        $xml =$this->arrayToXml($params);


        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);


        if (false === $output) {
          echo \'CURL Error:\' . curl_error($ch);
        }
        // 下单成功的话,微信返回个XML,里面包含prepayID,提取出来

        $match=$this->xml_to_array($output);
        //var_dump($match);die;

        if($match[\'result_code\']==\'FAIL\'){
            $result[\'status\']=3;
            $result[\'msg\']=$match[\'err_code_des\'];
            die(json_encode($result));
        }

        // 这里不是给小程序返回个prepayID,而是返回一个包含其他字段的JSON
        // 这个JSON小程序自己也可以生成,放在服务端生成是出于两个考虑:
        // 1. 小程序的appid不用写在小程序的代码里,appid、secret信息全部由服务器管理,比较安全
        // 2. 计算paySign需要用到md5,小程序端使用的是JavaScript,没有内置的md5函数,放在服务端计算md5比较方便

        @$prepayId = $match[\'prepay_id\'];

        if(!$match[\'prepay_id\']){
            $result[\'status\']=4;
            $result[\'msg\']=\'prepay_id为空,请查看具体原因\';
            die(json_encode($result));
        }
        $response= array(
          \'appId\' => $appid,        //小程序appid
          \'nonceStr\' => (string) mt_rand(10000, 99999),          // 随机串,32个字符以内
          \'package\' => (string)\'prepay_id=\' . $prepayId,
          \'signType\' => \'MD5\',
          \'timeStamp\' => (string) time(),          // 时间戳,注意得是字符串形式的
        );
        $sequence = \'\';
        foreach ($response as $key => $value) {
          $sequence .= "$key=$value&";
        }
        $response[\'paySign\'] = strtoupper(md5("{$sequence}key=".$mch_key));


        //$info[\'aaa\']=(string)$prepayId;

        $result[\'status\']=1;
        $result[\'msg\']=\'成功\';
        $result[\'data\']=$response;
        die(json_encode($result));
    }
function callback(){
        $order_id = $_GET[\'goods_id\'];
        
        $result = Db::name(\'\')->where("order_code=\'".$order_id."\'")->update(array(\'pay_status\'=>1,\'order_status\'=>1,\'pay_time\'=>time(),\'pay_id\'=>1,\'pay_name\'=>\'微信\',\'pay_platform\'=>\'小程序支付\'));

        $orderinfo = Db::name("")->field(\'order_amount,add_time\')->where("order_code=\'".$order_id."\'")->find();
        Db::name(\'order_log\')->insert(array(\'order_code\'=>$order_id,\'type\'=>\'小程序微信支付\',\'addtime\'=>date(\'Y-m-d H:i:s\',$orderinfo[\'add_time\']),\'paytime\'=>date(\'Y-m-d H:i:s\',time()),\'order_amount\'=>$orderinfo[\'order_amount\'],\'remark\'=>\'SUCCESS\'));
        $data[\'status\']=1;
        die(json_encode($data));
    }
    function notify($data)
    {
        $inputdata = file_get_contents("php://input");
        if (! empty($inputdata)) {
            
            $payment = model(\'Payment\')->get_payment("wxpay");
            $postdata = json_decode(json_encode(simplexml_load_string($inputdata, \'SimpleXMLElement\', LIBXML_NOCDATA)), true);
            /* 检查插件文件是否存在,如果存在则验证支付是否成功,否则则返回失败信息 */
            // 微信端签名
            $wxsign = $postdata[\'sign\'];
            unset($postdata[\'sign\']);

            // 微信附加参数
            $attach = $postdata[\'attach\'];

            foreach ($postdata as $k => $v) {
                $Parameters[$k] = $v;
            }
            // 签名步骤一:按字典序排序参数
            ksort($Parameters);

            $buff = "";
            foreach ($Parameters as $k => $v) {
                $buff .= $k . "=" . $v . "&";
            }
            $String;
            if (strlen($buff) > 0) {
                $String = substr($buff, 0, strlen($buff) - 1);
            }
            // 签名步骤二:在string后加入KEY
            $String = $String . "&key=" . $payment[\'wxpay_key\'];
            // 签名步骤三:MD5加密
            $String = md5($String);
            // 签名步骤四:所有字符转为大写
            $sign = strtoupper($String);
            // 验证成功
            if ($wxsign == $sign) {
                // 交易成功
                $returndata[\'return_code\'] = \'SUCCESS\';
            } else {
                $returndata[\'return_code\'] = \'FAIL\';
            }
        } else {
            $returndata[\'return_code\'] = \'FAIL\';
            $returndata[\'return_msg\'] = \'无数据返回\';
        }
        // 数组转化为xml
        $xml =$this->arrayToXml($returndata);

        echo $xml;
        exit();       
    }    
    function arrayToXml($arr)
    {

        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        { 
            if (is_array($val)){
                $xml.="<".$key.">".arrayToXml($val)."</".$key.">";
            }else{
                $xml.="<".$key.">".$val."</".$key.">";
            }
        }
        $xml.="</xml>";
        
        return $xml;
    }
    function xml_to_array($xml){
        if(!$xml){
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, \'SimpleXMLElement\', LIBXML_NOCDATA)), true);
        return $data;
    } 

欢迎各位同仁交流~

加油哦~小王

版权声明:本文为wangvv原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/wangvv/p/13646057.html