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);
}