iOS支付功能篇:原生WebView调起支付宝客户端支付方案
产品需求:
使用iOS原生WKWebView加载H5调起支付宝客户端进行支付的功能实现。
资源
后台提供H5支付接口
e.g : https://qr.alipay.com/bax06385q32ssucugqxm00f1
开发历程
####1. 安卓直接webView加载上面的URL直接可完成跳转支付宝弹出支付界面;
####2. iOS WKWebView加载这个URL,只是单纯加载,无法实现跳转;
####3. 使用Safari浏览器加载该URL,直接提示打开,如下图(这里由于一个订单只有一个小时的待付款时间限制,否则会失效,如果这里没有失效,会打开让您支付的页面):
####4. 第三步说明这个地址是OK的,使用原生webView为什么不能实现跳转呢?
初步思路这样的:dataStr就是服务器响应后的支付宝需要的参数,我想,带上参数跳转过去应该问题不大吧?跳转是成功的但是还是无法弹出支付的页面(这里理解成识别结果页面就可,未识别)
// 在收到响应开始加载后,决定是否跳转
– (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@”alipay://alipayclient/?%@”,navigationResponse.response.URL.absoluteString]] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
}];
WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
//这句是必须加上的,不然会异常
decisionHandler(actionPolicy);
}
####5. 很是纠结,我试着复制出来Safari浏览器的内容看看什么样的格式。
格式如下:
https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-othe
一顿分析后,我试着直接用这个地址跳转:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@”alipay://alipayclient/?%@”, @”https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-othe”]] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
}];
以上想法也是够傻的,再仔细看看,像下面这样就成功了。
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@”alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-othe”] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
}];
6.断点调试,打印服务器返回的信息
我打印了一下 navigationResponse.response.URL.absoluteString 这个东西是什么玩意?好吧,是经过URLEncode的。如下:
https%3a%2f%2fds.alipay.com%2f%3ffrom%3dmobilecodec%26scheme%3dalipays%3a%2f%2fplatformapi%2fstartapp%3fsaId%3d10000007%26clientVersion%3d3.7.0.0718%26qrcode%3dhttps%25253A%25252F%25252Fqr.alipay.com%25252Fbax041244dd0qf8n6ras805b%25253F_s%25253Dweb-other
在线URLCode解码: http://tool.chinaz.com/tools/urlencode.aspx
解码后:
https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-other
#####完结。
成功实现代码
加载URL代码
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@”https://qr.alipay.com/bax06385q32ssucugqxm00f1″]];
NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
//Cookies数组转换为requestHeaderFields
NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
//设置请求头
request.allHTTPHeaderFields = requestHeaderFields;
[self.payWebView loadRequest:request];
// 在收到响应开始加载后,决定是否跳转
– (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
//返回支付宝的信息字符串,alipays:// 以后的为支付信息,这个信息后台是经过 URLEncode 后的,前端需要进行解码后才能跳转支付宝支付(坑点)
//https://ds.alipay.com/?from=mobilecodec&scheme=alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%253A%252F%252Fqr.alipay.com%252Fbax041244dd0qf8n6ras805b%253F_s%253Dweb-other
NSString *urlStr = [navigationResponse.response.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([urlStr containsString:@”alipays://”]) {
NSRange range = [urlStr rangeOfString:@”alipays://”]; //截取的字符串起始位置
NSString * resultStr = [urlStr substringFromIndex:range.location]; //截取字符串
NSURL *alipayURL = [NSURL URLWithString:resultStr];
[[UIApplication sharedApplication] openURL:alipayURL options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
}];
}
WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
//这句是必须加上的,不然会异常
decisionHandler(actionPolicy);
}
总结
####这种方案就是相当于一个扫描二维码支付的方案,我们后台提供的URL信息里面包含了一个二维码信息,iOS使用WKWebView加载后得到相应的的二维码信息,我们按照指定格式跳转到支付宝客户端,带着信息过去,可能支付宝内部做了识别吧,直接就能弹出识别结果:是支付呢?还是该二维码已失效。
后续的难点就是支付成功后的iOS原生处理了,这里的逻辑可以发挥想象,该如何实现比较适合用户习惯吧。
iOS实现起来比安卓麻烦一点吧!不过这很iOS对吧。呵呵!