iOS微信H5支付无法返回APP解决方案

作者: b2c7a522e27e | 来源:发表于2018-04-19 19:05 被阅读4912次

    本文只讨论已成功调起微信支付后,无法返回自己的APP的问题,iOS微信H5支付不在讨论范围内。提供下列参考:
    微信H5支付官方文档
    微信H5支付官方Demo

    知道你们都喜欢看结论,先放结论吧!此方案支付多APP

    解决方案:

    1. 在微信支付管理后台注册一级域名,比如 company.com
    2. 在APP工程配置中设置URL Scheme,比如 A.company.com(A你可以随便写,后面的域名得和1.中一致)
    3. 在webView代理方法中拦截微信下单请求(注意是下单请求不是下单返回结果!!!),在这个请求的基础上生成新的请求,新的请求追加或修改参数redirect_url为你的URLScheme,即redirect_url=URLEncode(A.company.com://),cancel掉原来的请求,webView加载这个新的请求。
      具体的:
      需要拦截的请求前缀为,https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb
      UIWebView在 webView:shouldStartLoadWithRequest:navigationType: 代理方法中拦截
      WKWebView在 webView:decidePolicyForNavigationAction:decisionHandler: 代理方法中拦截
    //以WKWebView为例(其实我很不想贴代码的,无奈问的人太多)
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        NSURLRequest *request = navigationAction.request;
        NSString *wxPre = @"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb";
        if ([request.URL.absoluteString hasPrefix:wxPre]) {
            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:request];
            decisionHandler(WKNavigationActionPolicyCancel);
        }
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    1. (可选)微信支付结束(可能不是真正结束后面会细说)会发起redirect_url的重定向,webView拦截 request.URL.scheme 包含 company.com:// 的请求,在这里可以做一些后续操作,比如 刷新页面,通知前端支付完成等。如果支付跳转后出现白屏问题,可以在这里处理,比如干掉webView或刷新

    需要注意的问题:

    1. 微信H5下单接口(https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb)请求header中有个Referer字段,如果这个请求中没有redirect_url参数,微信支付结束后默认回调Referer字段中地址
    2. Referer头和redirect_url中的域名,都必须在微信后台注册过
    3. redirect_url回调并不可靠,可能微信支付还没结束就回调了。

    微信官方文档对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:代理方法中监听

    if ([request.URL.scheme rangeOfString:@"company.com"].length!=0) {
                //微信支付结束后会进入这里(注意:这里并不可靠,跳入微信5s后就会回调这里)
                //TODO: 处理webView,比如干掉或重定向到别的URL
                return NO;
    }
    

    另一种方案是在AppDelegate中处理(我下面的代码逻辑写的并不健壮,只是提供思路,请自行完善)

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
    {
        if ([url.scheme rangeOfString:@"company.com"].length!=0) {
           //TODO: 处理webView
        }
        return YES;
    }
    

    怎么处理webView:根据你自己的业务需求进行处理。楼主是直接关闭webView了。比如你可能需要展示支付结果,那你就让webView重定向到支付结果页面,只是个思路,请自行实现。
    如果你有更好的方案来避免白屏,请在评论中指出或私信我,谢谢!

    另附,iOS支付宝H5无法返回APP解决方案

    本文已被百度收录,谢谢大家的支持!如果喜欢请点赞或评论,让更多的人看到,谢谢!
    转载请注明出处,谢谢!

    参考链接:
    iOS 解决微信h5支付无法直接返回APP的问题
    iOS实现微信外部H5支付完成后返回原APP(多APP也可实现)

    相关文章

      网友评论

      • 33a231292dbe:还没解决的请加我QQ:691647860,秒解决
      • _旧时光:请问一下, newRequest.URL = [NSURL URLWithString:newURLStr]; [webView loadRequest:request]; 这里是不是写错了,应该是 [webView loadRequest:newRequest]; 吧,另外在webview里怎么写啊,wkwebview走到 decisionHandler(WKNavigationActionPolicyAllow);就崩溃
        b2c7a522e27e:谢谢指正,已经修改。
        因为WKWebView的请求只能处理一次,之前代码写的有问题,已经WKNavigationActionPolicyCancel后在调用WKNavigationActionPolicyAllow就会崩溃。
        webview里怎么写啊。没明白什么意思
      • FR_Zhang:WKWebView 如何解决拦截网页加载的问题
        b2c7a522e27e:@FR_Zhang 具体点
      • FR_Zhang:我现在有个问题,就是通过这种方式,跳转微信支付,成功或者取消,返回自己的app后,怎么判断是成功,取消,失败的情况
        b2c7a522e27e:无法判断成功还是失败。唯一的方式就是回来之后请求自己的后台接口去判断这笔订单是否成功
      • Chaoooo_iOS:白屏问题有更好的解决方法吗?我自己测的时候发现从微信返回app时,并没有走application:openUrl 这个方法
        b2c7a522e27e:目前没有更好的解决方案。如果你有欢迎提出来。
        你可以在跳出APP前往微信时把webView关闭,也就是发起微信支付时就关闭,这也是比较建议的做法。
        其它的方案请按我文章中操作,如果文章中的方法也帮不了你,那我也没办法了。
      • MLing小懒虫:大神,能加个QQ分享下经验吗?865392352
      • 蜀山之光:为什么我这样处理还是返回不到原来的app上,只是返回到链接,能告诉QQ吗,我解决一天还没解决出来,我想问一下,关于回去app的问题
        luckyhong:@CocoaKier 您好,我们服务器端是在微信下单接口请求返回的跳转支付mweb_url中去拼接的redirect_url,因为最后微信支付成功,或者是取消支付,都会回调一个支付授权结果的页面(要么支付成功,要么支付失败),追加或修改参数 redirect_url=URLEncode(A.company.com://)是要前端拦截webView去处理吗?谢谢~
        b2c7a522e27e:@luckyhong 解决方案中的第3步操作做了吗
        luckyhong:@CocoaKier 同问,我也是返回不到原app,请求解决办法。
      • 恩赐_解脱:你好,看了你的简书,解决了一个问题,十分感谢!我现在也是要做一个framework,我是用swift做的,需要在app内的h5界面调用支付宝,微信支付,支付宝已经搞好了,但是微信后台用的是财富通三方的支付平台,没有“在微信支付管理后台注册一级域名”,这样还能不能搞?
        b2c7a522e27e:域名必须一致,如果不一致将无法支付成功,详情请见微信文档 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4 下方其它常见错误3。
      • Javen205:IJPay让支付触手可及~了解一下
        https://gitee.com/Javen205/IJPay
        b2c7a522e27e:不错,不过你这毕竟是SDK,有些需求还是不能满足,比如一套项目要尽量少地使用SDK,比如我本身就是开发SDK,我的方案还是轻量啊:joy:

      本文标题:iOS微信H5支付无法返回APP解决方案

      本文链接:https://www.haomeiwen.com/subject/lszwkftx.html