微信-App支付 java服务器端

来源:互联网 发布:绝地求生罗技g502编程 编辑:程序博客网 时间:2024/05/16 13:48

1.相关变量设置:

微信支付相关配置
应用appid(在开发者中心设置)
wx.appid=wxe754*****b7
商户号(在开发者中心设置)
wx.mchid=1488***152
支付密钥((在开发者中心设置)长度32)
wx.apikey=mCuqsC********susvLa
统一下单接口,这里不需要修改,由系统自动调用
wx.uniurl=https://api.mch.weixin.qq.com/pay/unifiedorder

2.统一下单部分代码:

    /***     * 微信统一下单     *     *@param request     *@param response     *@throws IOException     *@throws JDOMException     *@date: 2017年9月1日     *@author: smallz     *     */    @RequestMapping("/prePay")    public void wxPrePay(String data, HttpServletRequest request,            HttpServletResponse response) {        Map<String, Object> resultMap = new HashMap<String, Object>();        StatusData statusObject = null;        JsonModel jsonModel = new JsonModel();        jsonModel.setHeaderValue("flag", "0");        SortedMap<Object, Object> parameterMap2 = new TreeMap<Object, Object>();        // jsonModel.setHeaderValue("flag", "0");        if (requestHandle(data, jsonModel) == true) {            try {                //支付类型                Integer payType=Integer.valueOf(jsonModel.getBodyValue("payType"));                Long memberId=Long.valueOf(jsonModel.getBodyValue("memberId"));                String orderId="";                String body="";                String price="";                String noncestr=WeChatUtils.CreateNoncestr();                if(payType.equals(WeChatPayTypeEnum.serviceFee.getStatus())){//服务费                    //计算服务费规则                    orderId=jsonModel.getBodyValue("orderId");                    body=WeChatPayTypeEnum.serviceFee.getName();                    price=PropertiesUtil.getPropertiesValue("serviceFeeCost");                }else if(payType.equals(WeChatPayTypeEnum.transaction.getStatus())///交易会员                        ){                    orderId=String.valueOf(System.currentTimeMillis());                    price=PropertiesUtil.getPropertiesValue("trascationFeeCost");                    body=WeChatPayTypeEnum.transaction.getName();                }else if(payType.equals(WeChatPayTypeEnum.limitInFee.getStatus())){//准入金                    orderId=jsonModel.getBodyValue("orderId");                    body=WeChatPayTypeEnum.limitInFee.getName();                    price=PropertiesUtil.getPropertiesValue("limitInFeeCost");                }else if(payType.equals(WeChatPayTypeEnum.orderFee.getStatus())){//订单结算                    orderId=jsonModel.getBodyValue("orderId");                    body=/*"2401_"+*/WeChatPayTypeEnum.orderFee.getName();                    //价格先写死                    price=PropertiesUtil.getPropertiesValue("limitInFeeCost");                }                int price100 = new BigDecimal(price).multiply(                        new BigDecimal(100)).intValue();                if (price100 <= 0) {                    statusObject = AppInteractiveState.MONEY_FMT_ERROR;                    returnJson(response, statusObject, resultMap);                    return;                }                LogUtils.info(getClass(), "===此次预支付的订单Id==="+orderId);                LogUtils.info(getClass(), "===此次预支付的订单内容==="+body);                LogUtils.info(getClass(), "===此次预支付的订单价格==="+price100);                // 设置回调地址-获取当前的地址拼接回调地址                String url = request.getRequestURL().toString();                String domain = url.substring(0, url.length() - 9);                System.out.println("====微信回调URL:"+domain+"wxNotify.do");                // 测试、正式环境                 String notify_url= domain+"wxNotify.do";                SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();                //封装请求参数                setSignParameters(request, jsonModel, price100, notify_url,                        parameters,orderId,body,WeChatUtils.CreateNoncestr(),payType,memberId);                // 封装请求参数结束                String requestXML = WeChatUtils.getRequestXml(parameters);                // 调用统一下单接口                String result = WeChatUtils.httpsRequest(UNI_URL, "POST", requestXML);                LogUtils.info(getClass(), "===请求微信统一支付返回结果===:");                LogUtils.info(getClass(),result);                //System.out.println("\n" + result);                try {                    /**                     * 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。                     * 参与签名的字段名为appId                     * ,partnerId,prepayId,nonceStr,timeStamp,package                     * 。注意:package的值格式为Sign=WXPay                     **/                    Map<String, String> map = XMLUtil.doXMLParse(result);                    if (map.get("return_code").equals("SUCCESS")) {                        statusObject = new StatusData(                                Integer.valueOf(AppInteractiveState.SUCCESS),                                "请求统一下单成功!");                    } else {                        statusObject = new StatusData(                                Integer.valueOf(AppInteractiveState.ERROR_BUSINESS),                                "请求统一下单失败!");                        LogUtils.error(getClass(), "微信统一下单错误,return_msg:"+map.get("return_msg"));                        returnJson(response, statusObject, resultMap);                        return;                    }                    //System.out.println(map);                    // parameterMap2 = new TreeMap<Object, Object>();                    parameterMap2.put("appid", APPID);                    //parameterMap2.put("attach", "*****");//这里二次签名无需对attach再签名(不然就是支付验证签名失败,本人已经填坑)                    parameterMap2.put("partnerid", MCH_ID);                    parameterMap2.put("prepayid", map.get("prepay_id"));                    parameterMap2.put("package", "Sign=WXPay");//这个key(package),绝对不能改,为了图方便我以为能省去parameterMap2.put("packageValue", "Sign=WXPay");这一句代码,结果填了一坑,导致签名失败。                    parameterMap2.put("noncestr", WeChatUtils.CreateNoncestr());                    // 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下                    parameterMap2.put(                            "timestamp",                            Long.parseLong(String                                    .valueOf(System.currentTimeMillis())                                    .toString().substring(0, 10)));                    //这里是二次签名                    String sign2 = WeChatUtils.createSign("UTF-8",parameterMap2);                    parameterMap2.put("tradeNo", orderId);                    //避免安卓package关键字字段                    parameterMap2.put("packageValue", "Sign=WXPay");                    parameterMap2.put("sign", sign2);                    System.out.println("二次签名参数:———————"+parameterMap2);                } catch (JDOMException e) {                    e.printStackTrace();                } catch (IOException e) {                    e.printStackTrace();                }            } catch (Exception e) {                e.printStackTrace();            }        }        //将统一下单的map返回给客户端        returnJson(response, statusObject, parameterMap2);    }    //生成签名    private void setSignParameters(HttpServletRequest request,            JsonModel jsonModel, int price100, String notify_url,            SortedMap<Object, Object> parameters,String orderId,String body,String dateStr,Integer payType,Long memberId) {        parameters.put("appid", APPID);        parameters.put("attach", payType+"|"+memberId+"|"+orderId);        parameters.put("mch_id", MCH_ID);        parameters.put("nonce_str",dateStr);        parameters.put("body", body);        parameters.put("out_trade_no",orderId); // 订单id        parameters.put("fee_type", "CNY");        parameters.put("total_fee", String.valueOf(price100));        //本机测试Ip        //parameters.put("spbill_create_ip", "220.202.152.37");        parameters.put("spbill_create_ip", getIpAddr(request));        parameters.put("notify_url", notify_url);        parameters.put("trade_type", "APP");        // 设置签名        String sign = WeChatUtils.createSign("UTF-8", parameters);        parameters.put("sign", sign);    }    /***     * 微信异步回调方法     *     *@param request     *@param response     *@throws IOException     *@throws JDOMException     *@date: 2017年9月1日     *@author: smallz     *     */    @SuppressWarnings("unchecked")    @RequestMapping("/wxNotify")    public void wxNotify(HttpServletRequest request,            HttpServletResponse response/*,String data*//*调试用*/) throws IOException, JDOMException {        try {        // 读取参数        InputStream inputStream;        StringBuffer sb = new StringBuffer();        inputStream = request.getInputStream();        String s;        BufferedReader in = new BufferedReader(new InputStreamReader(                inputStream, "UTF-8"));        while ((s = in.readLine()) != null) {            sb.append(s);        }        in.close();        inputStream.close();        // 解析xml成map        Map<String, String> m = new HashMap<String, String>();        m = XMLUtil.doXMLParse(sb.toString());        System.out.println("微信服务器返回的xml:"+sb.toString());        //m = XMLUtil.doXMLParse(data);        for (Object keyValue : m.keySet()) {            System.out.println(keyValue + "=" + m.get(keyValue));        }        // 过滤空 设置 TreeMap        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();        Iterator it = m.keySet().iterator();        while (it.hasNext()) {            String parameter = (String) it.next();            String parameterValue = m.get(parameter);            String v = "";            if (null != parameterValue) {                v = parameterValue.trim();            }            packageParams.put(parameter, v);        }        // 判断签名是否正确        String resXml = "";        if (WeChatUtils.isTenpaySign("UTF-8", packageParams)) {            LogUtils.info(this.getClass(), "签名校验成功,信息合法,未被篡改过");            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {                String mch_id = (String) packageParams.get("mch_id"); // 商户号                String openid = (String) packageParams.get("openid"); // 用户标识                String out_trade_no = (String) packageParams                        .get("out_trade_no"); // 商户订单号                String total_fee = (String) packageParams.get("total_fee");                String transaction_id = (String) packageParams                        .get("transaction_id"); // 微信支付订单号                WxPayResult trade = null;                //比对app端的数据(金额、商户号...)                if (!MCH_ID.equals(mch_id)                        || trade == null                        || new BigDecimal(total_fee).compareTo(new BigDecimal(                                trade.getTotal_fee()).multiply(new BigDecimal(                                100))) != 0) {                    LogUtils.error(this.getClass(), "支付失败,错误信息:"                            + packageParams.get("err_code"));                    resXml = "<xml>"                            + "<return_code><![CDATA[FAIL]]></return_code>"                            + "<return_msg><![CDATA[通知支付失败]]></return_msg>"                            + "</xml> ";                }             } else {                System.out.println("支付成功");                LogUtils.info(getClass(), "支付成功");                resXml = "<xml>"                        + "<return_code><![CDATA[SUCCESS]]></return_code>"                        + "<return_msg><![CDATA[OK]]></return_msg>"                        + "</xml> ";            }            // 保存微信支付信息            try {                wxPayResultService.savePayResult(packageParams);            } catch (Exception e) {                // TODO: handle exception            }            // ------------------------------            // 处理业务完毕            // ------------------------------            BufferedOutputStream out = new BufferedOutputStream(                    response.getOutputStream());            out.write(resXml.getBytes());            out.flush();            out.close();        }else {            resXml = "<xml>"                    + "<return_code><![CDATA[FAIL]]></return_code>"                    + "<return_msg><![CDATA[通知签名验证失败]]></return_msg>"                    + "</xml> ";            LogUtils.error(this.getClass(), "通知签名验证失败");        }    } catch (Exception e) {        e.printStackTrace();        LogUtils.error(getClass(), "异步交互异常:"+e.getMessage());    }    }   

如有不妥之处 请指出。

原创粉丝点击