iOS开发WKWebView嵌套H5支付调原生APP支付及回调

本文内容如标题,会涉及到H5调原生支付以及在微信、支付宝支付后跳转回本APP内容
1、H5调起微信、支付宝APP支付
2、支付成功或失败后的回调
首先需要再项目工程配置URL Types,路径“info->URL Types”,如图所示


项目工程文件.png

添加后info.plist文件的URL Types所得如图所示
URLTypes.png

微信的URL Schemes里面添加的必须为微信开放平台H5支付的域名,格式为xxx.###.com(大概如此具体问H5开发要),然后再添加下面代码

H5调起微信、支付宝支付原理都一样,都是在WKNavigationDelegate代理方法进行操作

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{}

不同的是微信需要判断“weixin://"而支付宝需要判断"alipays://" 、"alipay://",具体代码如下:

微信

if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        if ([scheme isEqualToString:@"weixin"]) {
            if (endPayRedirectURL) {
                [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[endPayRedirectURL stringByRemovingPercentEncoding]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30]];
            }
        }
        if ([navigationAction.request.URL.absoluteString hasPrefix:@"weixin://"]) {
            [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
        }
        return;
    }

其中“ endPayRedirectURL”是微信支付完成或者失败后回调需要用到的
微信处理回调其实就是将传给微信redirect_url拼接上APP的URL Types所配置的URL Schemes,如果没有传的直接拼接,传了的需要替换,具体方法如下

if ([reqUrl hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![reqUrl hasSuffix:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        NSString *redirectUrl = nil;
        if ([reqUrl containsString:@"redirect_url="]) {
            NSRange redirectRange = [reqUrl rangeOfString:@"redirect_url"];
            endPayRedirectURL =  [reqUrl substringFromIndex:redirectRange.location+redirectRange.length+1];
            redirectUrl = [[reqUrl substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }else {
            redirectUrl = [reqUrl stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }
        
        NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
        newRequest.allHTTPHeaderFields = navigationAction.request.allHTTPHeaderFields;
        [newRequest setValue:[NSString stringWithFormat:@"%@",CompanyFirstDomainByWeChatRegister] forHTTPHeaderField:@"Referer"];
        newRequest.URL = [NSURL URLWithString:redirectUrl];
        [webView loadRequest:newRequest];
        return;
    }

支付宝

if ([reqUrl hasPrefix:@"alipays://"] || [reqUrl hasPrefix:@"alipay://"]) {
        NSURL* alipayURL = [self changeURLSchemeStr:reqUrl];
        if (@available(iOS 10.0, *)) {
            [[UIApplication sharedApplication] openURL:alipayURL options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
            }];
        } else {
            [[UIApplication sharedApplication] openURL:alipayURL];
        }
    }

支付处理支付成功回调需要用到两个方法更改fromAppUrlScheme直接copy就可以

-(NSURL*)changeURLSchemeStr:(NSString*)urlStr{
    NSString* tmpUrlStr = urlStr.copy;
    if([urlStr containsString:@"fromAppUrlScheme"]) {
        tmpUrlStr = [tmpUrlStr stringByRemovingPercentEncoding];
        NSDictionary* tmpDic = [self dictionaryWithUrlString:tmpUrlStr];
        NSString* tmpValue = [tmpDic valueForKey:@"fromAppUrlScheme"];
        tmpUrlStr = [[tmpUrlStr stringByReplacingOccurrencesOfString:tmpValue withString:@"你自己的scheme"] mutableCopy];
        tmpUrlStr = [[tmpUrlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] mutableCopy];
    }
    NSURL * newURl = [NSURL URLWithString:tmpUrlStr];
    return newURl;
}
-(NSDictionary*)dictionaryWithUrlString:(NSString*)urlStr{
    if(urlStr && urlStr.length&& [urlStr rangeOfString:@"?"].length==1) {
        NSArray *array = [urlStr componentsSeparatedByString:@"?"];
        if(array && array.count==2) {
            NSString*paramsStr = array[1];
            if(paramsStr.length) {
                NSString* paramterStr = [paramsStr stringByRemovingPercentEncoding];
                NSData *jsonData = [paramterStr dataUsingEncoding:NSUTF8StringEncoding];
                NSDictionary *responseDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
                return responseDic;
            }
        }
    }
    return nil;
}

整个WKNavigationDelegate代码如下

#pragma mark - WKNavigationDelegate
static const NSString * CompanyFirstDomainByWeChatRegister = @"xxx.###.com";
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    NSString * reqUrl = navigationAction.request.URL.absoluteString;
    NSString * scheme = [navigationAction.request.URL scheme];
    
    ///打电话
    if ([scheme isEqualToString:@"tel"]) {
        NSString *resourceSpecifier = [navigationAction.request.URL resourceSpecifier];
        NSString *callPhone = [NSString stringWithFormat:@"telprompt:%@", resourceSpecifier];
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
    }
    
    /// 支付宝
    if ([reqUrl hasPrefix:@"alipays://"] || [reqUrl hasPrefix:@"alipay://"]) {
        NSURL* alipayURL = [self changeURLSchemeStr:reqUrl];
        if (@available(iOS 10.0, *)) {
            [[UIApplication sharedApplication] openURL:alipayURL options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @NO} completionHandler:^(BOOL success) {
            }];
        } else {
            [[UIApplication sharedApplication] openURL:alipayURL];
        }
    }
    
    /// 微信
    if ([reqUrl hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![reqUrl hasSuffix:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        NSString *redirectUrl = nil;
        if ([reqUrl containsString:@"redirect_url="]) {
            NSRange redirectRange = [reqUrl rangeOfString:@"redirect_url"];
            endPayRedirectURL =  [reqUrl substringFromIndex:redirectRange.location+redirectRange.length+1];
            redirectUrl = [[reqUrl substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }else {
            redirectUrl = [reqUrl stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }
        
        NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
        newRequest.allHTTPHeaderFields = navigationAction.request.allHTTPHeaderFields;
        [newRequest setValue:[NSString stringWithFormat:@"%@",CompanyFirstDomainByWeChatRegister] forHTTPHeaderField:@"Referer"];
        newRequest.URL = [NSURL URLWithString:redirectUrl];
        [webView loadRequest:newRequest];
        return;
    }
    if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        if ([scheme isEqualToString:@"weixin"]) {
            if (endPayRedirectURL) {
                [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[endPayRedirectURL stringByRemovingPercentEncoding]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30]];
            }
        }
        if ([navigationAction.request.URL.absoluteString hasPrefix:@"weixin://"]) {
            [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
        }
        return;
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

如需改正还望不吝赐教

你可能感兴趣的:(iOS开发WKWebView嵌套H5支付调原生APP支付及回调)