iOS解决H5微信支付跳转(&支付宝)
前言
在iOS里,使用WKWebView
加载H5页面,进行微信支付后,会跳转不回原来的App。现象就是微信内点击 (完成|取消) ,返回的是手机Safari
浏览器。针对这个问题,下面是我总结的解决方案,推荐使用第三个方案.
方案一:
在网上搜索时这类答案时,提到解决办法几乎全是这个方案,这个方案个人觉得有点麻烦了,如果要适配到iOS9之前可以考虑。总结起来如下:
1.1 在H5微信支付时,拦截Request Header
里面的Referer
字段,设置为能调起自己App的scheme
链接,比如shop.demo.com://
【iOS解决H5微信支付跳转(&支付宝)】1.2 拦截微信支付统一下单链接,修改链接中的redirect_url=
字段,比如改为:shop.demo.com://
,注意要跟Request Header
里面的Referer
字段是一致的。
1.3 设置App项目的URL Types
,增加一个URL Schemes
,内容就是上面的shop.demo.com
,注意白名单的添加.
1.4 注意,上面的shop.demo.com://
不能随便写,这个域名必须和 微信H5商家后台提交的授权域名一致,不然会报[商家参数格式有误,请联系商家解决]
1.5 具体的代码细节,网络上很多的,比如下面这2个哥们写的:
- https://www.jianshu.com/p/66449674cc6f
- https://www.jianshu.com/p/c82f336d946c
Schemes
不冲突? 二级域名?怎么让这么多App的开发者都写这么多代码呢?方案二: 之前有说,H5调起微信支付,会返回
Safari
浏览器,那干脆就在Safari
浏览器所呈现的页面,加个按钮,点击返回原App即可。(当然,高兴的话,你也可以直接执行js代码自动跳转回来),所以这个方案需要产品经理能同意!!2.1 App内的H5链接地址,多加个
query
参数,比如https://shop.demo.com/index?scheme=appScheme
2.2 H5的回调页面,根据
scheme=appScheme
,点击按钮,跳转回对应的App即可.2.3 注意:区分好iOS和Android,Android的H5微信支付是没问题的。也注意区分是在手机的
Safari
浏览器,还是在App内的浏览器。点评:需要产品经理同意,H5前端开发需要写很多判断代码。
方案三: 这个方案是目前==最优的方案==,使用
Universal Links
!!!Universal Link
(通用链接)是Apple在iOS9推出的一种能够方便的通过HTTPS链接来启动App的功能,当你的App支持Universal Link
后,一个正确的HTTPS链接就可以无缝重定向到你的App,且不需要通过Safari
浏览器,==微信==已全面支持Universal Link
.Universal Link
的配置过程,网上百度一大堆的,苹果爸爸在开发者网站也写的很详细,我这里简单过一下:3.1 必须有一个正规的
https
域名,并且拥有该域名下的上传到根目录的权限。(阿里云的https就可以)3.2 苹果开发者中心配置:在
Identifiers
里找到对应的App ID,在Capabilities
列表里有Associated Domains
,把它变为Enabled
就可以了。![iOS解决H5微信支付跳转(&支付宝)](https://img.it610.com/image/info10/3e3d1268c7924f09b1441afdfffa4f51.jpg)
文章图片
Associated Domains.png 3.3 在Xcode中,配置
Associated Domains
,注意格式,必须必须以applinks:
为前缀,域名当然是后台或者运维给你的。![iOS解决H5微信支付跳转(&支付宝)](https://img.it610.com/image/info10/730750802e6c431ab152b3c894a06ddd.jpg)
文章图片
Xcode.png 3.4 配置域名支持
Universal Links
这块自己查即可,资料很多的,注意的是apple-app-site-association
文件一定要配置对,它决定了能不能正确的跳转到App。3.5 上面都搞定后,前端H5需要做的就是处理iOS特殊的回调地址,这个地址是跟
apple-app-site-association
文件里面配置的PATHS
一致的,比如:redirect_url=https://www.shop.demo.com/apppath?returnUrl=https://www.shop.demo.com/result/123123
其实
redirect_url=https://www.shop.demo.com/apppath/
已经可以打开App了,后面跟的returnUrl=
是我跟前端的约定,毕竟打开App后,我需要加载显示真正的回调页面.3.5 其实代码很少的,比如App内的H5支付拦截,以
WKWebView
为例:- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.scheme isEqualToString:@"weixin"]) {
// 2.微信支付
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
3.6
Appdelegate.m
文件里面处理支付回调:// 通过universal link来唤起appAPI_AVAILABLE(ios(8.0))
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray> * restorableObjects))restorationHandler
{
// 检查是否是H5商城的支付回调唤起
if ([userActivity.webpageURL.host isEqualToString:@"shop.demo.com"]) {
// 1.获得真正的回调地址
NSArray *array = [userActivity.webpageURL.query componentsSeparatedByString:@"returnUrl="];
NSURL *url = [NSURL URLWithString:array.lastObject];
YouMallWebController *mallVC = [xx xxx];
// H5的控制器,看你的项目里怎么获取到了
[mallVC loadURL:url];
// 加载显示真正的回调地址
}
return YES;
}
3.7 正如你所看到的,通过
Universal Link
实现跳转回来,代码量很少,大多都是配置而已,需要注意的是:- 区分好Android 和 iOS,比如H5的URL加参数:
&from=ios
,安卓就是正常回调地址,iOS就是通过Universal Links
返回。 -
Universal Links
这个域名需要在微信H5商家后台提交的授权域名一致,不然会报[商家参数格式有误,请联系商家解决] - 通过
Universal Links
这样的回调地址,是可以调到不同的App,仅靠PATHS
区分即可。
Universal Link
的配置参考链接:- 苹果官网配置讲解链接
- 一个比较详细的博文
- 微信团队的讲解配置
AlipaySDK.h
里面:/**
*h5 拦截支付入口
*从h5链接中获取订单串并支付接口(自版本15.4.0起,推荐使用该接口)
*@param urlStr拦截的 url string
*@return YES为成功获取订单信息并发起支付流程;NO为无法获取订单信息,输入url是普通url
*/
- (BOOL)payInterceptorWithUrl:(NSString *)urlStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock;
所以,在
WKWebView
里面,拦截支付宝的H5支付就很方便了:- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.host isEqualToString:@"mclient.alipay.com"]) {
// 1.支付宝支付
[[AlipaySDK defaultService] payInterceptorWithUrl:navigationAction.request.URL fromScheme:@"You Scheme" callback:^(NSDictionary *resultDic) {
// 支付成功或者失败的 回调处理
}];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
附: 支付宝官方的文档讲解
最后: 思路就如上面所写了,其中的方案三也是我项目中使用的办法,不仅解决了跳转回来,还解决了跳转到N多App的问题。大家如果遇到什么问题,可以直接留言交流。
-- End ---
PS:最近我有跳槽的想法,有工作机会的老板,欢迎骚扰哦!北京呦!
END。
我是小侯爷。
在帝都艰苦奋斗,白天是上班族,晚上是知识服务工作者。
如果读完觉得有收获的话,记得关注和点赞哦。
非要打赏的话,我也是不会拒绝的。
推荐阅读
- parallels|parallels desktop 解决网络初始化失败问题
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 2020-04-07vue中Axios的封装和API接口的管理
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 员工的微信朋友圈是公司的宣传阵地吗()
- iOS中的Block
- FBI怎么和恐怖分子谈判