Android接入微信支付踩过的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lkjfyy/article/details/77371004

最近公司项目要用到微信支付,看了官方文档,发现好多坑,按着他们的步骤来,十有八九会栽在那,于是,记录下我踩得坑,免得以后再摔跟头。

强烈吐槽:微信开发文档写的不是一般的糟心!好了,废话不多说了,开始正文:

一、前期准备工作:

首先去微信开放平台默认你已经注册了微信开发平台账号,微信支付需要开发者资质验证好像是300大洋大笑,一般由公司提供账号)创建应用,如下图,在管理中心创建应用,按提示操作进行就行,没什么难的


其中最重要的就是你填写的包名一定要跟你要集成的APP的包名一致,也就是你项目下,AndroidManifest文件下的pakage或者build.gradle文件下的applicationid,如下图:



然后需要在手机上安装你的APP和微信提供的获取签名的工具,输入上述包名,拿到签名,然后微信会分配给你AppID和AppSecret。

微信支付需要你还要再申请一次,过程省略了,按照官方说明就行,很简单的;

二、微信支付接入(默认已拿到所有的微信支付所需的信息,比如商户号,商户秘钥等)

不知道公司什么逻辑,把微信支付的所有的逻辑全写在客户端了,建议提交订单给微信端,获取微信预支付订单的操作在后台完成!

1、统一下单,拿到微信预支付订单

//调用微信支付
private void wxPay() {
    String ipAddress= NetUtils.getIPAddress(this).trim();//获取本机ip地址
    String random=MD5Util.mCreateRandom().trim();//生成随机数
    int total_fee= (int) (money*100);
    String stringA="appid="+Constants.APP_ID+"&body="+text+"&mch_id="+Constants.mch_id+"&nonce_str="+random+
            "&notify_url=http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php&out_trade_no="+orderID+
            "&spbill_create_ip="+ipAddress+"&total_fee="+total_fee+"&trade_type=APP";
    String stringSignTemp=stringA+"&key="+Constants.key;//注:key为商户平台设置的密钥key
    String sign=MD5Util.md5(stringSignTemp).toUpperCase(); //注:MD5签名方式
    Log.e("获取stringSignTemp",stringSignTemp);
    Log.e("获取签名:",sign);
    Log.e("获取随机数:",random);
    String xml="<xml>\n" +
            "   <appid>"+Constants.APP_ID+"</appid>\n" +
            "   <body>"+text+"</body>\n" +
            "   <mch_id>"+Constants.mch_id+"</mch_id>\n" +
            "   <nonce_str>"+random+"</nonce_str>\n" +
            "   <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>\n" +
            "   <out_trade_no>"+orderID+"</out_trade_no>\n" +
            "   <spbill_create_ip>"+ipAddress+"</spbill_create_ip>\n" +
            "   <total_fee>"+total_fee+"</total_fee>\n" +
            "   <trade_type>APP</trade_type>\n" +
            "   <sign>"+sign+"</sign>\n" +
            "</xml>";
    if (TextUtils.isEmpty(ipAddress)){
        ShowUtil.mToast(_this,"当前无网络连接");
    }else {
        Log.e("获取ip地址:",ipAddress);
        OkGo.<String>post(wxPayUrl)
                .tag(this)
                .upString(xml, MediaType.parse("application/xml"))
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        String result=response.body().trim();
                        Map<String,String> map=XmlToMap.decodeXml(result);//把微信返回的xml封装进map
                        String prepay_id=MapUtils.get(map,"prepay_id","");//获取微信预支付订单
                        Log.e("微信支付请求结果:",result);
                        Log.e("获取微信预支付订单:",prepay_id);
                        if (TextUtils.isEmpty(prepay_id)){
                            ShowUtil.mToast(_this,"微信提交订单失败");
                        }else {
                            sendWXPayRep(prepay_id);//调起微信支付页面
                        }
                    }

                    @Override
                    public void onError(Response<String> response) {
                        super.onError(response);
                    }
                });
    }
}

这里要看清每个字段的名称,大小写都不要错,排序也不要错,否则拿不到预支付订单

2、调起微信支付界面

这里要用到一个类WXPayEntryActivity,这个类从官方提供的文档里复制过来用就行,但是注意一定要放在wxapi包下,wxapi包一定要放在你建项目的根包下,一定不能错,否则调不起!!!注意别忘记在AndroidManifest里注册WXPayEntryActivity!

//调起微信支付页面
private void sendWXPayRep(String prepayId) {

    String timeStamp=MD5Util.getTimeStamp()+"";
    Log.e("时间戳:",timeStamp);
    String random=MD5Util.mCreateRandom().trim();
    String stringA="appid="+Constants.APP_ID+"&noncestr="+random+"&package=Sign=WXPay&partnerid="+Constants.mch_id+
            "&prepayid="+prepayId+"&timestamp="+timeStamp;
    String stringSignTemp=stringA+"&key="+Constants.key;//注:key为商户平台设置的密钥key
    String sign=MD5Util.md5(stringSignTemp).toUpperCase(); //注:MD5签名方式

    //注册到微信
    IWXAPI api= WXAPIFactory.createWXAPI(this, Constants.APP_ID);
    api.registerApp(Constants.APP_ID);
    //设置商品信息
    PayReq payReq=new PayReq();
    payReq.appId=Constants.APP_ID;
    payReq.partnerId=Constants.mch_id;
    payReq.prepayId=prepayId;
    payReq.packageValue = "Sign=WXPay";
    payReq.nonceStr=random ;
    payReq.timeStamp=timeStamp;
    payReq.sign= sign;
    api.sendReq(payReq);
}

注意这里获取签名时,拼接的字段名跟要传递的参数字段名并不一致(坑),如appid并不是appId,partnerid并不是partnerId;

到这里应该能成功调起微信支付界面了,这个activity界面可以自己定义,自己布置view就行。

祝君成功!!!


猜你喜欢

转载自blog.csdn.net/lkjfyy/article/details/77371004