iOS微信H5支付无法返回APP解决方案

1、在APP工程配置中设置一个新的URL Scheme为abc.daoway.cn(注意:其中“abc”需改为你的channel号,后面的域名必须为daoway.cn否则无法支付成功)
2、在WebView代理方法中拦截微信下单请求,在这个请求的基础上生成新的请求,新的请求追加或修改参数redirecturl为你的URLScheme,即redirecturl=URLEncode(abc.daoway.cn://),cancel掉原来的请求,webView加载这个新的请求。需要拦截的请求前缀为,https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb

UIWebView在 webView:shouldStartLoadWithRequest:navigationType: 代理方法中拦截;
WKWebView在 webView:decidePolicyForNavigationAction:decisionHandler: 代理方法中拦截。

//UIWebView示例代码

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *wxPre = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
    NSString *urlScheme = @"abc.daoway.cn://";    

    if ([request.URL.absoluteString hasPrefix:wxPre]) {//判断链接是否是微信支付 微信支付完成后回到APP的逻辑        
        //分解出原来的url字段
        NSString* scheme = request.URL.scheme;
        NSString* host = request.URL.host;
        NSString* path = request.URL.path;
        NSString* query = request.URL.query;
        NSArray* querys = [query componentsSeparatedByString:@"&"];
        NSMutableDictionary* params = [[NSMutableDictionary alloc] initWithCapacity:querys.count];
        for (NSString* q in querys) {
            NSArray* qs = [q componentsSeparatedByString:@"="];
            params[qs[0]] = qs.count > 1 ? qs[1] : @"";
        }        
        NSString *redirectUrl = [params objectForKey:@"redirect_url"];//微信支付请求带的redirect_url参数
        NSString *newRedirectUrl = [urlScheme URLEncoding];//需要做URLEncode处理
        if (redirectUrl && [redirectUrl isEqualToString:newRedirectUrl]) {
            //如果redirect_url已经修改了 则不拦截
            return YES;
        }else {
            if (redirectUrl) {//保存一下原本的redirect_url 等支付完成调回APP后需要使用 解决白屏问题
                self.wx_redirect_url = [redirectUrl URLDecoding];//需要URLDecode处理
            }            
            //修改redirect_url参数
            [params setObject:newRedirectUrl forKey:@"redirect_url"];

            //重新拼接成一个新的url
            NSMutableString *newQuery = [[NSMutableString alloc] init];
            for (NSString *key in params.allKeys) {
                [newQuery appendFormat:@"%@=%@&", key, [params objectForKey:key]];
            }

            NSString *newUrlStr = [NSString stringWithFormat:@"%@://%@%@?%@",scheme,host,path,newQuery];
            if (newUrlStr.length > 0) {
                newUrlStr = [newUrlStr substringToIndex:newUrlStr.length - 1];
            }

            //重新发起请求
            NSMutableURLRequest* newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:newUrlStr] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
            [newRequest setHTTPMethod:@"GET"];
            [newRequest setValue:urlScheme forHTTPHeaderField: @"Referer"];//需要设置一下Referer字段
            [self.webView loadRequest:newRequest];
            return NO;
        }
    }
    else if ([request.URL.absoluteString hasPrefix:urlScheme]) {//解决微信支付完成调回APP后白屏问题
        if (self.wx_redirect_url) {
            //刷新页面 重新请求上一步保存的原redirect_url 或者自己实现其他逻辑
            [self loadUrl:self.wx_redirect_url];
            return NO;
        }
    }

    return YES;
}

//WKWebView示例代码

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSString *wxPre = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
    NSString *urlScheme = @"abc.daoway.cn://";
    NSURLRequest *request = navigationAction.request;

    if ([request.URL.absoluteString hasPrefix:wxPre]) {//判断链接是否是微信支付 微信支付完成后回到APP的逻辑

        //分解出原来的url字段
        NSString* scheme = request.URL.scheme;
        NSString* host = request.URL.host;
        NSString* path = request.URL.path;
        NSString* query = request.URL.query;
        NSArray* querys = [query componentsSeparatedByString:@"&"];
        NSMutableDictionary* params = [[NSMutableDictionary alloc] initWithCapacity:querys.count];
        for (NSString* q in querys) {
            NSArray* qs = [q componentsSeparatedByString:@"="];
            params[qs[0]] = qs.count > 1 ? qs[1] : @"";
        }

        NSString *redirectUrl = [params objectForKey:@"redirect_url"];//微信支付请求带的redirect_url参数
        NSString *newRedirectUrl = [urlScheme URLEncoding];//需要做URLEncode处理
        if (redirectUrl && [redirectUrl isEqualToString:newRedirectUrl]) {
            //如果redirect_url已经修改了 则不拦截
            decisionHandler(WKNavigationActionPolicyAllow);
        }else {
            if (redirectUrl) {//保存一下原本的redirect_url 等支付完成调回APP后需要使用 解决白屏问题
                self.wx_redirect_url = [redirectUrl URLDecoding];//需要URLDecode处理
            }

            //修改redirect_url参数
            [params setObject:newRedirectUrl forKey:@"redirect_url"];

            //重新拼接成一个新的url
            NSMutableString *newQuery = [[NSMutableString alloc] init];
            for (NSString *key in params.allKeys) {
                [newQuery appendFormat:@"%@=%@&", key, [params objectForKey:key]];
            }

            NSString *newUrlStr = [NSString stringWithFormat:@"%@://%@%@?%@",scheme,host,path,newQuery];
            if (newUrlStr.length > 0) {
                newUrlStr = [newUrlStr substringToIndex:newUrlStr.length - 1];
            }

            //重新发起请求
            NSMutableURLRequest* newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:newUrlStr] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
            [newRequest setHTTPMethod:@"GET"];
            [newRequest setValue:urlScheme forHTTPHeaderField: @"Referer"];//需要设置一下Referer字段
            [self.webView loadRequest:newRequest];
            decisionHandler(WKNavigationActionPolicyCancel);
        }
    }
    else if ([request.URL.absoluteString hasPrefix:urlScheme]) {//解决微信支付完成调回APP后白屏问题
        if (self.wx_redirect_url) {
            //刷新页面 重新请求上一步保存的原redirect_url 或者自己实现其他逻辑
            [self loadUrl:self.wx_redirect_url];
            decisionHandler(WKNavigationActionPolicyCancel);
        }
    }

    decisionHandler(WKNavigationActionPolicyAllow);
}