微信

一、前期准备

  • 在开放平台的“开发者引用登记界面”申请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返回的结果作为用户支付的结果,要以后台服务器接收的异步通知或从后台查询得知的结果位准。

更多相关文章

  1. Android两个Activity传递数据,onActivityResult获取结果时Intent
  2. Android(安卓)windowTranslucentStatus属性源码分析
  3. 分析Activity的View绑定过程
  4. android 视图结构 呈现给用户的视图
  5. 字节跳动面试官:Android源码的Binder权限是如何控制?
  6. android事件分发(三)重要的函数requestDisallowInterceptTouchEven
  7. Android中onActivityResult方法总结
  8. [置顶] Android输入法框架
  9. android中fragment在后台回收时的生命周期

随机推荐

  1. android 源码下载 ARM/x86架构
  2. android中访问时的localhost问题
  3. Android(安卓)ListView详解
  4. google maps api 地址
  5. Android(安卓)Activity界面切换添加动画
  6. android 服务前台运行startForeground
  7. 第一节(搭建环境)
  8. Android系统信息获取
  9. android中GridView关于间距的属性值介绍
  10. android工具链与GNU工具链的比较