美文网首页
App接入微信H5支付常见错误及原因

App接入微信H5支付常见错误及原因

作者: imzzb | 来源:发表于2019-07-27 09:11 被阅读0次

    在App上接入微信H5支付一般都会遇到一些错误。本文讨论了这些错误的解决方案和背后的原因,希望能让读者能少踩些坑。

    错误可以分为两类:一是H5支付域名设置错误,二是URL Scheme跳转App错误。

    第一类,H5支付域名设置错误

    此类错误一般发生在安卓机器上(网上有人说iOS也遇到类似错误),在微信官方文档里有对这类现象的详细描述。

    一般情况下,检查下面两点就能排除这类错误:

    1. 登录商户号对应的商户平台—“产品中心”—“开发配置”,查看设置的H5支付域名是否包含商家发起支付的网页所在的域名。

    2. 在商家发起支付的网页,在发起支付的时候,浏览器会重定向到一个微信的页面(页面地址类似于:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096),这个页面会校验权限和安全性,我们暂且把它叫做微信校验页面。

      为了校验发起支付的域名是否合法,在请求微信校验页面的HTTP请求里,头部(HTTP Header)需要有“Referer”这个字段。了解HTTP的同学可能知道,Referer字段会告诉服务器请求的原始资源的URI。也就是说,Referer会告诉腾讯的服务器,是谁在请求微信校验页面。所以Referer的值应该是商家发起支付的页面的域名。

      通常情况下,浏览器或者WebView会为我们自动加上Referer,但是在安卓的自定义WebView中,无法自动加上Referer。需要在WebView中手动设置Referer,如:

      Map extraHeaders = new HashMap();
      extraHeaders.put("Referer", "商户申请H5时提交的授权域名"
      

    第二类,URL Scheme跳转错误

    1、无法跳转到微信App

    在完成了上述校验后,浏览器或者WebView会被重定向到一个URL Scheme(类似于:weixin://wap/pay?prepayid%3Dwx261541599457545c6f11d41a1106566432&package=1888940394&noncestr=1564126923&sign=1ba23428a32b17d5d03cf032b283379f)。

    对于安卓或者iOS的浏览器来说,这种URL Scheme一般可以成功跳转。但是对于安卓自定义WebView和iOS的WKWebView来说,无法使用URL Scheme跳转。

    1)安卓自定义WebView

    往往我们的app中使用自定义的WebView,会设置很多参数,经测试发现如果为WebView设置了WebViewClient,如下:

    webView.setWebViewClient(new WebViewClient() {
        // some logic
    }
    

    那么就不能唤起微信支付了,errorCode返回-10,提示“不支持该协议”。我们需要手动调起微信:

     @Override  
            public boolean shouldOverrideUrlLoading(WebView view, String url) {  
                // 如下方案可在非微信内部WebView的H5页面中调出微信支付
                if (url.startsWith("weixin://")) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                    return true;
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
    
    

    2) iOS UIWebView

    如果iOS端使用的是UIWebView,是可以支持URL Scheme的。但是自iOS 9之后,URL Scheme必须在Info.plist中列为白名单才有效。

    打开Info.plist,增加“LSApplicationQueriesSchemes”一行,类型设置为Array,并在这个数组中加入一个条目:“weixin”。

    image

    3)iOS WKWebView

    WKWebView不支持URL Scheme,或者叫默认不支持URL Scheme,需要我们手动调起微信。参考解决方法:

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        NSURL *url = navigationAction.request.URL;
        NSString *urlString = (url) ? url.absoluteString : @"";
        if ([urlString containsString:@"weixin://"]) {
            [[UIApplication sharedApplication] openURL:url];
            decisionHandler(WKNavigationActionPolicyCancel);
        }
    }
    

    如果你使用UIApplicationopenURL方法打开URL Scheme,你就不需要在Info.plist中把对应的URL Scheme列为白名单。

    因为,UIApplicationcanOpenURL会查询Info.plist中LSApplicationQueriesSchemes中的Scheme,如果没有对应的Scheme就返回NO。而当你使用UIApplicationopenURL方法打开一个URL Scheme的时候,并不会调用canOpenURL

    2、支付完成后无法从微信App跳转回到我们的App

    在调用微信支付的时候,微信允许你设置一个回调URL。在iOS上,支付完成后,微信会调起手机上的Safari浏览器加载这个回调URL。

    这个回调URL的逻辑我们无法改变,但是我们可以在回调URL指向的HTML页面里,判断是否是iOS Safari浏览器。如果是Safari,就可以调用我们App自己的URL Scheme。

    我们可以在Info.plist里增加一个URL Types:

    image

    然后在回调页面里合适的时机调用window.location = "testappdemo",注意"testappdemo"是你在Info.plist里设置的URL Scheme。

    这样Safari就会调起你的App。但是在调起你的App之前,会询问用户“是否在xxx里打开”

    image

    总结

    不论iOS还是安卓,在浏览器中完成微信H5支付一般是没有问题的,这也是微信H5支付设计的应用场景。

    不论在iOS还是安卓App上,接入微信H5支付都可能遇到各种各样的问题,所以微信官方文档提醒:

    H5支付不建议在APP端使用,如需要在APP中使用微信支付,请接APP支付

    相关文章

      网友评论

          本文标题:App接入微信H5支付常见错误及原因

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