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

本文介绍如何使用iOS原生WKWebView加载H5调起支付宝客户端完成支付的过程,包括解决iOS WKWebView无法直接跳转的问题及具体实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

产品需求:

使用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对吧。呵呵!
### 解决支付宝支付页面在Web应用中嵌套显示的问题 对于支付宝支付页面在Web应用中嵌套显示所面临的问题,主要集中在iOS环境下通过WebView加载H5页面时遇到的兼容性和功能缺失情况。具体表现为,在iOS端的支付宝小程序中,所有传参为`FormData`形式的接口都存在问题,而后端无法获取到这些参数的数据[^2]。 #### 一、理解问题根源 支付宝官方文档指出,在其小程序内的WebView组件并不完全支持某些HTML5特性,特别是涉及到文件上传操作时存在局限性。这表明了问题的核心在于浏览器环境差异以及API的支持程度不同所致。 #### 二、解决方案探讨 为了克服上述挑战,可以考虑以下几个方面来优化: ##### 1. 使用Axios库改进请求方式 采用`axios`作为HTTP客户端工具,并对其进行适当配置以适应特定平台的需求。例如,可以通过设置自定义头信息或调整Content-Type字段等方式尝试绕过限制。此外,还可以探索利用Blob对象或其他替代方案实现文件传输而不依赖于传统的multipart/form-data格式。 ```javascript const formData = new FormData(); formData.append('file', file); // 设置headers, 可能需要根据实际情况修改content-type axios.post('/upload', formData, { headers: { 'Content-Type': 'application/octet-stream' // 或者其他适合的内容类型 } }) .then(response => console.log(response)) .catch(error => console.error(error)); ``` ##### 2. 调整服务器端逻辑 如果前端更改难以满足需求,则建议与后端开发人员沟通协作,共同寻找更合适的解析方法。比如改变接收参数的形式(如JSON字符串),从而避开因表单编码带来的麻烦;或者是增加额外的安全验证机制确保跨域资源共享(CORS)策略得到妥善处理。 ##### 3. 利用JavaScript Bridge桥接技术 当常规手段仍无法解决问题时,不妨思考借助JavaScript Bridge这种桥梁式的交互模式。即让原生应用程序提供一组可供网页调用的方法集合,以此弥补纯Web技术栈下的不足之处。这种方式虽然增加了复杂度但也提供了更大的灵活性和可控性[^3]。 ```html <!-- 示例:触发本地相册选取 --> <button onclick="window.AlipayJSBridge.call('photoPicker')">选择照片</button> <script type="text/javascript"> if (typeof AlipayJSBridge === "object") { // 定义回调函数用于接收返回的结果 } </script> ``` #### 三、总结 综上所述,要成功解决支付宝支付页面在Web应用中嵌套显示所带来的难题,需综合考量多方面的因素并采取针对性措施。除了不断测试和完善现有代码外,保持对最新技术和框架的关注同样重要,因为它们往往能够带来意想不到的帮助和支持。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sailip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值