1. 程式人生 > >PHP+H5微信小程式webview巢狀H5支付(公司專案筆記)

PHP+H5微信小程式webview巢狀H5支付(公司專案筆記)

1.h5轉後臺

mui.openWindow({
                    url: "轉向後臺的網址/doMiniPay?payMoney=" + n + "&buyContent=" + buyContent + "&uid=" + uid,
                    waiting: {
                        autoShow: true, //自動顯示等待框,預設為true
                        title: '正在載入支付頁面......', //等待對話方塊上顯示的提示內容
                    }

                })

  • url:轉向後臺的網址

  • payMoney:支付金額

  • buyContent:支付說明 舉例:XXX公司充值

  • uid:使用者id 用於將下單寫入資料庫

2.跳轉小程式獲取code 

// 小程式webview支付
    public function doMiniPay()
    {
//        $oid = I("oid");
        $oid = $this->getOrderId();
        $payjs = "
            <script type='text/javascript' src='https://res.wx.qq.com/open/js/jweixin-1.3.2.js'></script>
            <script type='text/javascript'>
            wx.miniProgram.getEnv(function(res) {
                if (res.miniprogram) {
                    // 走在小程式的邏輯
                    var params = '?oid=" . $oid . "';
                    var path = '/pages/wxPay/wxPay'+params;
                    //document.write(params);
                    wx.miniProgram.navigateTo({url: path});
                }
            });
            </script>
          ";
        echo $payjs;
    }

  • getOrderId方法為獲取隨機數方法
public function getOrderId($uid)
    {
        //日期:10位 timestamp
        $datetime = time();
        //隨機數
        $newnum = $this->getNonceNums();
        return $datetime . $newnum;
    }

3.小程式端獲取code 向後臺請求獲取openid

 

var app = getApp()
Page({

  onLoad: function (options) {
    var that = this
    wx.setStorageSync('oid', options.oid);
    wx.login({
      success: function (res) {
        // 成功的話會返回:
        // {errMsg: "login:ok", code: "獲取使用者OpenID的ticket"}
        that.getOpenId(res.code)
      }
    })
  },
  getOpenId: function (jsCode) {
    var that = this
    wx.request({
      url: '後臺獲取openid方法的網址login方法',
      data: {
        js_code: jsCode // wx.login()時得到的ticket
      },
      success: function (res) {
        that.getPrePayId(res.data.openid)
      }
    })
  },
})

4.後端獲取openid方法

 //小程式支付後端
    public function login()
    {
        $params['appid'] = '';// 小程式的appID
        $params['secret'] = '';//小程式的appsecret
        $params['js_code'] = $_GET['js_code'];

//      測試用的將值寫入文件  
// file_put_contents('./lilllsss.txt',$_GET['js_code'],FILE_APPEND);

        $params['grant_type'] = 'authorization_code';


        $urls = "https://api.weixin.qq.com/sns/jscode2session?appid=".$params['appid']."&secret=".$params['secret']."&grant_type=authorization_code&js_code=".$params['js_code']."";

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $urls);
        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;

    }

5.小程式方法拿著openid請求prepayid並進行下單

 getPrePayId: function (openId) {
    var that = this
    wx.request({
      url: '後臺wxpay方法獲取prepayid',
      data: {
        openid: openId,
        oid: wx.getStorageSync('oid')
      },
      success: function (res) {
        that.pay(res.data);
      }
    })
  },
  pay: function (data) {
    var that = this
    data.success = function (res) {
      that.payOver()
    }
    data.fail = function (res) {
      that.payOver()
    }
    wx.requestPayment(data)
  },

  payOver: function () {
    wx.reLaunch({
      url: '/pages/index/index?oid=' + wx.getStorageSync('oid')
    })
  }

6.後臺下單 微信返回xml資訊 將xml資訊解析取到prepayid 打包資料返回給小程式端

// 小程式支付後端
    public function wxpay(){
        $oid = I("oid");
        $dao = M();
//        $sql = "這裡是去訂單資訊的sql";
//        $orderRs = $dao->query($sql);

        $weiXin = new Weixin();

        $param['appid']             = '小程式的appid';
        $param['mch_id']            = "商戶號";
        $param['nonce_str']         = $weiXin->getNonceNum();// 隨機字串
        $param['body']              = "糧多多充值";
        $param['out_trade_no']      = $this->getOrderId();//隨機數+時間生成訂單號
        $param['total_fee']         = 1;//支付金額
        $param['spbill_create_ip']  = $_SERVER['REMOTE_ADDR'];
        $param['notify_url']        = 'https://luoluotech.com/lddServer/pay/PayNotify.php';
        $param['trade_type']        = "JSAPI"; //H5 支付型別
        $param['openid']        = $_GET['openid'];



        // 按照要求計算sign

//        file_put_contents('./ldsdasdqweqwd.txt',$sequence,FILE_APPEND);
        ksort($param);
        $sequence = '';
        foreach ($param as $key => $value) {
            $sequence .= "$key=$value&";
        }

//        file_put_contents('./ldsdhiudsadqweqweqwd.txt',$sequence,FILE_APPEND);

        $apikey = "key商戶平臺自己設定的";// 這個是手動設定的

        $sequence = $sequence ."key=$apikey";
//        file_put_contents('./ldsddasdqwessfd.txt',$sequence,FILE_APPEND);
        $param['sign'] = strtoupper(md5($sequence));
//        file_put_contents('./ldsdhirethbgfb.txt',$param['sign'],FILE_APPEND);
        // 給微信發出的請求,整個引數是個XML

        $xml = '<xml>' . PHP_EOL;
        foreach ($param as $key => $value) {
            $xml .= "<$key>$value</$key>" . PHP_EOL;
        }
        $xml .= '</xml>';


        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $output = curl_exec($ch);



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

        // 下單成功的話,微信返回個XML,裡面包含prepayID,提取出來 <prepay_id><![CDATA[這個就是我們要的值]]></prepay_id>

        if (0 === preg_match('/<prepay_id><\!\[CDATA\[(\w+)\]\]><\/prepay_id>/', $output, $match)) {
            echo $output;
            exit(0);
        }
        file_put_contents('./ldadsadqweqewdsdggdfggfb.txt',$output,FILE_APPEND);

        $weiXin = new Weixin();
        $prepayId = $match[1];
        $response['appId'] = '小程式appid';
        $response['nonceStr'] = $weiXin->getNonceNum();
        $response['package'] = 'prepay_id=' . $prepayId;
        $response['signType'] = 'MD5';
        $response['timeStamp'] =  (string) time();
        $sequence = '';
        foreach ($response as $key => $value) {
            $sequence .= "$key=$value&";
        }
        $response['paySign'] = strtoupper(md5("{$sequence}key=手動設定的商戶key"));

        echo json_encode($response);
    }

7.小程式調起微信支付

pay: function (data) {
    var that = this
    data.success = function (res) {
      that.payOver()
    }
    data.fail = function (res) {
      that.payOver()
    }
    wx.requestPayment(data)
  },

  payOver: function () {
    wx.reLaunch({
      url: '/pages/index/index?oid=' + wx.getStorageSync('oid')
    })
  }