支付宝H5支付实现 绕过浏览器白名单

在开发支付宝H5支付的时候,遇到了一个很尴尬的问题,无法唤起支付宝APP问题分析:当前浏览器不在支付宝配置的白名单内

市场上的浏览器太多,总有用户会使用不一样的浏览器,就UC浏览器来说,不同版本也有出现不能唤醒支付宝APP来进行支付的时候。如何解决成了我当下的问题。

H5支付唤醒APP,本质上就是通过访问相关协议来达成的。支付宝支付的唤醒协议是 :alipays://platformapi/startApp?appId=20000125&orderSuffix=h5_route_token%3D%xxxxxxxxxxxxxxxxxxxxxxxxxx%22%26is_h5_route%3D%22true%22#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end
 

通过多次测试 ,orderSuffix字段的值是动态的 

 仔细可以发现,orderSuffix字段是urlencode的数据,urldecode后是h5_route_token="RZ42o1v1IQCySIL2FmkTUHzXDylwtFmobilecashierRZ42"&is_h5_route="true"

我的思路是通过访问 alipay.trade.wap.pay(手机网站支付接口) 获取H5支付宝的唤醒页面,然后通过正则表达式获取到orderSuffix字段的内容来拼接唤醒的url,通过iframe加载url来唤醒支付宝APP来实现支付。

  • 首先对获取的url进行处理,使之符合支付宝的正常请求 

// 原接口url            
// $result = 'https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-php-20161101&app_id=2021001165675388&biz_content={"productCode":"QUICK_WAP_PAY","body":"游戏商品","subject":"支付宝在线支付","out_trade_no":"27847720200826155042","total_amount":"0.01","timeout_express":"1m"}&charset=UTF-8&format=json&method=alipay.trade.wap.pay&notify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2&timestamp=2020-08-27 14:07:59&version=1.0&sign=jE4iZWsqrMkI2PW2sK7jMqlJjslzsibSZQ6lewlQreS8WPRGroZ35GPHvk9Vi18NSFms8ilI9JFB6VpNfQgn6LCXIzW4TuUq1vJ5EPM%2FkOt2iK1B15531VMDX4Cy7UZWWeXAhdC9d%2FawFulnZxbu3fT9K5slY%2BJhPInad0nsSFkj%2FY0%2FG02AEXatu7cdtOGbLoanwiXP8R1oCGK6mdTE95h%2BEPDILsrYXlhU83XIcqHzrCse4svbfWTfMhEfpKj3I8ZfcVrPANWvWUWCTrLaS48%2BcE5ww7K59NiqQ3i%2BZN2cszLhCCPUmMH%2FYeme7Gx2dgl701Acuk9l8cj2V%2BDlYg%3D%3D';

                
// 目标接口url      
// $result = 'https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-php-20161101&app_id=2021001165675388&biz_content={%22productCode%22:%22QUICK_WAP_PAY%22,%22body%22:%22%E6%B8%B8%E6%88%8F%E5%95%86%E5%93%81%22,%22subject%22:%22%E6%94%AF%E4%BB%98%E5%AE%9D%E5%9C%A8%E7%BA%BF%E6%94%AF%E4%BB%98%22,%22out_trade_no%22:%2227847720200826155042%22,%22total_amount%22:%220.01%22,%22timeout_express%22:%221m%22}&charset=UTF-8&format=json&method=alipay.trade.wap.pay&notify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2&timestamp=2020-08-27%2014:07:59&version=1.0&sign=jE4iZWsqrMkI2PW2sK7jMqlJjslzsibSZQ6lewlQreS8WPRGroZ35GPHvk9Vi18NSFms8ilI9JFB6VpNfQgn6LCXIzW4TuUq1vJ5EPM%2FkOt2iK1B15531VMDX4Cy7UZWWeXAhdC9d%2FawFulnZxbu3fT9K5slY%2BJhPInad0nsSFkj%2FY0%2FG02AEXatu7cdtOGbLoanwiXP8R1oCGK6mdTE95h%2BEPDILsrYXlhU83XIcqHzrCse4svbfWTfMhEfpKj3I8ZfcVrPANWvWUWCTrLaS48%2BcE5ww7K59NiqQ3i%2BZN2cszLhCCPUmMH%2FYeme7Gx2dgl701Acuk9l8cj2V%2BDlYg%3D%3D';
                
            $params_str = str_replace('https://openapi.alipay.com/gateway.do?', '', $result);
            parse_str($params_str, $arr);
            // $arr['biz_content'] = $arr['biz_content'];
            // $arr = http_build_query($arr);
            $params = [];
            $entities = array('%7B','%3A','%2C','%7D','%2F','+',);
            $replacements = array('{',':',',','}','/','%20',);
            foreach($arr as $key => $val) {
                if(in_array($key, ['biz_content', 'timestamp', 'sign'])) {
                    $val = str_replace($entities, $replacements, urlencode($val));
                }
                if($key == 'sign') {
                    $val = str_replace('/', '%2F', $val);
                }
                $params[] = $key.'='.$val;
            }
            $path = '/gateway.do?'.join('&', $params);

            $result= 'https://openapi.alipay.com'.$path;
  •  进行curl请求,这里请求的时候需要注意三个问题,1:支付宝特殊的请求头,2:是302跳转,3:是https加密数据的获取

            $result= 'https://openapi.alipay.com'.$path;

            // dump($result);
            // $path = '/gateway.do?alipay_sdk=alipay-sdk-php-20161101&app_id=2021001165675388&biz_content={%22productCode%22:%22QUICK_WAP_PAY%22,%22body%22:%22%E6%B8%B8%E6%88%8F%E5%95%86%E5%93%81%22,%22subject%22:%22%E6%94%AF%E4%BB%98%E5%AE%9D%E5%9C%A8%E7%BA%BF%E6%94%AF%E4%BB%98%22,%22out_trade_no%22:%2227847720200826155042%22,%22total_amount%22:%220.01%22,%22timeout_express%22:%221m%22}&charset=UTF-8&format=json&method=alipay.trade.wap.pay&notify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2&timestamp=2020-08-27%2011:52:06&version=1.0&sign=fX60K9esyL0IRIuwCr7ecQSYvaBdihGa%2BbDtfA8PnBBnIHKyoln4ojCpnWL6W8YbCKbsFylcUCs302261JSfMgtg1RcIPZ4tgnGKkWdgDUTRx4s4smX5UsgMtkRuigcytA4cwzZ0UnERozF0BwC5AXwMhIkDqTxOUO%2BznfvODdCt6fjTCr5zjzJwAmfwcrf3wZIlATUDQBW8HHue9TTMRucAmapn5QhtRovKIb4F1i2wvttG4qvFSG6PZalyDEGgweDYUdEpobYYEjNbaXglAM2Bk8zOuYvNMfHBtRjNEjfLhE1%2Fzo1RJ1MjQagFwWghqHcebdyAcyMN2N%2FM%2BygqIQ%3D%3D';
            // dump($path);die;
            $cookie = '';
            // $cookie = 'ALIPAYJSESSIONID=GZ00KyPQiHFziO5OfaaavPp9p7AgvXsuperapiGZ00; awid=RZ42E27N4bI1nV6rTI4aWHDqaBwsejmobileclientgwRZ42; ctoken=pJaVM8Rj2r64glGJ; JSESSIONID=0D9A8FED7AC720067FC963498A75404D; spanner=uB7iE1BtqE6wK+oapYREsseb1+G8O+INXt2T4qEYgj0=; zone=RZ42B';
            $header = [
                'authority: openapi.alipay.com',
                'method: GET',
                'path: '.$path,
                'scheme: https',
                'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'accept-encoding: gzip, deflate, br',
                'accept-language: zh-CN,zh;q=0.9',
                'cookie: '.$cookie,
                'sec-fetch-dest: document',
                'sec-fetch-mode: navigate',
                'sec-fetch-site: none',
                'sec-fetch-user: ?1',
                'upgrade-insecure-requests: 1',
                'user-agent: Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Mobile Safari/537.36',
            ];

            // dump($header);

            // $url = 'http://auto.jrj.com.cn/';
            $url = $result;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            //若给定url自动跳转到新的url,有了下面参数可自动获取新url内容:302跳转
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            //设置cURL允许执行的最长秒数。
            // curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            // curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0');
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            
            //设置获取的信息以文件流的形式返回,而不是直接输出。
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

            // 解释gzip内容
            curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
            
            $content = curl_exec($ch);
            //获取请求返回码,请求成功返回200
            $code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
            // echo $code . "\n\n";

            //获取一个cURL连接资源句柄的信息。(is_h5_route=\"true\")
            //$headers 中包含跳转的url路径 
            $headers = curl_getinfo($ch);
            $content = $this->strToUtf8($content);
            preg_match('/{"requestType"(.*)is_h5_route=\D\Dtrue\D\D\D}/', $content, $matches);
            // var_dump($isMatched, $matches);
            // dump('alipay://alipayclient/?'.urlencode($matches[0]));
            $params = json_decode($matches[0]);
            // dump($params);die;
            $o['android'] = urlencode($params->dataString);
            // dump($o);
            $alipay_url = 'alipays://platformapi/startApp?appId=20000125&orderSuffix=' . $o['android'] .'#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end';
           

 目前就实现了安卓的唤醒协议生成和拼接,IOS的后面更新

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值