問題分析
正常的H5支付流程如下
按照上面的支付流程會出現(xiàn) App -> 微信 -> 支付 -> 點擊 完成 -> safari訪問redirect_url設(shè)置的URL,這種流程其實用戶體驗是有點糟糕的,我們期望是 App -> 微信 -> 支付 -> 點擊 完成 -> App訪問redirect_url設(shè)置的URL
問題分析到上面已經(jīng)非常明了了,無非就是攔截處理,下面講講具體的實施。
問題分析
根據(jù)上面的分析解決的思路應(yīng)該非常的清晰
攔截請求
1.首先在decidePolicyForNavigationAction 回調(diào)里攔截支付的請求攔截的字符串:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb 如果包含了該鏈接做如下處理,isload變量是控制是否是第一次沒有修改redirect_url參數(shù)的請求防止重復(fù)請求
NSString *urlString = [[navigationAction.request URL] absoluteString];
urlString = [urlString stringByRemovingPercentEncoding];
PPLog(@"%@",urlString);
///scheme:通信協(xié)議.常用的http,https,ftp,maito等
if ([navigationAction.request.URL.scheme isEqualToString:@"tel"]) {//tel:點擊電話咨詢按鈕,調(diào)起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加載的微信支付統(tǒng)一下單鏈接, 將redirect_url參數(shù)修改為喚起自己App的URLScheme,不然取消支付直接返回safari瀏覽器 如果包含了該鏈接做如下處理,isload變量是控制是否是第一次沒有修改redirect_url參數(shù)的請求防止重復(fù)請求
if ([urlString containsString:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && !isLoad) {
//重寫redirect_url時注意一定是授權(quán)的URL://的協(xié)議 WX_H5_Pay_UrlSchemes:h5商城支付后臺配置的域名或者子域名
NSString *WXH5SchemeURL = [NSString stringWithFormat:@"%@://",WX_H5_Pay_UrlSchemes];
NSArray *arr = [urlString componentsSeparatedByString:@"redirect_url="];
redirect_url = arr[1];//保存回調(diào)url,微信支付成功或者失敗走的就是這個回調(diào)
urlString = [NSString stringWithFormat:@"%@redirect_url=%@",arr[0],WXH5SchemeURL];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
//設(shè)置授權(quán)域名
[request setValue:WXH5SchemeURL forHTTPHeaderField: @"Referer"];
[webView loadRequest:request];
isLoad = YES;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
isLoad = NO;
decisionHandler(WKNavigationActionPolicyAllow);//允許跳轉(zhuǎn)
2.在項目設(shè)置Scheme鏈接用于支付完后返回App

xcode配置scheme
到這一步已經(jīng)成功了一大半了,你會發(fā)現(xiàn)現(xiàn)在支付成功后能返回App了但是返回的時候webView是白屏。白屏其實就是網(wǎng)頁沒有任何請求導(dǎo)致的,接下來我們就要使用上步提前記錄好后臺給的redirect_url的url了。
在AppDelegate里監(jiān)聽url.scheme的值
在AppDelegate里監(jiān)聽url.scheme的值是否為我們之前設(shè)置好的xxxx.com 如果是xxxx.com 發(fā)起通知 通知webview加載提前記錄好的redirect_url的url了
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
//微信支付取消或者成功回調(diào)
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 = @"";
}
}
此時已經(jīng)基本解決,但是有個bug就是點擊導(dǎo)航欄返回試,會重復(fù)拉起微信支付頁面,需要在返回方法里實現(xiàn):
-(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,不然點擊導(dǎo)航欄返回按鈕會重復(fù)調(diào)起微信支付頁面
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];
}