Android集成微信支付主要步骤和特别需要注意的问题

来源:互联网 发布:SQL是面向问题的语言吗 编辑:程序博客网 时间:2024/04/28 01:35

一:介绍

大家在商城类等需要支付功能的项目中,一般需要集成支付宝和微信支付,集成支付宝比较简单,官方文档清晰明了.但是相比于支付宝,微信支付就显得坑爹得多,下面说一下微信支付的主要步骤和特别需要注意的问题,首先声明博客里没用官方的demo,官方demo的参数都是从服务器得到的,而有的公司的服务器并没有对微信进行集成,发起微信支付所需要的参数比如prepay_id是在客户端集成的,前面一种情况就是发起网络请求获取json,进行解析就可以从服务器得到所需要的各项参数,比较简单.这篇博客主要针对后面一种情况!同时,错误之处也希望大家批评指正!


二:集成微信支付的主要步骤


1.先贴一下demo的结构图



2.介绍项目结构

(1).demo结构图中,微信的功能都在wxapi包下,在这里请大家注意,WXPayEntryActivity这个activity必须要在wxapi包下,否则微信支付后没有回调结果.微信支付的结果会在这个activity中的onReq函数中回调,大家根据项目需要重写onResp方法即可.同时微信官方文档指出,安卓客户端不能以微信的回调结果作为判断依据,而是要根据公司的服务器订单信息根据订单是否支付成功来作为支付是否成功的依据.

(2).Constants类中放置了APP_ID(微信分配的公众账号ID),MCH_ID(微信支付分配的商户号),API_KEY(API秘钥,在商户平台上设置)这三个参数

(3).MD5,MD5Utils,Utils这三个类不用修改,PayActivity这个activity就是支付界面,大家可根据项目修改支付界面


3.支付的主要步骤

(1).先生成与支付订单prepay_id

(2).生成签名参数

(3).发起支付


4.对3中的各个步骤逐一说明

(1)先提交支付的各种参数,这一步骤微信推荐在服务器端完成,但是如果公司没有完成这一步,那就必须我们在安卓端完成了.首先开启一个异步任务,根据官方的文档点击打开官方文档发起请求,在异步任务的doInBackground方法中完成生成商品参数的任务,核心代码如下:(demo会在博客末尾贴出下载地址)

@Override        protected Map<String, String> doInBackground(Void... params) {            String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");            String entity = genProductArgs();            Log.e("orion", entity);            byte[] buf = Util.httpPost(url, entity);            String content = new String(buf);            Log.e("orion", content);            Map<String, String> xml = decodeXml(content);            return xml;        }
下面是生成商品参数的方法

private String genProductArgs() {        StringBuffer xml = new StringBuffer();        try {            String nonceStr = genNonceStr();            xml.append("</xml>");            List<NameValuePair> packageParams = new LinkedList<>();            packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));//微信分配的公众账号ID            packageParams.add(new BasicNameValuePair("body", "APP pay test"));//商品或支付单简要描述            packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));//微信支付分配的商户号            packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));//随机字符串,不长于32位。推荐随机数生成算法            packageParams.add(new BasicNameValuePair("notify_url", "http://121.40.35.3/test"));//接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。            packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo()));//商户系统内部的订单号            packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));//APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP            packageParams.add(new BasicNameValuePair("total_fee", "1"));//订单总金额,单位为分            packageParams.add(new BasicNameValuePair("trade_type", "APP"));//交易类型            String sign = genPackageSign(packageParams);            packageParams.add(new BasicNameValuePair("sign", sign));//签名            String xmlstring = toXml(packageParams);            return xmlstring;        } catch (Exception e) {            Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());            return null;        }    }

(2).第二步就是生成签名参数,主要是生成与支付订单prepay_id

private void genPayReq() {        req.appId = Constants.APP_ID;//公众账号ID        req.partnerId = Constants.MCH_ID;//商户号        req.prepayId = resultunifiedorder.get("prepay_id");//预支付交易会话ID        req.packageValue = "prepay_id=" + resultunifiedorder.get("prepay_id");//暂填写固定值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);//签名        sb.append("sign\n" + req.sign + "\n\n");        show.setText(sb.toString());        Log.e("orion", signParams.toString());    }

(3)然后第三步就是发起微信支付了,请注意支付之前要把app注册到微信

msgApi.registerApp(Constants.APP_ID);<pre name="code" class="java" style="color: rgb(34, 34, 34);font-size:10px; line-height: 22.4px;">msgApi.sendReq(req);

三:特别需要注意的问题,都是我碰到的坑

(1)上面的红色标注是需要大家注意的地方

(2)微信支付的支付金额单位是分,不同于支付宝的支付金额单位(元),大家需要对分转换成元,因为订单金额是int型,所以转换步骤比较多,贴代码

goods_price = ((int) ((Double.parseDouble(goods_price)) * 100)) + "";//分转换为元


(3)微信支付的商品描述如果是中文,则需要对中文进行转码,或者把商品描述改成英文

(4)就是测试微信支付的时候,如果打印的日志没有签名错误,则说明签名没有问题.但是要真正支付的话就要用keystore打包签名出来进行测试,debug测试是不会调出支付界面的

(5)待定


四:demo下载地址


地址:点击下载demo 这篇博客先到这,谢谢大家!






0 1