本文只讨论已成功调起微信支付后,无法返回自己的APP的问题,iOS微信H5支付不在讨论范围内。提供下列参考:
知道你们都喜欢看结论,先放结论吧!此方案支付多APP
解决方案:
具体的:
UIWebView在 webView:shouldStartLoadWithRequest:navigationType: 代理方法中拦截
WKWebView在 webView:decidePolicyForNavigationAction:decisionHandler: 代理方法中拦截
//以WKWebView为例(
- (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest*request = navigationAction.request;
if([request.URL.absoluteStringhasPrefix:wxPre]) {
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] init];
newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
NSString*newURLStr =nil;
newRequest.URL= [NSURLURLWithString:newURLStr];
[webViewloadRequest:newRequest];
decisionHandler(WKNavigationActionPolicyCancel);
}
else{
decisionHandler(WKNavigationActionPolicyAllow);
}
}
需要注意的问题:
2.Referer头和redirect_url中的域名,都必须在微信后台注册过
3.redirect_url回调并不可靠,可能微信支付还没结束就回调了。
由于设置redirect_url后,回跳指定页面的操作可能发生在:1,微信支付中间页调起微信收银台后超过5秒 2,用户点击“取消支付“或支付完成后点“完成”按钮。因此无法保证页面回跳时,支付流程已结束,所以商户设置的redirect_url地址不能自动执行查单操作,应让用户去点击按钮触发查单操作
2018.6.14更新:
很多人私信问我白屏的问题
按我的方案流程应该是这样的:
1.APPH5页面点击购买,跳到微信,APPH5白屏
2.微信点击取消或购买完成,直接跳回APP,此时APPH5仍是白屏
(注意,上述过程都是没有进入Safari的)
3.关闭webView
白屏是需要你自己额外处理的:
只要是跳回到APP就算是支付结束(可能成功可能失败),你需要在支付结束后处理webView。
这里有两件事:一是怎能判断支付结束;二是如何处理webView。
怎么判断支付结束:一种方案是在webView的webView:shouldStartLoadWithRequest:navigationType:代理方法中监听
//微信支付结束后会进入这里(注意:这里并不可靠,跳入微信5s后就会回调这里)
//TODO:处理webView,比如干掉或重定向到别的URL
returnNO;
}
另一种方案是在AppDelegate中处理(我下面的代码逻辑写的并不健壮,只是提供思路,请自行完善)
- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(nullableNSString*)sourceApplication annotation:(id)annotation{
//TODO:处理webView
}
returnYES;
}
怎么处理webView:根据你自己的业务需求进行处理。楼主是直接关闭webView了。比如你可能需要展示支付结果,那你就让webView重定向到支付结果页面,只是个思路,请自行实现。
2018.11.9本楼更新
1.在webview不用自己拦截URL去处理redirect_url;
2.在Appdelegete的openURL代理方法里面,拦截到url再替换字符串即可;
- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(nullableNSString*)sourceApplication annotation:(id)annotation{
//从微信返回拦截回调地址
UIViewController*serviceViewController = [self getCurrentViewController];
if([serviceViewControllerisKindOfClass:[RootWebViewControllerclass]]) {
RootWebViewController*vc = (RootWebViewController*)serviceViewController;
[vc.WKwebViewloadRequest:newRequest];
}
}
}
如果你有更好的方案来避免白屏,请在评论中指出或私信我,谢谢!
参考链接: