美文网首页iOS开发
iOS WKWebView调用微信支付

iOS WKWebView调用微信支付

作者: 言霏 | 来源:发表于2019-07-07 17:36 被阅读0次

    业务场景为JS中调用微信支付,原生APP跳转至微信付款,成功或失败后返回原生APP。

    1. 原生APP使用的为WKWebView,JS调用微信SDK后原生APP是不会跳转至微信的(UIWebView可以),需要在webView:decidePolicyForNavigationAction:decisionHandler:中添加代码
    [[UIApplication sharedApplication] openURL:URL options:@{} completionHandler:nil];
    

    此时原生APP可以跳转到微信了,但是付款成功或失败后并不能返回原生APP而是跳转到了safari,接下来就是为了让微信能够返回我们原生APP。

    1. 当JS调用微信支付时我们在webView:decidePolicyForNavigationAction:decisionHandler:中会先后收到两波指令
    • image1@2x.png
    • image2.png

    想让微信支付完成后跳回原生APP就需要处理https://wx.tenpay.com中的redirect_url,而weixin://wap/pay是真正调起微信的链接。
    将第一条指令中redirect_url的值替换xxx.faker.com://www.myFaker.com/epay……,其中xxx.faker.com为申请微信支付时授权域名(问申请支付的开发人员,xxx可以随便是啥),同时在原生APP的URLType中添加xxx.faker.com

    image3@2x.png
    1. 这样微信支付完成跳转回原生APP后就会加载xxx.faker.com://www.myFaker.com/epay……,显然这个地址加载不出来(会空白页),还需将该地址的scheme替换为https
      最终代码为:
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
        NSURLRequest *request = navigationAction.request;
        NSURL *URL = request.URL;
        NSString *myScheme = @"www.cmrh.com";
        if ([URL.host isEqualToString:@"wx.tenpay.com"]) {
    
            decisionHandler(WKNavigationActionPolicyAllow);
            NSURLComponents *cmps = [[NSURLComponents alloc] initWithURL:URL resolvingAgainstBaseURL:YES];
            NSString *redirect_url = nil;
            for (NSURLQueryItem *item in cmps.queryItems) {
                if ([item.name isEqualToString:@"redirect_url"]) {
                    redirect_url = item.value;
                    break;
                }
            }
            if (redirect_url == nil) return;
            NSURL *redirect_URL = [NSURL URLWithString:redirect_url];
            if (redirect_URL == nil) return;
            NSString *replaceScheme = redirect_URL.scheme;
            // 如果replaceScheme已经被替换过了就不再替换了
            if (replaceScheme == nil || [replaceScheme isEqualToString:myScheme]) return;
            NSString *my_redirect_url = [redirect_url stringByReplacingOccurrencesOfString:replaceScheme withString:myScheme];
            NSString *urlAbsoluteString = [URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding)];
            NSString *my_requestUrl = [urlAbsoluteString stringByReplacingOccurrencesOfString:redirect_url withString:my_redirect_url];
            NSURL *my_requestURL = [NSURL URLWithString:my_requestUrl];
            NSMutableURLRequest *my_request = [NSMutableURLRequest requestWithURL:my_requestURL];
            if (my_requestURL == nil) return;
            my_request.allHTTPHeaderFields = request.allHTTPHeaderFields;
            // 让webView加载被修改过的request
            // 这会导致本方法再次被调用哦
            [webView loadRequest:my_request];
            return;
        }
    
        if ([URL.scheme isEqualToString:@"weixin"]) {
            if ([[UIApplication sharedApplication] canOpenURL:URL]) {
                if (@available(iOS 10.0, *)) {
                    [[UIApplication sharedApplication] openURL:URL options:@{} completionHandler:nil];
                } else {
                    [[UIApplication sharedApplication] openURL:URL];
                }
                decisionHandler(WKNavigationActionPolicyCancel);
            }
        } else if ([URL.scheme isEqualToString:myScheme]) {
            // 在微信支付完成或失败后回到APP会调用
            // 将xxx.faker.com://www.myFaker.com/epay…
            // 修改成 https://www.myFaker.com/epay…
            // 让webView重新加载
            decisionHandler(WKNavigationActionPolicyCancel);
            NSString *urlAbsoluteString = [URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:(NSUTF8StringEncoding)];
            NSString *schemeDetail = [NSString stringWithFormat:@"%@://",myScheme];
            NSString *targetUrl = [urlAbsoluteString stringByReplacingOccurrencesOfString:schemeDetail withString:@"https://"];
            NSURL *targetURL = [NSURL URLWithString:targetUrl];
            NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
            [webView loadRequest:request];
        } else {
            decisionHandler(WKNavigationActionPolicyAllow);
        }
    }
    

    相关文章

      网友评论

        本文标题:iOS WKWebView调用微信支付

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