在开发支付宝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¬ify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2×tamp=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¬ify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2×tamp=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¬ify_url=http://www.game256.com.cn/payapi/paydemo/Notify.html&return_url=http://www.game256.com.cn/payapi/index/paysuccess.html&sign_type=RSA2×tamp=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的后面更新