微信小程序获取手机号 前台+php后台

两个部分三个位置,前台加后台,前台分为js+wxml

前端

wxml

<button class='bottom' open-type="getPhoneNumber"  bindgetphonenumber="getphonenumber"   >
    授权登录
</button>

js:需要修改两个请求连接

// pages/demo/demo.js
Page({
    
    
  getphonenumber: function (e) {
    
    
    if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
    
    
      wx.showModal({
    
    
        title: '提示',
        showCancel: false,
        content: '未授权',
        success: function (res) {
    
    }
      })
    } else {
    
    
      //调用接口获取登录凭证
      wx.login({
    
    
        success: function (res) {
    
    
          //获取到的code
          var code = res.code;
          if (!code) {
    
    
            console.log('获取用户登录态失败!' + res.errMsg)
          }
          //获取opendi、session_key
          wx.request({
    
    
            url: 'htt son/wei/v1/getopenid',
            method: 'POST',
            data: {
    
    
              code: code,
            },
            header: {
    
    
              'content-type': 'application/json'
            },
            success: function (res) {
    
    
              wx.setStorageSync('openid', res.data.openid);

              var encryptedData = e.detail.encryptedData
              var iv = e.detail.iv
              var se_key = res.data.session_key
              console.log(res);
              //换取手机号
              wx.request({
    
    
                url: 'https    wp-json/wei/v1/getphone',
                method: 'POST',
                data: {
    
    
                  // 必须,获取手机号
                  encryptedData: encryptedData,
                  iv: iv,
                  session_key: se_key,
                  // 修改数据库所需
                  uid:3
                },
                header: {
    
    
                  'Content-Type': 'application/x-www-form-urlencoded'
                },
                method: 'POST',
                success: function (res) {
    
    
                  console.log(res);
                  /* 
                 每个人都不同
				countryCode: "86"  
				phoneNumber: "123"
				purePhoneNumber: "7823"
				watermark: {timestamp: 16175702, appid: "wxa0fe31"}
                 
                 */
                }
              })
            },
          });
        }
      });
    }
  },

})

后台

封装了三个功能:

  1. 获取openid+session_key
  2. 获取用户手机号
  3. 支付

需要修改 __construct里的内容,支付需要所有信息获取完全

<?php


// include "PHP/wxBizDataCrypt.php";

class Wei_user_controller extends WP_REST_Controller
{
    
    

  public function register_routes()
  {
    
    

    register_rest_route("wei/v1", '/' . "pay", array(
      array(
        'methods'         => "post",
        'callback'        => array($this, 'pay_fn'),

      )
    ));
    register_rest_route("wei/v1", '/' . "getopenid", array(
      array(
        'methods'         => "POST",
        'callback'        => array($this, 'getopenid_fn'),

      )
    ));
    register_rest_route("wei/v1", '/' . "getphone", array(
      array(
        'methods'         => "POST",
        'callback'        => array($this, 'getphone_fn'),

      )
    ));
  }
  // 小程序付款
  public function pay_fn($request)
  {
    
    
    $params = $request->get_params();
    $aaa = new Wx_app;
    $res = $aaa->pay($params['code']);
    return $res;
  }
  //换取手机号
  public function getphone_fn($request)
  {
    
    
    $params = $request->get_params();
    $aaa = new Wx_app;
    $data = $aaa->get_phone($params['session_key'], $params['encryptedData'], $params['iv']);

    if (isset($data->phoneNumber)) {
    
    
      global $wpdb;
      $phone  = $data->phoneNumber;
      $sql = "UPDATE wp_usermeta SET meta_value='{
      
      $phone}' WHERE user_id={
      
      $params['uid']} and meta_key='user_phone'";
      $res2 = $wpdb->query($sql);
      return $data;
    }
  }
  //获取openid、session_key
  public function getopenid_fn($request)
  {
    
    

    $params = $request->get_params();
    $aaa = new Wx_app;
    $res = $aaa->get_openid($params['code']);
    return $res;
  }
}



  
class Wx_app
{
    
    
  public function __construct()
  {
    
    
    $this->mchid = '14 022'; //https://pay.weixin.qq.com 产品中心-开发配置-商户号
    $this->apiKey = 'lnh asrvjw';   //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
    $this->appid = "w e31";   /* 小程序appid */
    $this->appSecret  = "d5 c";/* 小程序AppSecret */

    // //回调的url【自己填写】, 付款
    $this->notify_url = '回调/notify.php';
  }



  // 功能1 :获取openid、session_key
  public function  get_openid($code)
  {
    
    
    $code = $code;
    $WX_APPID =  $this->appid; //appid
    $WX_SECRET =   $this->appSecret; //AppSecret
    $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $WX_APPID . "&secret=" . $WX_SECRET . "&js_code=" . $code . "&grant_type=authorization_code";
    $infos = json_decode(file_get_contents($url));
    return $infos;
  }
  // 功能2,获取电话
  public function get_phone($sessionKey, $encryptedData, $iv)
  {
    
    
    $appid =  $this->appid;
    $data = $this->decryptData($encryptedData, $iv, $sessionKey, $appid);
    $res = json_decode($data);
    return $res;
  }






  // 功能3,微信支付
  public function pay($code)
  {
    
    

    $fee = 0.01; //举例支付0.01
    $appid =        $this->appid; //这里填写公众号appiid的话会显示 appid和openid不匹配 ,解决方法 添加特约商户号关联起来,在商户号后台关联小程序即可,调用时候使用小程序的appid
    $body =         '标题';
    $mch_id =       $this->mchid;  //商户号
    $nonce_str =    $this->nonce_str(); //随机字符串
    $notify_url =    $this->notify_url;
    $openid =        $this->get_openid($code)->openid;
    $out_trade_no = $this->order_number($openid); //商户订单号
    $spbill_create_ip = '127.0.0.1'; //服务器的ip【自己填写】;
    $total_fee =    $fee * 100; // 微信支付单位是分,所以这里需要*100
    $trade_type = 'JSAPI'; //交易类型 默认


    //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
    $post['appid'] = $appid;
    $post['body'] = $body;
    $post['mch_id'] = $mch_id;
    $post['nonce_str'] = $nonce_str; //随机字符串
    $post['notify_url'] = $notify_url;
    $post['openid'] = $openid;
    $post['out_trade_no'] = $out_trade_no;
    $post['spbill_create_ip'] = $spbill_create_ip; //终端的ip
    $post['total_fee'] = $total_fee; //总金额 
    $post['trade_type'] = $trade_type;
    // $sign1 = $this->sign($post); //签名
    $sign = self::getSign($post,  $this->apiKey);
    $post_xml = '<xml>
                    <appid>' . $appid . '</appid>
                    <body>' . $body . '</body>
                    <mch_id>' . $mch_id . '</mch_id>
                    <nonce_str>' . $nonce_str . '</nonce_str>
                    <notify_url>' . $notify_url . '</notify_url>
                    <openid>' . $openid . '</openid>
                    <out_trade_no>' . $out_trade_no . '</out_trade_no>
                    <spbill_create_ip>' . $spbill_create_ip . '</spbill_create_ip>
                    <total_fee>' . $total_fee . '</total_fee>
                    <trade_type>' . $trade_type . '</trade_type>
                    <sign>' . $sign . '</sign>
                    </xml> ';
    //统一接口prepay_id
    $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    $xml = $this->http_request($url, $post_xml);  //发送请求
    $array = $this->xml($xml); //全要大写
    // print_r($array); // print_r($xml); die();
    /*  */

    if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
    
    
      $time = time();
      $tmp = []; //临时数组用于签名
      $tmp['appId'] = $appid;
      $tmp['nonceStr'] = $nonce_str;
      $tmp['package'] = 'prepay_id=' . $array['PREPAY_ID'];
      $tmp['signType'] = 'MD5';
      $tmp['timeStamp'] = "$time";

      $data['state'] = 200;
      $data['timeStamp'] = "$time"; //时间戳
      $data['nonceStr'] = $nonce_str; //随机字符串
      $data['signType'] = 'MD5'; //签名算法,暂支持 MD5
      $data['package'] = 'prepay_id=' . $array['PREPAY_ID']; //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
      $data['paySign'] =  self::getSign($tmp,  $this->apiKey); //签名,具体签名方案参见微信公众号支付帮助文档;
      $data['out_trade_no'] = $out_trade_no;
    } else {
    
    
      $data['state'] = 0;
      $data['text'] = "错误";
      $data['RETURN_CODE'] = $array['RETURN_CODE'];
      $data['RETURN_MSG'] = $array['RETURN_MSG'];
    }


    echo json_encode($data);
  }


  //授权
  public function decryptData($encryptedData, $iv, $sessionKey, $appid)
  {
    
    
    if (strlen($sessionKey) != 24) {
    
    
      return 41001;
    }
    $aesKey = base64_decode($sessionKey);


    if (strlen($iv) != 24) {
    
    
      return 41002;
    }
    $aesIV = base64_decode($iv);

    $aesCipher = base64_decode($encryptedData);

    $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

    $dataObj = json_decode($result);
    if ($dataObj  == NULL) {
    
    
      return 41003;
    }
    if ($dataObj->watermark->appid != $appid) {
    
    
      return 41004;
    }
    $data = $result;
    return $data;
  }

  //随机32位字符串
  private function nonce_str()
  {
    
    
    $result = '';
    $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
    for ($i = 0; $i < 32; $i++) {
    
    
      $result .= $str[rand(0, 48)];
    }
    return $result;
  }



  //生成订单号
  private function order_number($openid)
  {
    
    
    //date('Ymd',time()).time().rand(10,99);//18位
    return md5($openid . time() . rand(10, 99)); //32位
  }



  //签名 $data要先排好顺序
  private function sign($data)
  {
    
    
    $stringA = '';
    foreach ($data as $key => $value) {
    
    
      if (!$value) continue;
      if ($stringA) $stringA .= '&' . $key . "=" . $value;
      else $stringA = $key . "=" . $value;
    }
    $wx_key = ''; //申请支付后有给予一个商户账号和密码,登陆后自己设置的key
    $stringSignTemp = $stringA . '&key=' . $wx_key;
    return strtoupper(md5($stringSignTemp));
  }
  // 获取签名
  public static function getSign($params, $key)
  {
    
    
    ksort($params, SORT_STRING);
    $unSignParaString = self::formatQueryParaMap($params, false);
    $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    return $signStr;
  }
  protected static function formatQueryParaMap($paraMap, $urlEncode = false)
  {
    
    
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v) {
    
    
      if (null != $v && "null" != $v) {
    
    
        if ($urlEncode) {
    
    
          $v = urlencode($v);
        }
        $buff .= $k . "=" . $v . "&";
      }
    }
    $reqPar = '';
    if (strlen($buff) > 0) {
    
    
      $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
  }
  //curl请求
  public function http_request($url, $data = null, $headers = array())
  {
    
    
    $curl = curl_init();
    if (count($headers) >= 1) {
    
    
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    }
    curl_setopt($curl, CURLOPT_URL, $url);


    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);


    if (!empty($data)) {
    
    
      curl_setopt($curl, CURLOPT_POST, 1);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
  }


  //获取xml
  private function xml($xml)
  {
    
    
    $p = xml_parser_create();
    xml_parse_into_struct($p, $xml, $vals, $index);
    xml_parser_free($p);
    $data = [];
    foreach ($index as $key => $value) {
    
    
      if ($key == 'xml' || $key == 'XML') continue;
      $tag = $vals[$value[0]]['tag'];
      $value = $vals[$value[0]]['value'];
      $data[$tag] = $value;
    }
    return $data;
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_44797182/article/details/113239831
今日推荐