美文网首页
关于App集成微信支付调起微信及回调App问题

关于App集成微信支付调起微信及回调App问题

作者: 张小凡123 | 来源:发表于2021-02-24 17:55 被阅读0次

    问题分析

    正常的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];
    }
    

    End 到此已经全部解决

    相关文章

      网友评论

          本文标题:关于App集成微信支付调起微信及回调App问题

          本文链接:https://www.haomeiwen.com/subject/wjnsfltx.html