根据需求,需要在iOS App嵌套的H5页面中拦截到H5的微信和支付宝支付,并调起微信和支付宝客户端。
由于我的项目里是用WKWebView加载的H5页面,因此首先需要在WKWebView 的delegate中拦截到微信和支付宝到支付请求,具体是在- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
方法中进行拦截。
一开始想拦截到微信和支付宝的支付链接通过 [[UIApplication sharedApplication]openURL:webView.URL]; 的方式打开微信和支付宝:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString* requestUrl = navigationAction.request.URL.absoluteString;
if ([requestUrl hasPrefix:@"alipays://"] || [requestUrl hasPrefix:@"alipay://"]) {
[[UIApplication sharedApplication]openURL:navigationAction.request.URL];
}
if ([requestUrl hasPrefix:@"weixin://"]) {
[[UIApplication sharedApplication]openURL:navigationAction.request.URL];
}
decisionHandler(WKNavigationActionPolicyAllow);
}
但是发现通过这种方式在调起微信和支付宝后无法再返回到App,后面在支付宝开放平台文档中发现,支付宝有提供手机网站支付转 App 支付到接口,链接🔗,其中有拦截+支付二合一接口( payInterceptorWithUrl...),通过这个接口,我们不需要手动拦截支付宝请求,只需要在decidePolicyForNavigationAction方法中调用接口方法,并设置需要返回的scheme,scheme在targets -> info下的URL Types中添加并设置:
// 支付宝支付
__weak ViewController* wself = self;
NSString * urlStr = navigationAction.request.URL.absoluteString;
BOOL isIntercepted = [[AlipaySDK defaultService] payInterceptorWithUrl:urlStr fromScheme:@"alipaySchemes" callback:^(NSDictionary *result) {
// 处理支付结果
if ([result[@"isProcessUrlPay"] boolValue]) {
if ([result[@"resultCode"] intValue] == 9000) {
// 支付成功
[wself.webView goBack];
[MBProgressHUD showSuccess:@"支付成功" toView:self.view];
}else{
[wself.webView goBack];
[MBProgressHUD showSuccess:@"取消支付" toView:self.view];
}
}
}];
if (isIntercepted) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
注意:在使用支付宝提供的接口时,不需要再手动拦截"alipay://"等,否则,将不能成功调起支付宝客户端
支付宝会通过我们设置的scheme返回App,微信没有提供H5转App支付的接口,但是在成功设置Universal Link通用链接后发现,通过openURL的方式打开微信,可以设置options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO},返回时,会根据Universal Link返回到我们App。
最后实现代码如下:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString* requestUrl = [navigationAction.request.URL absoluteString];
//微信支付
if ([requestUrl hasPrefix:@"weixin://"]) {
//通过友盟API判断是否安装微信客户端
if([[UMSocialManager defaultManager] isInstall:UMSocialPlatformType_WechatSession]){
if([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
} ];
} else {
[[UIApplication sharedApplication]openURL:webView.URL];
}
}else{
[MBProgressHUD showSuccess:@"微信未安装" toView:self.view];
}
}
// 支付宝支付
__weak ViewController* wself = self;
BOOL isIntercepted = [[AlipaySDK defaultService] payInterceptorWithUrl:requestUrl fromScheme:@"alipaySchemes" callback:^(NSDictionary *result) {
// isProcessUrlPay 代表 支付宝已经处理该URL
if ([result[@"isProcessUrlPay"] boolValue]) {
if ([result[@"resultCode"] intValue] == 9000) {
// 支付成功
[wself.webView goBack];
[MBProgressHUD showSuccess:@"支付成功" toView:self.view];
}else{
[wself.webView goBack];
[MBProgressHUD showSuccess:@"取消支付" toView:self.view];
}
}
}];
if (isIntercepted) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}