• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

android webview调起微信h5支付以后发生了什么

武飞扬头像
韩zj
帮助1

webview调起微信h5支付

先把webview调起微信h5支付的代码贴一下,网上都有

		 @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview_privacy);
        ButterKnife.bind(this);

        setToolBar(R.id.toolbar, true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                if (webView.canGoBack())
                {
                    webView.goBack();// 返回前一个页面

                }
                else
                {
                    finish();
                }
            }
        });
        Intent intent = getIntent();
        action = (WebviewForAppointActivity.WebAction) intent.getSerializableExtra(WEBVIEW_ACTION);
        actionPatten = intent.getStringExtra(WEBVIEW_ACTION_PATTEN);
        isFromHospital = intent.getBooleanExtra(Extras.EXTRA_DATA, false);
        if (action == null || actionPatten == null)
        {
            action = null;
            actionPatten = null;
        }


        initWebView();

        String url = getIntent().getStringExtra(WEBVIEW_URL);
        if (TextUtils.isEmpty(url))
        {
            ToastUtil.showLongToast("地址错误,地址不能为空");
            return;
        }
        else
        {
            referer = getIntent().getStringExtra(Extras.EXTRA_DATA2);
            if (referer != null && !StringUtil.isEmpty(referer))
            {
                HashMap<String, String> stringStringHashMap = new HashMap<>();
                stringStringHashMap.put("Referer", referer);

                webView.loadUrl(url, stringStringHashMap);
            }
            else
            {
                webView.loadUrl(url);
            }


        }
    }

 public class MyWebViewClient extends WebViewClient
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
        {
            String url = request.getUrl().toString();
            if (!TextUtils.isEmpty(url))
            {
                if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
                {
                    finish();
                    return false;
                }
             if (url.startsWith("weixin://") || url.startsWith("alipays://") || url.startsWith("tel:"))
                {
                    try
                    {
                        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                        return true;
                        //防止没有app匹配到action时抛出异常闪返
                    }
                    catch (Exception ignored)
                    {
                        ignored.printStackTrace();
                        final NoticeDialog noticeDialog = new NoticeDialog(WebviewForAppointActivity.this);
                        noticeDialog.setLinearLayoutInputVisible(false);
                        noticeDialog.setTitle("提示");
                        noticeDialog.setNoticeContent("您尚未安装微信,不能支付?");
                        noticeDialog.setSubmitButtonText("确定");
                        noticeDialog.setCancelButtonText("取消");
                        noticeDialog.setSubmitListener(new View.OnClickListener()
                        {
                            @Override
                            public void onClick(View v)
                            {

                                noticeDialog.dismiss();
                                finish();
                            }
                        });
                        noticeDialog.setCancelListener(new View.OnClickListener()
                        {
                            @Override
                            public void onClick(View v)
                            {
                                noticeDialog.dismiss();
                                finish();

                            }
                        });
                        noticeDialog.showAtLocation(WebviewForAppointActivity.this.getWindow().getDecorView(), Gravity.CENTER, 0, 0);

                    }
                    return super.shouldOverrideUrlLoading(webView, request);
                }
                else
                {
                    try
                    {
                        Map<String, String> extraHeaders = new HashMap<String, String>();
                        extraHeaders.put("Referer", referer);
                        view.loadUrl(url, extraHeaders);
                        referer = url;
                        return true;//不调用系统的浏览器打开网页

                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                    return true;
                }
            }

            return super.shouldOverrideUrlLoading(view, request);
        }
       ......
        }
学新通

先解释一下代码:
webview只能识别http://或https://开头的url,微信支付的url以weixin://开头,因此需要用intent调起能处理此scheme开头的url的App

 if (url.startsWith("weixin://") || url.startsWith("alipays://") || url.startsWith("tel:"))

如果没有设置,会报错

net::ERR_UNKNOWN_URL_SCHEME

然后要设置Referer,这个是商户申请H5时提交的授权域名,要不然会报错商家参数格式有错

   Map<String, String> extraHeaders = new HashMap<String, String>();
                        extraHeaders.put("Referer", referer);
                        view.loadUrl(url, extraHeaders);
                        referer = url;

Webview获取回调

学新通
这个回调我试了一下,基本上都在5秒就会调用。webview获取回调以及处理自己逻辑的代码可以这样写
首先在shouldOverrideUrlLoading拦截回调url,这个是redirect_url拼接的,可以由后台返回,然后在webview里写一个接口,再定义一个类来继承,里边操作自己的逻辑,伪代码是这样

//Webview里定义
 public interface WebAction extends Serializable
    {
        void doAction(WebviewForAppointActivity webViewActivity);
    }

继承这个接口的类

/**
 * Created by hanzj on 2021/10/22
 * 查询微信h5支付结果
 */

public class WeiXinH5PayAction implements WebviewForAppointActivity.WebAction
{
    private PayQueryParam payQueryParam;

    /**
     * 查询支付订单
     */
    private void payQuery(PayQueryParam payQueryParam, WebviewForAppointActivity webViewActivity)
    {

        RequestEntity<PayQueryParam> entity = new RequestEntity<>();
        entity.setReqData(payQueryParam);

        OkHttpUtils.postString().url(Contants.APIURL.POST_APPOINTPayQUERY.getUrl()).headers(entity.getHeader())
                .content(entity.getBody()).build().execute(new JsonCallBack<ResponseEntity<PayQueryResults>>()
        {
            @Override
            public void onError(Call call, Exception e, RequestCall requestCall)
            {

                ToastUtil.showLongToast("服务器繁忙,请您稍后尝试。");
            }

            @Override
            public void onResponse(ResponseEntity<PayQueryResults> data, RequestCall requestCall)
            {
                if (data.isOK())
                {
                   OnLinePayResultActivity.startActivity(webViewActivity,data.getRstData());
                   webViewActivity.finish();
                }
                else
                {
                    OnLinePayResultActivity.startActivity(webViewActivity,null);
                    webViewActivity.finish();
                }
            }
        });
    }


    @Override
    public void doAction(WebviewForAppointActivity webViewActivity)
    {

            payQuery(payQueryParam,webViewActivity);

    }
    public void setPayQueryParam(PayQueryParam payQueryParam){
        this.payQueryParam=payQueryParam;
    }

}
学新通

在webview中拦截调用

  action = (WebviewForAppointActivity.WebAction) intent.getSerializableExtra(WEBVIEW_ACTION);
        actionPatten = intent.getStringExtra(WEBVIEW_ACTION_PATTEN);

    public class MyWebViewClient extends WebViewClient
    {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
        {
            WebView.HitTestResult hitTestResult = view.getHitTestResult();
            Log.e("shouldOverrideUrlLoading", TimeUtil.getBeijingNowTime("HHmmss"));
            String url = request.getUrl().toString();
            if (!TextUtils.isEmpty(url))
            {
               if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
                {
                    action.doAction(WebviewForAppointActivity.this);
     
                    return true;
                }
                }
                ....
 
学新通

当然,要是嫌麻烦的话,可以直接在

if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
                {
                }

处理逻辑
我的逻辑
我这边的逻辑是,支付的时候,直接打开支付页面,然后5秒以后就会调回调接口,我捕捉到这个url,因为回调地址是域名,webview会显示404,用户体验不好,我就加载成空白页,然后弹出对话框,提示用户支付完成或者未完成,然后关闭webview

  public class MyWebViewClient extends WebViewClient{
            if (actionPatten != null && url.lastIndexOf(actionPatten) != -1&&
                        !isFromHospital)
                {

                    webView.loadUrl("about:blank ");
                    final NoticeDialog noticeDialog = new NoticeDialog(WebviewForAppointActivity.this);
                    noticeDialog.setLinearLayoutInputVisible(false);
                    noticeDialog.setTitle("提示");
                    noticeDialog.setNoticeContent("是否完成支付?");
                    noticeDialog.setSubmitButtonText("已完成");
                    noticeDialog.setCancelButtonText("未完成");
                    noticeDialog.setSubmitListener(new View.OnClickListener()
                    {
                        @Override
                        public void onClick(View v)
                        {

                            noticeDialog.dismiss();
                            finish();
                        }
                    });
                    noticeDialog.setCancelListener(new View.OnClickListener()
                    {
                        @Override
                        public void onClick(View v)
                        {
                            noticeDialog.dismiss();
                            finish();

                        }
                    });
                    noticeDialog.showAtLocation(WebviewForAppointActivity.this.getWindow().getDecorView(), Gravity.CENTER, 0, 0);


                    return false;
                }
                }
学新通

调起支付以后,发生了什么

学新通

支付页面弹出以后,会发生什么?原理我还没深究,我先说一下我这边的研究情况
是否调起微信app
我把支付url放到手机浏览器中,会调起微信app,但是在webview中发起支付,我看了一下打开的支付页面,并没有在微信中打开,所以并没有唤起微信app
是否在网页中支付
没唤起微信app,那是不是就在当前webview加载的网页中支付了呢,为了测试这个情况,我果断删除了微信app,结果支付报错,那就是没有在当前网页支付,还是需要依赖微信app
支付页面是否加载在webview中
难道支付页面,是在自己app的webview中加载的吗?为了测试这个问题,我在回调url加载以后,finish掉webview的页面,发现支付页面不受影响,关闭支付以后,回到webview前一个页面,说明支付页面并没有加载在webview中
支付页面是依赖本app吗
那不在webview中加载,是否依赖于调起支付的app呢。为了测试这个问题,我直接在回调url加载以后,杀掉了整个进程,然后发现支付页面依然存在,结论就是支付页面不依赖调起他的app
结论
通过以上观察,调起支付页面以后,就会超出我们的控制,自己app不能控制这个支付过程和结果,所以要主动查询,一般5秒会调用回调url,在这里我们可以弹出提示框,在其他页面可以进行主动查询支付情况

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfahhh
系列文章
更多 icon
同类精品
更多 icon
继续加载