h5內嵌微信小程序,調用微信支付功能


在小程序中不能使用之前在瀏覽器中配置的支付功能,只能調用小程序專屬的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;
    } 

歡迎各位同仁交流~

加油哦~小王


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM