微信支付第一弹(扫码支付Java)

版权声明:觉得还行的小伙伴,希望留个赞 https://blog.csdn.net/qq_37345604/article/details/79742324

应用场景

    随着互联网发展,众多网站都链接了微信、支付宝等支付方式,今天讲的是本人在做微信支付扫码支付时所遇到的坑,自我感觉比其他一些文档讲解的细致多,有用就拿去,没用也别喷,谢谢、



下单支付

可以先看一下文档,有个基本认知:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1

1、必备条件

首先你要要申请一个公共账号,最好申请的时候就是服务号,因为微信支付的前提必须是服务号

如果是公众号需要先申请验证才能升级为服务号。

1.1、微信服务号申请地址:

http://www.weixinvip888.com/index.php?s=/index/wx.html

1.2、扫码支付流程

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1

2、引入相关的jar包(此章讲解的扫码支付模式二)

<!-- 生成二维码所需的jar包 开始 -->
        <dependency>
              <groupId>com.uqihong</groupId>
              <artifactId>qdcode</artifactId>
              <version>1.0.0</version>
        </dependency>
        <dependency>
              <groupId>com.uqihong</groupId>
              <artifactId>qdcodeSwetake</artifactId>
              <version>1.0.0</version>
        </dependency>
        <!-- 生成二维码所需的jar包 结束 -->
    <!-- 微信支付需要的jar包 -->
        <dependency>
            <groupId>xmlpull</groupId>
            <artifactId>xmlpull</artifactId>
            <version>1.1.3.1</version>
        </dependency>
        <dependency>
            <groupId>xpp3</groupId>
            <artifactId>xpp3</artifactId>
            <version>1.1.4c</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>fluent-hc</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient-cache</artifactId>
            <version>4.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.5</version>
        </dependency>
3、微信扫码支付所需参数

public class WeixinPayConfigure {
    /**
     * 域名 项目域名
     */
    public static final String ROOTURL = "http://www.uxuexi.com";
    /**
     * 域名 请求微信时的路径
     */
    public static final String ORDER_ROOTURL = "http://order.uxuexi.com";
    /**
     * 商户id (商户号)
     */
    public static final String MCH_ID = "1111111111";
    /**
     * 公共账号id                       (18位数↓)
     */
    public static final String APPID = "wx111111111111111c";
    /**
     * 应用秘钥(AppSecret)  在公众号平台上找↓
     */
    public static final String APP_SECRET = "f4e04138de2b34b75a645c13a654f815";
    /**API秘钥*/
    public static final String API_KEY = "shemadongxi1243432sdf3213";
    /**
     * 统一下单URL 
     */
    public static final String PAY_UNIFIED_ORDER_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 微信公众号交易类型 (扫码支付类型:NATIVE,公众号支付类型:JSAPI)
     */
    public static final String TRADE_TYPE = "NATIVE";
    /**
     * 微信支付成功之后的回调 (微信支付成功后调用)
     */
    public static final String NOTIFY_ACTIVITY_URL = ORDER_ROOTURL + "/pay/wx/wxnotify.json";
}
4、微信支付操作(这步操作需商品订单创建成功后执行)
     ①、订单创建成功去支付(PC端)
    @At
    public Object gowxPay(@Param("orderId") long orderId, @Param("payPrice") double payPrice) {
                   //此处返回的是二维码
        return weChatPayViewService.getOrCode(orderId);
    }
    ②、获取二维码所需的预支付订单路径   
public Object getOrCode(long orderId) {
        ExceptionUtil.checkId(orderId, "订单id不能为空");
        //获取二维码
        return getWxPayCodeUrl(orderId);
    }
    ③、拼接预支付订单路径
 private String getWxPayCodeUrl(long orderId) {
        OrderEntity order = orderBusinessService.getWithEx(orderId);
        double paymentPrice = order.getPayPrice();
        PayEntity payEntity = dbDao.fetch(PayEntity.class, PAY_SWITCH_KEY);
        if (payEntity.isPay()) {
            paymentPrice = payEntity.getMoney();
        }
        //拼接预支付路径(二维码所需路径)dowithWxReturn():处理微信返回,sendReqGetPreOrder():拼接
        return dowithWxReturn(sendReqGetPreOrder(ConvertUtil.obj2long(orderId), paymentPrice));
    }
    ④、处理微信返回
    private String dowithWxReturn(String result) {
        String codeUrl = "";
        Map<String, Object> weixinPrepayInfo = MapUtil.map();
        try {
                         //解析XML(工具类1)
            weixinPrepayInfo = XMLParser.getMapFromXML(result);
            String return_code = (String) weixinPrepayInfo.get("return_code");
            if ("SUCCESS".equals(return_code)) {
                codeUrl = (String) weixinPrepayInfo.get("code_url");
                //非空判断↓
                if (Util.isEmpty(codeUrl)) {
                    //-----------------------------------对象转换成字符串,(工具类2)↓
                    throw ExceptionUtil.bEx(ConvertUtil.obj2str(weixinPrepayInfo.get("err_code_des")));
                }
                return codeUrl;
            } else {
                throw ExceptionUtil.bEx("预支付失败");
            }
        } catch (Exception e) {
            ExceptionUtil.bEx("调用微信预支付接口出错");
        }
        return codeUrl;
    }  
    ⑤、拼接微信预支付路径所需参数  
 public String sendReqGetPreOrder(long orderId, double payPrice) {
        ExceptionUtil.checkEmpty(orderId, "订单id不能为空");
        int randomNumLength = 32;
        Map<String, Object> params = MapUtil.map();
        //公共账号id
        params.put("appid", WeixinPayConfigure.APPID);
        //商户id
        params.put("mch_id", WeixinPayConfigure.MCH_ID);
        //商品描述
        params.put("body", "优学习课程");
        //设备号
        //ctrl+alt+T
        params.put("device_info", "WEB");
        //随机字符串 产生随机字符串 字符串由26个字母以及数字构成(该方法见工具类↓)
        params.put("nonce_str", RandomUtil.randomString(randomNumLength));
        //订单编号
        params.put("out_trade_no", orderId);
        //金额
        double paymentPrice = payPrice;
        //-----------------------(工具类3)将元为单位的转换为分 (乘100)↓                       
        params.put("total_fee", AmountUtils.changeY2F(paymentPrice));
        //回调地址
        params.put("notify_url", WeixinPayConfigure.NOTIFY_ACTIVITY_URL);
        //公众号交易类型
        params.put("trade_type", WeixinPayConfigure.TRADE_TYPE);
        //签名 (工具类4)
        String sign = Signature.getSign(params, WeixinPayConfigure.API_KEY);
        params.put("sign", sign);
        //---------------(工具类5)
        return HttpRequest.sendPost(WeixinPayConfigure.PAY_UNIFIED_ORDER_API, params);
    }
5、生成二维码
 ①、二维码有两种生成方式,
        一、在后台,用Java编程把微信返回路径解析成二维码打回前端(工具类6)

        二、把微信返回的路径(URL)打回前端,前端生成二维码插件QRCode.js(

            资料:http://code.ciaoca.com/javascript/qrcode/)

②、此章生成二维码则是运用的前端js生成
    注意:记得引入插件   <script src="qrcode.js"></script>
 $ajax.weAjax({
        url:we.vr.order+'/pay/wx/gowxPay.html?orderId='+data,
            data:{},
            success:function(data){
                 $('#qrCode').empty();
                  var qrcode = new QRCode(document.getElementById("qrCode"), data)
                   $wedialog.dialog({
                   title:'微信支付',
                    content:$('.qrCode')
                   });
           }
   })
支付成功
1、当用户扫码支付成功后,微信会调取我们配置的成功后的回调函数
①、调用成功后的回调函数
@At
    @Filters
    public void wxnotify() throws Exception {
        weChatPayViewService.weChatPayViewService();
    }
②、微信提醒,签名校验校验
public void weChatPayViewService() throws Exception {
        HttpServletRequest request = Mvcs.getReq();
        HttpServletResponse response = Mvcs.getResp();
        //获取微信响应的内容
        String responseString = getWeiXinResponseContent(request);
        PrintWriter out = response.getWriter();
        String resp = "";
        String signKey = WeixinPayConfigure.API_KEY;
        //---------------------签名算法,见工具类4
        boolean verify = Signature.checkIsSignValidFromResponseString(responseString, signKey);
        if (!verify) {
            logger.error("签名验证失败");
            resp = "签名验证失败";
            out.write(resp);
            out.close();
            return;
        }
        //解析微信返回的XML文件↓
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        String result_code = ConvertUtil.obj2str(map.get("result_code"));
        if (!"SUCCESS".equalsIgnoreCase(result_code)) {
            //--------------获取响应给微信的xml数据↓(工具类7)
            resp = PayCommonUtil.getResponseXML("ERROR", "ERROR");
            out.write(resp);
            out.close();
            return;
        }
        //签名校验成功,处理订单
        resp = handleOrder(map);
        out.write(resp);
        out.close();
    }
③、处理订单
@Aop("txDb")
    private String handleOrder(Map<String, Object> map) throws Exception {
        //获取响应给微信的xml数据↓
        String resp = PayCommonUtil.getResponseXML("SUCCESS", "OK");
        //微信支付订单↓
        String transaction_id = ConvertUtil.obj2str(map.get("transaction_id"));
        //支付完成时间↓
        String time_end = ConvertUtil.obj2str(map.get("time_end"));
        //商户订单号↓
        String out_trade_no = (String) map.get("out_trade_no");
        //if逻辑,如果上述三个参数为空说明此订单支付失败,直接return
        if (Util.isEmpty(transaction_id) || Util.isEmpty(time_end) || Util.isEmpty(out_trade_no)) {
            resp = PayCommonUtil.getResponseXML("ERROR", "参数错误,微信支付订单号、支付完成时间、订单号均不能为空");
            return resp;
        }
        //根据订单号获取订单
        OrderEntity order = orderBusinessService.get(ConvertUtil.obj2long(out_trade_no));
        //判断该订单是否存在
        if (Util.isEmpty(order)) {
            resp = PayCommonUtil.getResponseXML("ERROR", "订单不存在");
            return resp;
        }
        //获取订单状态
        int orderStatus = order.getStatus();
        //如果订单状态是“已完成”,说明此订单已被处理过则无需再处理,直接return
        if (WxOrderStatusEnum.FINISHED.intKey() == orderStatus) {
            return resp;
        }
        //如果此订单是为付款,则说明此订单没有被处理过,if里面可以写自己所需要的业务
        if (WxOrderStatusEnum.WAITING_PAY.intKey() == orderStatus) {
          //此处写你所需的业务即可,比如:更改订单状态、添加购买记录、添加支付记录等
        }
        return resp;
    }
④、当支付成功,订单完成之后,则需要关闭二维码弹框,当然,微信本身是不可能来实现这一步的,所以还是需要我们自己来处理,
这里暂时写了个定时器,根据查询订单状态来确认订单是否完成,完成、则关闭二维码
window.setInterval(function () {
      $.get(we.vr.order+'/pay/wx/queryorder.html?orderId='+data, 
            {"timed": new Date().getTime()}, 
             function (data) {
                 if(data.isPay == true){
                     $('.ui-dialog-close').click();
                     we.utils.gotoUrl(we.vr.kecheng+'/student/mycourse.html');
                 }
            });
}, 3000);
②.①、获取微信响应的内容
private String getWeiXinResponseContent(HttpServletRequest request) throws IOException,
            UnsupportedEncodingException {
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        //获取微信调用我们notify_url的返回信息
        String responseString = new String(outStream.toByteArray(), "utf-8");
        outStream.close();
        inStream.close();
        return responseString;
    }
相关工具类
1、解析XML工具类
public class XMLParser {
    public static Map<String, Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException,
            SAXException {
        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is = Utils.getStringStream(xmlString);
        Document document = builder.parse(is);
        //获取到document里面的全部结点
        NodeList allNodes = document.getFirstChild().getChildNodes();
        Node node;
        Map<String, Object> map = new HashMap<String, Object>();
        int i = 0;
        while (i < allNodes.getLength()) {
            node = allNodes.item(i);
            if (node instanceof Element) {
                map.put(node.getNodeName(), node.getTextContent());
            }
            i++;
        }
        return map;
    }
}
2、生成随机字符串
 //生成随机字符串,字符串由26个字母以及数字构成
    public static String randomString(final int lengths) {
        return random(lengths, STRING_CODE);
    }
3、金额工具类
public class AmountUtils {
    /**金额为分的格式 */
    public static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+";
    /**   
     * 将分为单位的转换为元并返回金额格式的字符串 (除100)  
     *   
     * @param amount  
     * @return  
     * @throws Exception   
     */
    public static String changeF2Y(Long amount) throws Exception {
        if (!amount.toString().matches(CURRENCY_FEN_REGEX)) {
            throw new Exception("金额格式有误");
        }
        int flag = 0;
        String amString = amount.toString();
        if (amString.charAt(0) == '-') {
            flag = 1;
            amString = amString.substring(1);
        }
        StringBuffer result = new StringBuffer();
        if (amString.length() == 1) {
            result.append("0.0").append(amString);
        } else if (amString.length() == 2) {
            result.append("0.").append(amString);
        } else {
            String intString = amString.substring(0, amString.length() - 2);
            for (int i = 1; i <= intString.length(); i++) {
                if ((i - 1) % 3 == 0 && i != 1) {
                    result.append(",");
                }
                result.append(intString.substring(intString.length() - i, intString.length() - i + 1));
            }
            result.reverse().append(".").append(amString.substring(amString.length() - 2));
        }
        if (flag == 1) {
            return "-" + result.toString();
        } else {
            return result.toString();
        }
    }
    /**  
     * 将分为单位的转换为元 (除100)  
     *   
     * @param amount  
     * @return  
     * @throws Exception   
     */
    public static String changeF2Y(String amount) throws Exception {
        if (!amount.matches(CURRENCY_FEN_REGEX)) {
            throw new Exception("金额格式有误");
        }
        return BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)).toString();
    }
    /**   
     * 将元为单位的转换为分 (乘100)  
     *   
     * @param amount  
     * @return  
     */
    public static String changeY2F(Long amount) {
        return BigDecimal.valueOf(amount).multiply(new BigDecimal(100)).toString();
    }
    /**   
     * 将元为单位的转换为分 (乘100)  
     *   
     * @param amount  
     * @return  
     */
    public static long changeY2F(Double amount) {
        return Math.round(amount * 100);
    }
    /**   
     * 将元为单位的转换为分 替换小数点,支持以逗号区分的金额  
     *   
     * @param amount  
     * @return  
     */
    public static String changeY2F(String amount) {
        String currency = amount.replaceAll("\\$|\\¥|\\,", ""); //处理包含, ¥ 或者$的金额    
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }
}
4、微信支付签名算法工具类
public class Signature {
    /**
     * 签名算法
     * @param o 要参与签名的数据对象
     * @return 签名
     * @throws IllegalAccessException
     */
    public static String getSign(Object o) throws IllegalAccessException {
        ArrayList<String> list = new ArrayList<String>();
        Class<?> cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            if (f.get(o) != null && f.get(o) != "") {
                list.add(f.getName() + "=" + f.get(o) + "&");
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        Utils.log("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        Utils.log("Sign Result:" + result);
        return result;
    }
    public static String getSign(Map<String, Object> map, String key) {
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (entry.getValue() != "") {
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + key;
        //Util.log("Sign Before MD5:" + result);
        System.out.println("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        System.out.println("Sign Result:" + result);
        //Util.log("Sign Result:" + result);
        return result;
    }
    /**
     * 从API返回的XML数据里面重新计算一次签名
     * @param responseString API返回的XML数据
     * @return 新鲜出炉的签名
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static String getSignFromResponseString(String responseString, String key) throws IOException, SAXException,
            ParserConfigurationException {
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
        map.put("sign", "");
        //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
        return Signature.getSign(map, key);
    }
    /**
     * 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
     * @param responseString API返回的XML数据字符串
     * @return API签名是否合法
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static boolean checkIsSignValidFromResponseString(String responseString, String key)
            throws ParserConfigurationException, IOException, SAXException {
        Map<String, Object> map = XMLParser.getMapFromXML(responseString);
        Utils.log(map.toString());
        String signFromAPIResponse = map.get("sign").toString();
        if (signFromAPIResponse == "" || signFromAPIResponse == null) {
            Utils.log("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
            return false;
        }
        Utils.log("服务器回包里面的签名是:" + signFromAPIResponse);
        //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
        map.put("sign", "");
        //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
        String signForAPIResponse = Signature.getSign(map, key);
        if (!signForAPIResponse.equals(signFromAPIResponse)) {
            //签名验不过,表示这个API返回的数据有可能已经被篡改了
            Utils.log("API返回的数据签名验证不通过,有可能被第三方篡改!!!");
            return false;
        }
        Utils.log("恭喜,API返回的数据签名验证通过!!!");
        return true;
    }
}
5、HttpRequest工具类
public class HttpRequest {
    private static Log log = new Log(LoggerFactory.getLogger(HttpRequest.class));
    public static String sendPost(String url, Map<String, Object> parameters) {
        String result = null;
        HttpPost httpPost = new HttpPost(url);
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = PayCommonUtil.getRequestXml(parameters);
        Utils.log("API,POST过去的数据是:");
        Utils.log(postDataXML);
        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
        Utils.log("executing request" + httpPost.getRequestLine());
        try {
            //非ssl连接
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "UTF-8");
        } catch (ConnectionPoolTimeoutException e) {
            log.e("http get throw ConnectionPoolTimeoutException(wait time out)");
        } catch (ConnectTimeoutException e) {
            log.e("http get throw ConnectTimeoutException");
        } catch (SocketTimeoutException e) {
            log.e("http get throw SocketTimeoutException");
        } catch (Exception e) {
            log.e("http get throw Exception");
        } finally {
            httpPost.abort();
        }
        return result;
    }
}
6、二维码工具类
public class QrcodeUtil {
    public static boolean encoderQRCode(String content, String imgPath) {
        ExceptionUtil.checkEmpty(content, "链接不能为空");
        boolean isSuccess = true;
        try {
            Qrcode qrcodeHandler = new Qrcode();
            // 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小 
            qrcodeHandler.setQrcodeErrorCorrect('L');
            qrcodeHandler.setQrcodeEncodeMode('B');
            qrcodeHandler.setQrcodeVersion(7);
            //               int imgSize = 67 + 12 * (size - 1);
            byte[] contentBytes = content.getBytes("gb2312");
            BufferedImage bufImg = new BufferedImage(215, 215, BufferedImage.TYPE_INT_RGB);
            Graphics2D gs = bufImg.createGraphics();
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, 215, 215);
            // 设定图像颜色> BLACK 
            gs.setColor(Color.BLACK);
            // 设置偏移量 不设置可能导致解析出错 
            int pixoff = 2;
            // 输出内容> 二维码 
            if (contentBytes.length > 0 && contentBytes.length < 800) {
                boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                        }
                    }
                }
            } else {
                System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,120 ]. ");
            }
            gs.dispose();
            bufImg.flush();
            // 生成二维码QRCode图片 
            ImageIO.write(bufImg, "png", new File(imgPath));
            return isSuccess;
        } catch (Exception e) {
            isSuccess = false;
            e.printStackTrace();
            return isSuccess;
        }
    }
    /**
     * 获取二维码存放的位置
     *
     * @param kvConfig 
     * @param file
     * @param upload
     * @param foldPath
     * @param fileName 文件名(有文件可以不传这个名称)
     * @return 路径
    */
    public static String getQrCodePath(KvConfig kvConfig, IUpload upload) {
        DateTime dt = DateTimeUtil.now();
        final String fileServer = kvConfig.getValue("file_server");
        StringBuilder sb = new StringBuilder(fileServer).append(File.separator);
        if (!Util.isEmpty(upload)) {
            sb.append(upload.foldName()).append(File.separator);
        }
        String realFoldPath = dt.getYear() + File.separator + dt.getMonthOfYear() + File.separator + dt.getDayOfMonth()
                + File.separator;
        sb.append(realFoldPath);
        sb.append(RandomUtil.uu16() + ".png");
        FileUtil.createNewFile(new File(sb.toString()));
        return StringUtil.path2Web(sb.toString());
    }
    /**
     * 
     * 得到路径
     *
     * @param path
     * @param kvConfig
     */
    public static String getRelationPath(String path, KvConfig kvConfig) {
        if (Util.isEmpty(path)) {
            return "";
        }
        File f = new File(kvConfig.getValue("file_server"));
        return StringUtil.removeLeft(StringUtil.path2Web(path), StringUtil.path2Web(f.getPath()));
    }
}
7、支付工具类
public class PayCommonUtil {
    /**
     * 获取请求微信接口时的xml数据
     */
    public static String getRequestXml(Map<String, Object> params) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = params.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = entry.getValue().toString();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }
    /**
     * 获取响应给微信的xml数据
     */
    public static String getResponseXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg
                + "]]></return_msg></xml>";
    }
}

下面链接是微信公众号支付

微信支付第二弹(公众号支付)

展开阅读全文

没有更多推荐了,返回首页