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

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

原文 http://blog.csdn.net/yj_sail/article/details/74452361

2017-07-05 17:20:48阅读(685)

产品需求:

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

资源

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

开发历程 1. 安卓直接webView加载上面的URL直接可完成跳转支付宝弹出支付界面; 2. iOS WKWebView加载这个URL,只是单纯加载,无法实现跳转; 3. 使用Safari浏览器加载该URL,直接提示打开,如下图(这里由于一个订单只有一个小时的待付款时间限制,否则会失效,如果这里没有失效,会打开让您支付的页面):

iOS支付功能篇:原生WebView调起支付宝客户端支付<a href=方案" src="http://img.blog.csdn.net/20170705154802015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWWpfc2FpbA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描述" title="">iOS支付功能篇:原生WebView调起支付宝客户端支付方案

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) {
    }];   
断点调试,打印服务器返回的信息

我打印了一下 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对吧。呵呵!

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹