当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP实现一个二维码同时支持支付宝和微信支付的示例

发布:smiling 来源: PHP粉丝网  添加日期:2022-04-12 08:41:15 浏览: 评论:0 

实现思路

生成一个二维码,加入要处理的url连接

在用户扫完码后,在对应的脚本中,判断扫码终端,调用相应的支付

若能够扫码之后能唤起相应app,支付宝要用手机网站支付方式,微信要使用jsapi支付方式

效果展示

PHP实现一个二维码同时支持支付宝和微信支付的示例

提示: 因为项目即将上线,所以上面的支付二维码连接被我替换了(注意在生成二维码时加入的连接,要带上http协议)

PHP实现一个二维码同时支持支付宝和微信支付的示例

PHP实现一个二维码同时支持支付宝和微信支付的示例

实现

步骤生成二维码

  1. //我的url指向了checkTerrace方法 
  2. $url  = self::ADMIN_URL . 'params=' . $params;  
  3. //ADMIN_URL是生成二维码的url,请替换成自己 

处理用户扫码操作(checkTerrace方法)

  1. public function checkTerrace() 
  2.   { 
  3.    $pay_type = $this->getPayType(); //该方法使用来判断用户扫码终端的 
  4.    $params  = $this->request->get('params'); //生成二维码url带的参数(看个人需求,我的项目需要额外参数) 
  5.    $params  = $this->desDecode($params); //这里是因为我对参数进行了desc加密,看个人需求 
  6.    if ($pay_type === 'alipay') { //如果用户是通过支付宝扫码,进行支付宝相关操作 
  7.        if ($params === false) { 
  8.          echo "系统错误!,请稍后重试"
  9.          exit
  10.        } 
  11.        $res = $this->createOrder($pay_type$params); 
  12.        if (!$res) { 
  13.          echo "系统错误,请稍后重试"
  14.          exit
  15.        } 
  16.        $this->aliPay($res); 
  17.    } elseif ($pay_type === 'wechat') { //如果用户是通过微信扫码,进行微信相关操作 
  18.        if ($params === false) { 
  19.          echo "系统错误,请稍后重试"
  20.          exit
  21.        } 
  22.        $prepare = $this->wechat($pay_type$params); 
  23.        $this->assign('json'$prepare); 
  24.        return $this->display('wpay.html'); 
  25.    } elseif ($pay_type === false) { 
  26.        echo "请使用支付宝或微信进行扫码"
  27.        exit
  28.    } 
  29.  } 

判断扫码终端

  1. /** 
  2.  * 判断扫码终端 
  3.  * 
  4.  * @return string|boolean 
  5.  * @date 2021-02-04 
  6.  */ 
  7.  private function getPayType() 
  8.  { 
  9.    if (strstr($_SERVER['HTTP_USER_AGENT'], 'AlipayClient')) { 
  10.      return "alipay"
  11.    } elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')) { 
  12.      return "wechat"
  13.    } else { 
  14.      return false; 
  15.    } 
  16.  } 

生成订单

  1. /** 
  2.  * 生成订单 
  3.  * 
  4.  * @param string $pay_type 
  5.  * @param json $params 
  6.  * @return void 
  7.  * @date 2021-02-04 
  8.  */ 
  9. //这个逻辑就不贴代码了 
  10. private function createOrder($pay_type$params
  11.   /*生成订单相关逻辑代码*/ 

支付宝支付

  1. /** 
  2.    * 唤起支付宝app 
  3.    * 
  4.    * @param array $api_params 
  5.    * @return void 
  6.    * @date 2021-02-04 
  7.    */ 
  8.   private function aliPay($api_params
  9.   { 
  10.     $config = [ 
  11.       'notify_url'     => '异步回调地址'
  12.       'is_open_certificate' => true 
  13.     ]; 
  14.     $domain = urlencode($api_params['domain']); 
  15.     $api = [ 
  16.       'out_trade_no'  => $api_params['trade_no'], 
  17.       'total_amount'  => '0.01'
  18.       'subject'     => '商品标题'
  19.       'passback_params' => $domain 
  20.     ]; 
  21.     $pay = new Pay($config);  
  22.     $res = $pay->driver('alipay')->gateway('wap')->pay($api); //调用支付宝手机网站支付 
  23.     echo $res
  24.   } 

微信支付

  1. /** 
  2.    * 唤起微信app  
  3.    * 
  4.    * @return void 
  5.    * @date 2021-02-04 
  6.    */ 
  7.   public function wechat($pay_type$params
  8.   { 
  9.     $opend_id = $this->getOpenId(); //处理微信jsapi支付之前,要先获取用户的openID 
  10.     if (!$opend_id) { 
  11.       echo "微信授权失败..."
  12.       exit
  13.     } 
  14.     $api_params = $this->createOrder($pay_type$params); //用户openID获取成功后才进行订单生产操作 
  15.     if (!$api_params) { 
  16.       echo "系统错误,请稍后重试"
  17.       exit
  18.     } 
  19.     $config = ['notify_url'  => '微信异步回调地址']; 
  20.     $api  = [ 
  21.       'body'     => '我是标题'
  22.       'out_trade_no' => $api_params['trade_no'], 
  23.       'total_fee'  => 1,   
  24.       'openid'    => $opend_id
  25.       'attach'    => $api_params['domain'
  26.     ]; 
  27.     $pay = new Pay($config); 
  28.     $res = $pay->driver('wechat')->gateway('mp')->pay($api); //调用微信jsapi支付 
  29.     return $res
  30.   } 

静默获取openID

  1. /** 
  2.    * 获取用户的openid 
  3.    * 
  4.    * @return void 
  5.    * @date 2021-02-04 
  6.    */ 
  7.   public function getOpenId() 
  8.   { 
  9.     if (isset($_SESSION['open_id']) && $_SESSION['open_id']) { 
  10.       return $_SESSION['open_id']; 
  11.     } 
  12.     if (!$this->request->get('code')) { 
  13.       $redirect_uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //这里授权后微信跳转的地址,要写在订单处理处,否则会造成因为程序跳转到微信授权页面,导致脚本逻辑终止 
  14.       $redirect_uri = urlencode($redirect_uri); 
  15.       $url = $this->codeUrl . 'redirect_uri=' . $redirect_uri . '&appid=' . $this->appId . '&scope=snsapi_base&response_type=code&state=STATE#wechat_redirect'//使用用户静默授权模式(因为我不需要获取用户信息所有就没采用用户手段授权模式) 
  16.       header("location:{$url}"); //跳转到微信授权页面 
  17.     } else { 
  18.       $openidurl = $this->openidUrl . 'appid=' . $this->appId . '&secret=' . $this->appSecret . '&code=' . $this->request->get('code') . '&grant_type=authorization_code'
  19.       $data = Http::get($openidurl); 
  20.       $data = json_decode($data, true); 
  21.       if ($data['openid']) {  
  22.         $_SESSION['open_id'] = $data['openid']; //获取到的用户openID存储到session中 
  23.       } else { 
  24.         $_SESSION['open_id'] = false; 
  25.       } 
  26.       return $_SESSION['open_id']; 
  27.     } 
  28.   } 

前端轮询判断监听订单支付状态

  1. $(function() { 
  2.  
  3.       $("#code").qrcode({ 
  4.  //jQuery生成二维码 
  5.         width: 165, //宽度 
  6.         height: 167, //高度 
  7.         text: $('input[name="url"]').val()  
  8.       }); 
  9.       var startTime = Date.parse(new Date())/1000; 
  10.       //设置定时器 
  11.       var poll_request = setInterval( function() { 
  12.           $.ajax({ 
  13.             url: '/company/StoreSetting/checkStatus'
  14.             data:{time:startTime}, 
  15.             dataType:'json'
  16.             type:'get'
  17.             success:function(res) { 
  18.               if (res.code == 400) { 
  19.                 var result = clearTimer(poll_request, startTime); 
  20.                 if (result) { 
  21.                   var html = `<img src="/Static/images/paybg.png">`+ 
  22.                         `<div class="notify" id="notify">`+ 
  23.                         `<img src="/Static/images/pay_time_out.png" alt="">`+ 
  24.                         `<span class="pay_tip">点击重新获取</span>`+ 
  25.                         `</div>`; 
  26.                   $('.qrcode-img').emptyempty(); 
  27.                   $('.qrcode-img').append(html); 
  28.                 } 
  29.               } else if(res.code == 500) { 
  30.                 var html = `<img src="/Static/images/paybg.png">`+ 
  31.                         `<div class="notify">`+ 
  32.                         `<img src="/Static/images/pay_error.png" alt="">`+ 
  33.                         `<span class="pay_tip">已扫码<br>请在手机端操作</span>`+ 
  34.                         `</div>`; 
  35.                 $('.qrcode-img').emptyempty(); 
  36.                 $('.qrcode-img').append(html); 
  37.                 clearTimer(poll_request, startTime); 
  38.               } else if(res.code == 200) { 
  39.                 clearInterval(poll_request) 
  40.                 layer.msg("支付成功", {icon:6}, function() { 
  41.                   window.location.reload() 
  42.                 }) 
  43.                 // layer.msg("支付成功", {icon:6}, function() { 
  44.                     
  45.                 // }) 
  46.               } 
  47.             } 
  48.           }) 
  49.       }, 2000); 
  50.     }) 
  51.     function clearTimer(index, startTime) { 
  52.       if (((Date.parse(new Date())/1000) - startTime) > 60) { 
  53.         clearInterval(index) 
  54.         return 'reload'
  55.       } 
  56.       return false; 
  57.     } 
  58.     //刷新二维码 
  59.     $('.qrcode-img').on("click"'#notify'function() { 
  60.       $('.qrcode-img').emptyempty() 
  61.       $("#code").qrcode({ 
  62.         width: 165, //宽度 
  63.         height: 167, //高度 
  64.         text: $('input[name="url"]').val()  
  65.       }); 
  66.       var startTime = Date.parse(new Date())/1000; 
  67.       var poll_request = setInterval( function() { 
  68.           $.ajax({ 
  69.             url: '/company/StoreSetting/checkStatus'
  70.             data:{time:startTime}, 
  71.             dataType:'json'
  72.             type:'get'
  73.             success:function(res) { 
  74.               if (res.code == 400) { 
  75.                 var result = clearTimer(poll_request, startTime); 
  76.                 if (result) { 
  77.                   var html = `<img src="/Static/images/paybg.png">`+ 
  78.                         `<div class="notify" id="notify">`+ 
  79.                         `<img src="/Static/images/pay_time_out.png" alt="">`+ 
  80.                         `<span class="pay_tip">点击重新获取</span>`+ 
  81.                         `</div>`; 
  82.                   $('.qrcode-img').emptyempty(); 
  83.                   $('.qrcode-img').append(html); 
  84.                 } 
  85.               } else if(res.code == 500) { 
  86.                 var html = `<img src="/Static/images/paybg.png">`+ 
  87.                         `<div class="notify">`+ 
  88.                         `<img src="/Static/images/pay_error.png" alt="">`+ 
  89.                         `<span class="pay_tip">已扫码<br>请在手机端操作</span>`+ 
  90.                         `</div>`; 
  91.                 $('.qrcode-img').emptyempty(); 
  92.                 $('.qrcode-img').append(html); 
  93.                 clearTimer(poll_request, startTime); 
  94.               } else if(res.code == 200) { 
  95.                 clearInterval(poll_request) 
  96.                 layer.msg("支付成功", {icon:6}, function() { 
  97.                   window.location.reload() 
  98.                 }) 
  99.                 // layer.msg("支付成功", {icon:6}, function() { 
  100.                     
  101.                 // }) 
  102.               } 
  103.             } 
  104.           }) 
  105.       }, 2000);  
  106.     }) 

前端效果:

用户进入支付页面但是一直为扫码,超过一定时间

PHP实现一个二维码同时支持支付宝和微信支付的示例

用户扫码后一直未进行支付,超过一定时间。

PHP实现一个二维码同时支持支付宝和微信支付的示例

Tags: PHP支持支付宝微信支付

分享到: