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…”导入到工程中。如图:
      android中关于微信支付流程的总结_第1张图片
    • 【AndroidStudio项目】选中项目,按“F4”调出“Project Sructure”窗口,添加jar包到项目中。如图:
      android中关于微信支付流程的总结_第2张图片

      android中关于微信支付流程的总结_第3张图片

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

            <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将支付结果发送给后台服务器,查询支付结果, 获取实际支付结果,并展示结果。

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

    android中关于微信支付流程的总结_第4张图片

三、项目集成【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返回的结果作为用户支付的结果,要以后台服务器接收的异步通知或从后台查询得知的结果位准。

    android中关于微信支付流程的总结_第5张图片

你可能感兴趣的:(支付,android,微信)