本文只讨论已成功调起微信支付后,没法返回本身的APP的问题,iOS微信H5支付不在讨论范围内。提供下列参考:
微信H5支付官方文档
微信H5支付官方Demophp
本文实现的效果:你的App->微信客户端->支付或取消->你的App
此方案支持多App,不一样的App添加处理后不会出现返回混乱的状况。html
另附,iOS支付宝H5支付没法返回APP解决方案web
微信官方文档中关于“回调页面”有这么一段话:api
正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面,则能够在MWEB_URL后拼接上redirect_url参数,来指定回调页面。微信
如,您但愿用户支付完成后跳转至www.wechatpay.com.cn,则能够作以下处理:
假设您经过统一下单接口获到的
MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096
则拼接后的地址为
MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn
markdown
微信H5支付,在中间页面的URL上提供了一个redirect_url参数,用于指定支付结束后的回调页面(默认是没有redirect_url参数的,微信会取请求头中referer参数的值做为回调页)。微信客户端会经过[[UIApplication sharedApplication] openURL:url]
方法来返回回调页。若是咱们把redirect_ur设置成咱们App的URLSchemes是否是就能够返回咱们的App了?ide
这里的company.com请和你微信下单时的一级域名保持一致,即与微信中间页wx.tenpay.com**请求头**中的Referer字段对应的值一致。由于在微信中间页会去校验Referer和redirect_url的值是否在微信后台注册过。 2. 在APP工程配置中设置URL Scheme,好比 A.company.com(A你能够随便写,后面的域名得和1.中一致) 3. 在webView代理方法中拦截微信中间页请求(注意是请求不是返回结果),在这个请求的基础上新建一个请求,追加参数redirect_url=URLEncode(A.company.com://),cancel掉原来的请求,webView从新加载这个新的请求。oop
//以WKWebView为例(下面的代码可能不严谨,只是表达一个思路,请根据本身实际状况调整)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
//下面这个这个字符串不要直接写在代码中,不然会被苹果机审扫描到pay字段,致使被拒绝。能够自行加密处理或让后台返回
NSString *wxPre = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
if ([request.URL.absoluteString hasPrefix:wxPre] && [request.URL.absoluteString rangeOfString:@"redirect_url"].length==0) {
//开始微信支付会走这里
//将要请求微信中间页,且中间页没有追加过redirect_url参数,追加redirect_url
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] init];
newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
NSString *newURLStr = nil;
//TODO: 对newURLStr追加参数redirect_url=URLEncode(@"A.company.com://")
newRequest.URL = [NSURL URLWithString:newURLStr];
[webView loadRequest:newRequest];
decisionHandler(WKNavigationActionPolicyCancel);
}
else if ([request.URL.scheme rangeOfString:@"company.com"].length!=0) {
//微信支付结束(完成\取消\超时)后会走这里
//TODO: 关闭微信中间页,好比dismiss webViewController,或[webView goBack]
}
else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
复制代码
微信官方文档对redirect_url的描述:
因为设置redirect_url后,回跳指定页面的操做可能发生在:1,微信支付中间页调起微信收银台后超过5秒 2,用户点击“取消支付“或支付完成后点“完成”按钮。所以没法保证页面回跳时,支付流程已结束,因此商户设置的redirect_url地址不能自动执行查单操做,应让用户去点击按钮触发查单操做post
白屏问题我之前也没搞清楚缘由,只知道怎么规避,此次整理这篇博客时又好好研究了一下,终于弄清除缘由了。微信支付
现象:
首先,不使用这篇文章中的方法时,微信支付结束后,手动回到App,不会有白屏的问题。
其次,若是使用了这篇文章中的方法,有些读者反映,虽然微信支付结束后可以自动跳回App,可是App会整个白屏,没法继续操做。
微信中间页wx.tenpay.com/cgi-bin/mmp…
window.onload = function() {
...省略
var url = "weixin://wap/pay?prepayid%3Dwx18xxxxxxxxx&package=156xxxxxx&noncestr=157xxxxx&sign=719bxxxxxxxxxxx";
var redirect_url = "A.company.com://";
top.location.href = url;
if (redirect_url) {
setTimeout(function() {
top.location.href = redirect_url;
},
5000);
} else {
setTimeout(function() {
window.history.back();
},
5000);
}
}
复制代码
看完是否是就豁然开朗了。
白屏缘由总结:
发起微信支付时,会把页面重定向到中间页,也能够理解为校验页,有错误提示错误缘由(以下图),没错误就是纯白色页面同时拉起微信客户端支付,中间页的js代码里面会判断是否有redirect_url的值,若是没有则5s后返回上一页window.history.back(),也就返回支付前的H5页面了;若是redirect_url有值,则重定向到redirect_url页面,而redirect_url=“A.company.com://“,重定向会失败,就停留在微信中间页了,这就是白屏的缘由。
在支付结束后关闭微信中间页便可解决白屏问题。
有两个点,一个是支付结束的时机,一个是关闭微信中间页。
支付结束的时机,我上文提到过
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
if ([request.URL.scheme rangeOfString:@"company.com"].length!=0) {
//微信支付结束(完成\取消\超时)后会走这里
//TODO: 关闭微信中间页,好比dismiss webViewController,或[webView goBack]
}
...
}
复制代码
关闭微信中间页,我这里提供两种思路:
1.按文章步骤操做后,App跳转微信后,支付或取消没有返回App而是跳转到Safari
若是以为这篇文章对你有帮助,请点个赞吧。若是有疑问能够关注个人公众号给我留言。
转载请注明出处,谢谢!
参考连接:
iOS 解决微信h5支付没法直接返回APP的问题
iOS实现微信外部H5支付完成后返回原APP(多APP也可实现)