您好,欢迎来到源码搜藏!分享精神,快乐你我!提示:担心找不到本站?在百度搜索“源码搜藏”,网址永远不丢失!
  • 首 页
  • 在线工具
  • jquery手册
  • 当前位置:首页 > 安卓源码 > VIP源码 > 安卓应用 >

    Android开发微信app支付(android端+java后台)实例源码

    时间:2018-01-27 11:57 来源:互联网 作者:源码搜藏 浏览:收藏 挑错 推荐 打印

    本文讲解使用微信支付接口完成在android开发的原生态app中完成微信支付功能, 文章具体讲解了前端android如何集成微信支付功能以及后台如何组装前端需要支付信息, 话不多话, 具体看文章内容吧

    本实例项目运行条件:

    开发环境: 【Android Studio】

    1. 到微信开放平台注册帐号并且创建移动应用

       https://open.weixin.qq.com/cgi-bin/frame?t=home/app_tmpl&lang=zh_CN

    blob.png

     

    2. 获得移动应用的权限【微信支付】

       这个权限要求比较高,需要公司资质 并且 每年需要支付300元 才能开通 (这里不作讲解, 具体到官网上申请)

    blob.png

     

    3. 配置应用签名, 这个签名通过 android打包文件jks生成或者keystore生成    【如何生成jks文件】

       签名文件生成方法: 

       3.1  keytool -list -v -keystore jks文件(或者keystore文件)

       3.2 获取指纹证书md5值, 将md5中的冒号去掉, 大写换成小写   (详情)

       总结: 微信开放平台Android应用签名的本质便是我们签名文件jks(或者keystore)的MD5值

    blob.png

    4. 配置支付密钥, 【如何配置密钥】    【微信配置密钥官网】

      blob.png

     

    5. 应用程序开发完成后,debug模式是无法完成支付的,应用程序必须由相应的jks签名之后生成的apk包安装在手机上才能进行分支付(微信会校验应用签名)

     

    2. 支付流程讲解

    2.1 android程序启动后如下第一张图, 点击【确认支付】

      2.1.1 android端向后台请求获得预支付信息

      2.1.2 后台根据微信官网平台上的 配置信息 加上 订单信息 生成预支付信息

      2.1.3 android端根据预支付信息 拉起微信支付页面进行支付(见下面第二张图)

     

    blob.png              blob.png

     

    3. 代码详解(Android端)

    3.1 在android studio中引入 微信需要使用的jar包

        blob.png

     

    3.2 在android工程对应的包名下面新建 包以及类, wxapi/WXPayEntryActivity

    blob.png

     

    在AndroidManifest.xml中引用 WXPayEntryActivity

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <application
        android:allowBackup="true"
        android:icon="@drawable/desk"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            android:screenOrientation="portrait"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
        </activity>
     
        <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:screenOrientation="portrait"
            android:exported="true"
            android:launchMode="singleTop"/>
    </application>

     

    WXPayEntryActivity 代码详情(支付完成后,onResp会被调用,BaseResp.ErrCode.ERR_OK 表明支付成功)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
     
        private static final String TAG = "WXPayEntryActivity";
     
        private IWXAPI api;
     
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
     
            Constant.wxApi.handleIntent(getIntent(), this);
        }
     
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
            api.handleIntent(intent, this);
        }
     
        @Override
        public void onReq(BaseReq req) {
        }
     
        /**
         * 得到支付结果回调
         */
        @Override
        public void onResp(BaseResp resp)
        {
            Log.i(TAG, "onPayFinish, errCode = " + resp.errCode);
     
            String strPayResult = "";
            switch (resp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    Toast.makeText(this, "付款成功!", Toast.LENGTH_SHORT).show();
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL:
                    //分享取消
                    //Toast.makeText(this, "付款取消!", Toast.LENGTH_SHORT).show();
                    //Constant.WEIXIN_PAY_STATUS = "PAY_CANCEL";
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED:
                    //分享拒绝
                    //Toast.makeText(this, "付款拒绝!", Toast.LENGTH_SHORT).show();
                    //Constant.WEIXIN_PAY_STATUS = "PAY_DENY";
                    break;
            }
     
            //向之前页面返回支付结果信息
            /*Intent intent = new Intent();
            intent.putExtra("payResult", strPayResult);
            setResult(100, intent);*/
            finish();
        }
    }

     

    3.3 支付按钮的点击事件

        通过http协议向后台请求相应的预支付信息, 根据这些信息组装相应的信息来调用微信接口, 拉起微信支付界面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    @OnClick(R.id.pay)
    public void pay(){
        String orderNum = OrderInfo.generateOutTradeNo();
        payService
                .wpay(orderNum, totalPrice, address.getText().toString() + "-外卖订单")
                .subscribe(new Action1<WeiXinPrePay>() {
                    @Override
                    public void call(WeiXinPrePay payInfo) {
                        if (Constant.wxApi != null) {
                            PayReq req = new PayReq();
                            req.appId = payInfo.getAppId();// 微信开放平台审核通过的应用APPID
                            req.partnerId = payInfo.getMchId();// 微信支付分配的商户号
                            req.prepayId = payInfo.getPrepayId();// 预支付订单号,app服务器调用“统一下单”接口获取
                            req.nonceStr = payInfo.getNonceStr();// 随机字符串,不长于32位,服务器小哥会给咱生成
                            req.timeStamp = payInfo.getTimeStamp();// 时间戳,app服务器小哥给出
                            req.packageValue = "WXPay";// 固定值Sign=WXPay,可以直接写死,服务器返回的也是这个固定值
                            req.sign = payInfo.getPaySign();// 签名,服务器小哥给出,他会根据:                                                   om/wiki/doc/api/app/app.php?chapter=4_3指导得到这个
                            Constant.wxApi.sendReq(req);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        showToast(throwable.getMessage());
                    }
                });
    }

     

    4 微信支付Java后台

    4.1 后台代码结构图

        blob.png

     

    4.2 微信配置信息 Config.properties

    blob.png

     

    4.3 方法wxpay用于生成预支付订单信息

        方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码) 

    在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的其它回调就不需要再次处理了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    @Controller
    @RequestMapping("/pay")
    public class PayController {
        
        String timeMillis = String.valueOf(System.currentTimeMillis() / 1000);
        String randomString = PayCommonUtil.getRandomString(32);
        //支付成功后的回调函数
        public static String wxnotify = "http://gepanjiang.hk1.tunnelfrp.cc/WxPay/pay/notifyWeiXinPay.htm";
        
        public PayController() {
            System.out.println("MainController构造函数");
        }
        
        
        /**
         * @param totalAmount    支付金额
         * @param description    描述
         * @param request
         * @return
         */
        @RequestMapping(value = "/wxpay.htm", produces = MediaType.APPLICATION_JSON_VALUE)
        @ResponseBody    
        public Result wxpay(HttpServletRequest request) {
            Result result = new Result();
            Long userId = new Long(1);//baseController.getUserId();
           
            BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));
            String trade_no = "";
            String description="";
            try {
                trade_no = new String(request.getParameter("orderNum").getBytes("ISO-8859-1"),"UTF-8");
                description = request.getParameter("description");
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String openId = "";
            
            Map<String, String> map = weixinPrePay(trade_no,totalAmount,description,openId,request);  
            SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
            finalpackage.put("appId", ConfigManager.getInstance().getConfigItem("WXAppID")/*PayCommonUtil.APPID*/); 
            finalpackage.put("mchId", ConfigManager.getInstance().getConfigItem("MCH_ID"));
            Long time = (System.currentTimeMillis() / 1000);  
            finalpackage.put("timeStamp", time.toString());
            finalpackage.put("nonceStr", map.get("nonce_str"));
            finalpackage.put("prepayId", map.get("prepay_id"));
            finalpackage.put("package", "Sign=WXPay");
            finalpackage.put("signType", "MD5");
            String sign = PayCommonUtil.createSign("UTF-8", finalpackage);  
            finalpackage.put("paySign", sign);//官方文档上是sign,当前示例代码是paySign 可能以前的
            
            WeiXinPrePay prePay = new WeiXinPrePay();
            prePay.setAppId(ConfigManager.getInstance().getConfigItem("WXAppID"));
            prePay.setMchId(ConfigManager.getInstance().getConfigItem("MCH_ID"));
            prePay.setTimeStamp(time.toString());
            prePay.setNonceStr(map.get("nonce_str"));
            prePay.setPrepayId(map.get("prepay_id"));
            prePay.setSignType("MD5");
            prePay.setPaySign("paySign");
            result.setData(prePay);
            result.setStateCode(GeneralConstant.SUCCESS);
            result.setDesc("微信支付加载成功");
            
            return result;
        } 
     
        
        /**
         * 统一下单 
         * 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
         * @param trade_no
         * @param totalAmount
         * @param description
         * @param openid
         * @param sym
         * @param request
         * @return
         */
        @SuppressWarnings("unchecked")
        public Map<String, String> weixinPrePay(String trade_no,BigDecimal totalAmount,  
                String description, String openid, HttpServletRequest request) { 
            SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();  
            parameterMap.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID"));  //应用appid 
            parameterMap.put("mch_id", ConfigManager.getInstance().getConfigItem("MCH_ID")/*PayCommonUtil.MCH_ID*/);  //商户号
            //parameterMap.put("device_info", "WEB");
            parameterMap.put("nonce_str", randomString);  
            parameterMap.put("body", description);
            parameterMap.put("out_trade_no", trade_no);
            parameterMap.put("fee_type", "CNY");  
            System.out.println("jiner");  
            BigDecimal total = totalAmount.multiply(new BigDecimal(100));  //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100
            java.text.DecimalFormat df=new java.text.DecimalFormat("0");  
            parameterMap.put("total_fee", df.format(total));  
            System.out.println("jiner2");  
            parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));  
            parameterMap.put("notify_url", wxnotify);
            parameterMap.put("trade_type", "APP");//"JSAPI"
            //trade_type为JSAPI是 openid为必填项
            //parameterMap.put("openid", openid);
            System.out.println("");  
            String sign = PayCommonUtil.createSign("UTF-8", parameterMap); 
            System.out.println("jiner2");  
            parameterMap.put("sign", sign);  
            String requestXML = PayCommonUtil.getRequestXml(parameterMap);  
            System.out.println(requestXML);  
            String result = PayCommonUtil.httpsRequest(  
                    "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",  
                    requestXML);  
            System.out.println(result);  
            Map<String, String> map = null;  
            try {  
                map = PayCommonUtil.doXMLParse(result);  
            } catch (JDOMException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            return map;        
        }
        
        
     
        /**
         * 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行
         * @param request
         * @param response
         * @return
         * @throws IOException
         * @throws JDOMException
         */
        @RequestMapping(value = "notifyWeiXinPay.htm", produces = MediaType.APPLICATION_JSON_VALUE)
       // @RequestDescription("支付回调地址")
        @ResponseBody
        public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
            System.out.println("微信支付回调");
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            String resultxml = new String(outSteam.toByteArray(), "utf-8");
            Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);
            outSteam.close();
            inStream.close();
            
            
            Map<String,String> return_data = new HashMap<String,String>();  
            if (!PayCommonUtil.isTenpaySign(params)) {
                // 支付失败
                return_data.put("return_code", "FAIL");  
                return_data.put("return_msg", "return_code不正确");
                return StringUtil.GetMapToXML(return_data);
            } else {
                System.out.println("===============付款成功==============");
                // ------------------------------
                // 处理业务开始
                // ------------------------------
                // 此处处理订单状态,结合自己的订单数据完成订单状态的更新
                // ------------------------------
     
                String total_fee = params.get("total_fee");
                double v = Double.valueOf(total_fee) / 100;
                String out_trade_no = String.valueOf(Long.parseLong(params.get("out_trade_no").split("O")[0]));
                Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");
                String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
                String totalAmount = String.valueOf(v);
                String appId = params.get("appid");
                String tradeNo = params.get("transaction_id");
            
                return_data.put("return_code", "SUCCESS");  
                return_data.put("return_msg", "OK");  
                return StringUtil.GetMapToXML(return_data);
            }
        }
     
    }

    Android开发微信app支付(android端+java后台)实例源码转载请注明出处http://www.codesocang.com/appvip-yy/38394.html 源码搜藏网所有源码来自用户上传分享,版权问题及牵扯到商业纠纷均与源码搜藏网无关
    标签: