最近碰到一个需要用H5支付的商城,痛苦了一整天,查找了N多的资料,终于还是苦尽甘来了。话不多说,干货来了。我用的是WKWebView,套路是一样的。
1.首先,设置白名单,确保你能顺利跳转微信。
2.在webView的代理中,截获跳转微信的HTTP(下面的所有代码都是在这个方法中实现)
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler;
代码如下:
NSURL*url = navigationAction.request.URL;
NSString*urlString = url.absoluteString;
//调用微信
if([urlStringrangeOfString:@"weixin://wap/pay"].location!=NSNotFound) {
//阻止跳转
decisionHandler(WKNavigationActionPolicyCancel);
BOOLcanOpen = [[UIApplicationsharedApplication]canOpenURL:url];
if(canOpen) {
[[UIApplication sharedApplication] openURL:url];
}
return;
}
OK这两步是让跳转到微信的,但是支付完成或者取消支付之后会跳到浏览器!!!很无语。SO,请接着看。
3.设置schemes,让程序外能回到APP
4.更改参数redirect_url,实现回到APP
调用支付的时候一定会有一条URL:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb&redirect_url =**********,通过测试得出支付返回的时候会加载redirect_url,当你的redirect_url是网址的时候,必定会跳转到浏览器.浏览器有个特性就是当你的URL是****://的时候,会查找你的schemes,(iOS系统应该在跳转浏览器之前自己有了判断是网址才进浏览器,****://直接会调用APP),从而可以跳转到APP,SO,只要更改这个redirect_url的值等于你的schemes的值加上://,就可以实现跳转回APP.
static const NSString*schemeString =@"sale.eutrun.com";
static const NSString*redirectString =@"redirect_url";
NSString *jumpString = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
NSString*changeredirectString =[NSStringstringWithFormat:@"%@=%@://",redirectString,schemeString];
//更改微信参数redirect_url 只要把redirect_url改成scheme的地址加上://就能跳转回APP
if([urlString hasPrefix:jumpString] && ![urlString containsString:changeredirectString]) {
decisionHandler(WKNavigationActionPolicyCancel);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSRange redirectRange = [urlString rangeOfString:@"redirect_url"];
//更改redirect_url 为scheme的地址
NSString*redirectUrl = [[urlString substringToIndex:redirectRange.location]stringByAppendingString:changeredirectString];
//记录本来跳转的地址,用于APP回来之后的刷新
NSArray*reloadArray = [urlString componentsSeparatedByString:@"redirect_url="];
if(reloadArray.count>1) {
self.reloadURL= [[reloadArray lastObject]stringByRemovingPercentEncoding];
}else{
self.reloadURL=[NSString stringWithFormat:@"https:%@",schemeString] ;
}
//发送请求
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
//referer为空会提示"出现商家参数格式有误,请联系商家解决"
//设置Referer 此地址必须注册到商户后台
[requestsetValue:@"sale.eutrun.com://"forHTTPHeaderField:@"Referer"];
[self.webViewloadRequest:request];
});
});
return;
}
然而,这样子仍然不够好,回来的时候,是个白屏,因为你的URL是错误的,H5也不能识别,SO,最后一步。
5.重新加载正确的URL
if([urlString isEqualToString:[NSStringstringWithFormat:@"%@://",schemeString]]) {
decisionHandler(WKNavigationActionPolicyCancel);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.reloadURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
[self.webView loadRequest:request];
});
});
return;
}
这个有两个方法,直接写在webView的代理中,或者监听APP的生命周期都可以。综上所诉,可以完美的在支付完成跳回APP.
最后 加上decisionHandler(WKNavigationActionPolicyAllow);作为正确的H5跳转。
有什么问题请直接提问,看到的话会立刻回复的,有更好的方式方法麻烦大佬们不吝赐教,谢谢。