iOS支付功能篇:原生WebView调起支付宝客户端支付方案

产品需求:

使用iOS原生WKWebView加载H5调起支付宝客户端进行支付的功能实现。

资源

后台提供H5支付接口
e.g : https://qr.alipay.com/bax06385q32ssucugqxm00f1

开发历程

1. 安卓直接webView加载上面的URL直接可完成跳转支付宝弹出支付界面;

2. iOS WKWebView加载这个URL,只是单纯加载,无法实现跳转;

3. 使用Safari浏览器加载该URL,直接提示打开,如下图(这里由于一个订单只有一个小时的待付款时间限制,否则会失效,如果这里没有失效,会打开让您支付的页面):

iOS支付功能篇:原生WebView调起支付宝客户端支付方案_第1张图片iOS支付功能篇:原生WebView调起支付宝客户端支付方案_第2张图片

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对吧。呵呵!

你可能感兴趣的:(iOS开发,H5开发,小技巧,支付宝,支付,webview,url,ios)