关于App集成微信支付调起微信及回调App问题
2021-02-24 本文已影响0人
张小凡123
问题分析
正常的H5支付流程如下
按照上面的支付流程会出现 App -> 微信 -> 支付 -> 点击 完成 -> safari访问redirect_url设置的URL,这种流程其实用户体验是有点糟糕的,我们期望是 App -> 微信 -> 支付 -> 点击 完成 -> App访问redirect_url设置的URL
问题分析到上面已经非常明了了,无非就是拦截处理,下面讲讲具体的实施。
问题分析
根据上面的分析解决的思路应该非常的清晰
拦截请求
1.首先在decidePolicyForNavigationAction 回调里拦截支付的请求拦截的字符串:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb 如果包含了该链接做如下处理,isload变量是控制是否是第一次没有修改redirect_url参数的请求防止重复请求
NSString *urlString = [[navigationAction.request URL] absoluteString];
urlString = [urlString stringByRemovingPercentEncoding];
PPLog(@"%@",urlString);
///scheme:通信协议.常用的http,https,ftp,maito等
if ([navigationAction.request.URL.scheme isEqualToString:@"tel"]) {//tel:点击电话咨询按钮,调起h5弹框
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{} completionHandler:^(BOOL success) {
}];
} else {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
}
return;
}
if([urlString containsString:@"weixin://wap/pay?"]) {//打开微信支付
NSURL *url = [NSURL URLWithString:urlString];
if([UIApplication.sharedApplication openURL:url]) {
if (@available(iOS 10.0, *)) {
if([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
}];
}
} else {
[[UIApplication sharedApplication]openURL:webView.URL];
}
}
isLoad = YES;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//拦截WKWebView加载的微信支付统一下单链接, 将redirect_url参数修改为唤起自己App的URLScheme,不然取消支付直接返回safari浏览器 如果包含了该链接做如下处理,isload变量是控制是否是第一次没有修改redirect_url参数的请求防止重复请求
if ([urlString containsString:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && !isLoad) {
//重写redirect_url时注意一定是授权的URL://的协议 WX_H5_Pay_UrlSchemes:h5商城支付后台配置的域名或者子域名
NSString *WXH5SchemeURL = [NSString stringWithFormat:@"%@://",WX_H5_Pay_UrlSchemes];
NSArray *arr = [urlString componentsSeparatedByString:@"redirect_url="];
redirect_url = arr[1];//保存回调url,微信支付成功或者失败走的就是这个回调
urlString = [NSString stringWithFormat:@"%@redirect_url=%@",arr[0],WXH5SchemeURL];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
//设置授权域名
[request setValue:WXH5SchemeURL forHTTPHeaderField: @"Referer"];
[webView loadRequest:request];
isLoad = YES;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
isLoad = NO;
decisionHandler(WKNavigationActionPolicyAllow);//允许跳转
2.在项目设置Scheme链接用于支付完后返回App
xcode配置scheme到这一步已经成功了一大半了,你会发现现在支付成功后能返回App了但是返回的时候webView是白屏。白屏其实就是网页没有任何请求导致的,接下来我们就要使用上步提前记录好后台给的redirect_url的url了。
在AppDelegate里监听url.scheme的值
在AppDelegate里监听url.scheme的值是否为我们之前设置好的xxxx.com 如果是xxxx.com 发起通知 通知webview加载提前记录好的redirect_url的url了
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
//微信支付取消或者成功回调
if ([url.scheme containsString:WX_H5_Pay_UrlSchemes]) {
[[NSNotificationCenter defaultCenter] postNotificationName:WX_H5_PAY object:nil];
return YES;
}
return YES;
}
在wkWebView接收通知,重定向wk,刷新页面
-(void)goBackWhitWXPay {
//重定向地址不为空
if(redirect_url.length > 0) {
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:redirect_url]];
[self.wkWebView loadRequest:req];
redirect_url = @"";
}
}
此时已经基本解决,但是有个bug就是点击导航栏返回试,会重复拉起微信支付页面,需要在返回方法里实现:
-(void)goBack{
// PPLog(@"=====%@",self.wkWebView.backForwardList.backList);
// PPLog(@"=====%@",self.wkWebView.backForwardList.forwardList);
// PPLog(@"=====currentItem:%@",self.wkWebView.backForwardList.currentItem);
// PPLog(@"=====backItem:%@",self.wkWebView.backForwardList.backItem);
// PPLog(@"=====forwardItem:%@",self.wkWebView.backForwardList.forwardItem);
//
// PPLog(@"***************************************");
//
// PPLog(@"=====currentItem:%@",self.wkWebView.backForwardList.currentItem.URL);
// PPLog(@"=====currentItem:%@",self.wkWebView.backForwardList.currentItem.title);
// PPLog(@"=====currentItem:%@",self.wkWebView.backForwardList.currentItem.initialURL);
//
for (NSInteger i = 0; i < self.wkWebView.backForwardList.backList.count; i++) {
WKBackForwardListItem *itm = self.wkWebView.backForwardList.backList[i];
//拦截支付url,不然点击导航栏返回按钮会重复调起微信支付页面
if([[itm.URL absoluteString] containsString:@"payUrl="]) {
//回到商城首页
[self.wkWebView goToBackForwardListItem:self.wkWebView.backForwardList.backList[0]];
return;
}
}
//正常返回
self.wkWebView.canGoBack ? [self.wkWebView goBack]:[self.navigationController popViewControllerAnimated:YES];
}