当前位置: 代码迷 >> Android >> android中关于微信支付流程的小结
  详细解决方案

android中关于微信支付流程的小结

热度:174   发布时间:2016-04-24 11:32:15.0
android中关于微信支付流程的总结

微信

一、前期准备

  • 在开放平台的“开发者引用登记界面”申请AppID,只有在开放平台上通过审核的应用才能集成微信支付的功能。
  • 下载微信终端开发工具包【网址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN】
  • 或在微信支付商户平台开发文档页面下载工具包和demo:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
  • 将工具包中libs目录下的libammsdk.jar复制到你的libs目录下,

    • 【eclipse项目】右击选中“Configure Build Path…”—>“Add jars…”导入到工程中。如图:
    • 【AndroidStudio项目】选中项目,按“F4”调出“Project Sructure”窗口,添加jar包到项目中。如图:
      这里写图片描述

  • 在清单文件中添加权限:

            <uses-permission android:name="android.permission.INTERNET"/>         <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>         <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>         <uses-permission android:name="android.permission.READ_PHONE_STATE"/>         <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 添加混淆规则。在混淆配置文件proguard.cfg中,增加如下代码,否则,将导致无法弹出发送第三方消息的确认框。

    -keep class com.tencent.mm.sdk.** {   *;}

二、项目集成【微信支付目前的做法,凡是涉及签名的操作均交由后台服务器去做】

  • 与微信建立通信联系:在代码中向微信APP注册你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合适的地方进行注册。笔者比较喜欢在调用微信支付的时候才进行注册。

    final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);msgApi.registerApp(Constants.APP_ID);
  • 将用户选择的订单信息发送给后台服务器,由后台服务器调用微信支付API提供的统一下单接口等一系列和签名相关的操作,签名完成后,APP接收后台传送回来的prepay_id、sign等数据。
  • 调用api.sendReq(req)发起支付。

    //从后台获取返回的参数PayReq req = new PayReq();req.appId   = json.getString("appid");req.partnerId   = json.getString("partnerid");req.prepayId    = json.getString("prepayid");req.nonceStr    = json.getString("noncestr");req.timeStamp   = json.getString("timestamp");req.packageValue    = json.getString("package");req.sign        = json.getString("sign");req.extData     = "app data"; // optional// 发起支付。//在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信api.sendReq(req);
  • 支付完成后,微信会同步返回一个支付结果给APP,并通过异步返回支付结果给后台服务器。
  • APP将支付结果发送给后台服务器,查询支付结果, 获取实际支付结果,并展示结果。

    附一张微信支付流程图【摘自微信支付平台:)】

    这里写图片描述

三、项目集成【APP端请求统一下单接口、进行签名,这是微信支付之前的做法,目前已经不支持,写在这里只是为了纪念一下那段苦逼的日子】

  • 在调用微信支付的Activity的onCreate方法中实例化支付请求对象:

    req = new PayReq();
  • 与微信建立通信联系:在代码中向微信APP注册你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合适的地方进行注册。笔者比较喜欢在调用微信支付的时候才进行注册。

    final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);msgApi.registerApp(Constants.APP_ID);
  • 调用统一下单接口,生成预支付订单号prepay_id:
    (1). URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
    (2).开启任务:

    GetPrepayIdTask getPrepayId = new GetPrepayIdTask();                getPrepayId.execute();

    (3).在任务中调用统一下单接口,获取prepay_id。

    private class GetPrepayIdTask extends            AsyncTask<Void, Void, Map<String, String>> {        private ProgressDialog dialog;        @Override        protected void onPreExecute() {            dialog = ProgressDialog.show(context, getString(R.string.app_tip),                    getString(R.string.getting_prepayid));        }        @Override        protected void onPostExecute(Map<String, String> result) {            if (dialog != null) {                dialog.dismiss();            }            resultunifiedorder = result;            System.out.println("result=" + result);            // 生成签名参数            genPayReq();            // 调起支付接口            sendPayReq();        }        @Override        protected void onCancelled() {            super.onCancelled();        }        @Override        protected Map<String, String> doInBackground(Void... params) {            // 统一下单接口            String url = String            //genProductArgs方法用来生成订单详细信息,在官方demo中有详细代码。            String entity = genProductArgs();            System.out.println("entity=" + entity);            byte[] buf = Util.httpPost(url, entity);            String content = new String(buf);            System.out.println("content=" + content);            Map<String, String> xml;            try {                xml = decodeXml(new String(content.getBytes("iso8859-1"),                        "utf-8"));                return xml;            } catch (UnsupportedEncodingException e) {                e.printStackTrace();            }            return null;        }    }

    订单详细信息中需要注意的几个参数:

    • notify_url:微信和我们后台建立链接的HTTP协议地址,在支付完成后,微信会通过这个地址向我们的后台服务器发送支付结果。
    • out_trade_no:这个参数是我们服务器生成的订单编号。
    • spbill_create_ip:终端IP,我们服务器定好的。
    • total_fee:订单金额,单位为分。
    • 返回订单详情时一定要注意中文编码问题:String(xmlstring.toString().getBytes(), “ISO8859-1”)。
  • 任务执行完成后,将参数重新签名。

    //在任务执行完成后调用这个方法。private void genPayReq() {            req.appId = Constants.APP_ID;            req.partnerId = Constants.MCH_ID;            req.prepayId = resultunifiedorder.get("prepay_id");            //参数值是固定的            req.packageValue = "Sign=WXPay";            req.nonceStr = genNonceStr();            req.timeStamp = String.valueOf(genTimeStamp());            List<NameValuePair> signParams = new LinkedList<NameValuePair>();            signParams.add(new BasicNameValuePair("appid", req.appId));            signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));            signParams.add(new BasicNameValuePair("package", req.packageValue));            signParams.add(new BasicNameValuePair("partnerid", req.partnerId));            signParams.add(new BasicNameValuePair("prepayid", req.prepayId));            signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));            //再次签名            req.sign = genAppSign(signParams);        }
  • 发起支付。

     msgApi.sendReq(req);
  • 回调支付结果
    在包名路径下创建新的文件夹wxapi,并在此文件夹下创建WXPayEntryActivity类,注意:文件夹名称和类名称必须按照这样命名,否则会导致无法回调。在类中实现onResp方法,支付完成后微信APP会返回到我们的APP上,并回调此方法。我们要做的就是在这个方法中接收通知,判断返回码,如果支付成功则将返回结果发送给后台服务器,查询支付结果再向用户展示实际支付结果。千万要记住:不能以APP返回的结果作为用户支付的结果,要以后台服务器接收的异步通知或从后台查询得知的结果位准。

    这里写图片描述

  相关解决方案