admin
2020-05-20 98b1a0affd69bbe63223c21fdd2c404e8bedfccb
utils/src/main/java/org/yeshi/utils/wx/WXPayUtil.java
@@ -1,12 +1,23 @@
package org.yeshi.utils.wx;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.dom4j.DocumentException;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.StringUtil;
import org.yeshi.utils.entity.wx.RedPackParams;
import org.yeshi.utils.entity.wx.WXAPPInfo;
import org.yeshi.utils.entity.wx.WXPlaceOrderParams;
import org.yeshi.utils.exception.WXOrderException;
import org.yeshi.utils.exception.WXPlaceOrderParamsException;
/**
 * 微信支付帮助类
@@ -16,6 +27,36 @@
 */
public class WXPayUtil {
   private static String post(String url, String entity) {
      HttpClient client = new HttpClient();
      PostMethod method = new PostMethod(url);
      method.setRequestBody(entity);
      try {
         client.executeMethod(method);
         return method.getResponseBodyAsString();
      } catch (HttpException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
      return "";
   }
   /**
    * 付款到零钱
    *
    * @param appId
    * @param openId
    * @param mchId
    * @param key
    * @param pwd
    * @param cert
    * @param orderNo
    * @param money
    * @param desc
    * @param ip
    * @return
    */
   public static String payToOpenId(String appId, String openId, String mchId, String key, String pwd,
         InputStream cert, String orderNo, BigDecimal money, String desc, String ip) {
      Map<String, String> map = new HashMap<>();
@@ -41,4 +82,279 @@
      return null;
   }
   /**
    * 发放微信红包
    *
    * @param params
    * @param pwd
    * @param cert
    * @return
    */
   public static String redPackToOpenId(RedPackParams params, String pwd, InputStream cert) {
      // 转化成分
      BigDecimal money = params.getMoney();
      money = money.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN);
      Map<String, String> map = new HashMap<>();
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("mch_billno", params.getBillno());
      map.put("mch_id", params.getMchId());
      map.put("wxappid", params.getWxappId());
      map.put("send_name", params.getSendName());
      map.put("re_openid", params.getOpenid());
      map.put("total_amount", money.toString());
      map.put("total_num", params.getTotalNum() + "");
      map.put("wishing", params.getWishing());
      map.put("client_ip", params.getClientIp());
      map.put("act_name", params.getActName());
      map.put("remark", params.getRemark());
      if (!StringUtil.isNullOrEmpty(params.getSceneId()))
         map.put("scene_id", params.getSceneId());
      if (!StringUtil.isNullOrEmpty(params.getRiskInfo()))
         map.put("risk_info", params.getRiskInfo());
      map.put("sign", WXUtil.getSignMD5(map, params.getKey()));
      String entity = WXUtil.loadWXMessage(map);
      try {
         String result = HttpUtil.httpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", entity,
               pwd, cert);
         return result;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return null;
   }
   /**
    * 查询红包领取记录
    *
    * @param billno
    *            商户订单号
    * @param mchId
    *            商户号
    * @param key
    * @param appId
    *            Appid
    * @param pwd
    * @param cert
    * @return
    */
   public static String getRedPackRecord(String billno, String mchId, String appId, String key, String pwd,
         InputStream cert) {
      Map<String, String> map = new HashMap<>();
      map.put("mch_billno", billno);
      map.put("mch_id", mchId);
      map.put("wxappid", appId);
      map.put("bill_type", "MCHT");
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("sign", WXUtil.getSignMD5(map, key));
      String entity = WXUtil.loadWXMessage(map);
      try {
         String result = HttpUtil.httpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo", entity, pwd,
               cert);
         return result;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return null;
   }
   /**
    * 微信支付统一下单
    *
    * @param params
    * @return
    * @throws WXPlaceOrderParamsException
    */
   public static Map<String, String> produceOrder(WXPlaceOrderParams params) throws WXPlaceOrderParamsException {
      if (params == null)
         throw new WXPlaceOrderParamsException(1, "请传入下单参数");
      if (params.getInfo() == null)
         throw new WXPlaceOrderParamsException(2, "请传入下单应用信息");
      if (StringUtil.isNullOrEmpty(params.getInfo().getAppId()))
         throw new WXPlaceOrderParamsException(201, "请传入下单应用信息-appId");
      if (StringUtil.isNullOrEmpty(params.getInfo().getAppSecret()))
         throw new WXPlaceOrderParamsException(202, "请传入下单应用信息-appSecret");
      if (StringUtil.isNullOrEmpty(params.getInfo().getMchId()))
         throw new WXPlaceOrderParamsException(203, "请传入下单应用信息-mchId");
      if (StringUtil.isNullOrEmpty(params.getInfo().getMchKey()))
         throw new WXPlaceOrderParamsException(204, "请传入下单应用信息-mchKey");
      if (StringUtil.isNullOrEmpty(params.getBody()))
         throw new WXPlaceOrderParamsException(3, "请传入body");
      if (StringUtil.isNullOrEmpty(params.getOrderNo()))
         throw new WXPlaceOrderParamsException(4, "请传入orderNo");
      if (params.getFee() == null)
         throw new WXPlaceOrderParamsException(5, "请传入fee");
      if (StringUtil.isNullOrEmpty(params.getIp()))
         throw new WXPlaceOrderParamsException(6, "请传入ip");
      if (StringUtil.isNullOrEmpty(params.getNotifyUrl()))
         throw new WXPlaceOrderParamsException(7, "请传入notifyUrl");
      if (StringUtil.isNullOrEmpty(params.getTradeType()))
         throw new WXPlaceOrderParamsException(8, "请传入tradeType");
      // if (StringUtil.isNullOrEmpty(params.getOpenId()))
      // throw new WXPlaceOrderParamsException(9, "请传入openId");
      Map<String, String> map = new HashMap<String, String>();
      map.put("appid", params.getInfo().getAppId());
      map.put("mch_id", params.getInfo().getMchId());
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("body", params.getBody());
      map.put("out_trade_no", params.getOrderNo());
      map.put("total_fee", "" + params.getFee().multiply(new BigDecimal(100)).intValue());
      map.put("spbill_create_ip", params.getIp());
      map.put("notify_url", params.getNotifyUrl());
      map.put("trade_type", params.getTradeType());
      if (!StringUtil.isNullOrEmpty(params.getOpenId()))
         map.put("openid", params.getOpenId());
      map.put("sign", WXUtil.getSignMD5(map, params.getInfo().getMchKey()));
      String entity = WXUtil.loadWXMessage(map);
      String result = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder", entity);
      try {
         System.out.println("统一下单结果:" + new String(result.getBytes("GBK"), "UTF-8"));
      } catch (Exception e) {
         e.printStackTrace();
      }
      Map<String, String> resultMap = WXUtil.parseXML(result);
      return resultMap;
   }
   /**
    * 订单退款
    *
    * @param orderNo-订单号
    * @param orderMoney-订单总资金
    * @param refundMoney-退款金额
    * @param reason-退款原因
    * @param appInfo
    * @param pwd-证书密码
    * @param cert-证书
    */
   public static boolean refund(String orderNo, BigDecimal orderMoney, BigDecimal refundMoney, String reason,
         WXAPPInfo appInfo, String pwd, InputStream cert) throws WXOrderException {
      Map<String, String> map = new HashMap<String, String>();
      map.put("appid", appInfo.getAppId());
      map.put("mch_id", appInfo.getMchId());
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("out_trade_no", orderNo);
      map.put("out_refund_no", orderNo);// 商户退款单号
      map.put("total_fee", orderMoney.multiply(new BigDecimal(100)).intValue() + "");// 订单金额
      map.put("refund_fee", orderMoney.multiply(new BigDecimal(100)).intValue() + "");// 退款金额
      if (!StringUtil.isNullOrEmpty(reason))
         map.put("refund_desc", reason);
      map.put("sign", WXUtil.getSignMD5(map, appInfo.getMchKey()));
      try {
         String result = HttpUtil.httpsPost("https://api.mch.weixin.qq.com/secapi/pay/refund",
               WXUtil.loadWXMessage(map), pwd, cert);
         System.out.println("订单退款结果:" + result);
         Map<String, String> resultMap = WXUtil.parseXML(result);
         if ("SUCCESS".equalsIgnoreCase(resultMap.get("return_code"))
               && "SUCCESS".equalsIgnoreCase(resultMap.get("result_code")))
            return true;
         throw new WXOrderException(100, "微信支付接口出错:" + result);
      } catch (Exception e) {
         e.printStackTrace();
      }
      return false;
   }
   /**
    * 查询订单号是否支付成功
    *
    * @param orderNo
    * @param app
    * @return
    * @throws WXOrderException
    */
   public static boolean isPaySuccess(String orderNo, WXAPPInfo app) throws WXOrderException {
      Map<String, String> map = new HashMap<String, String>();
      map.put("appid", app.getAppId());
      map.put("mch_id", app.getMchId());
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("out_trade_no", orderNo);
      map.put("sign", WXUtil.getSignMD5(map, app.getMchKey()));
      String result = HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery", WXUtil.loadWXMessage(map));
      try {
         try {
            result = new String(result.getBytes("GBK"), "UTF-8");
         } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
         }
         System.out.println("订单查询结果:" + new String(result.getBytes("GBK"), "UTF-8"));
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      }
      Map<String, String> resultMap = null;
      try {
         resultMap = WXUtil.parseXML(result);
      } catch (Exception e) {
         try {
            result = new String(result.getBytes("GBK"), "UTF-8");
         } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
         }
         resultMap = WXUtil.parseXML(result);
      }
      if ("SUCCESS".equalsIgnoreCase(resultMap.get("return_code"))
            && "SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) {
         if ("SUCCESS".equalsIgnoreCase(resultMap.get("trade_state")))// 支付成功
            return true;
         else
            return false;
      } else {
         throw new WXOrderException(100, "微信支付接口出错:" + result);
      }
   }
   /**
    *
    * @param refundOrderNo
    *            -退款单号
    * @param app
    * @return
    * @throws WXOrderException
    */
   public static boolean isRefundSuccess(String refundOrderNo, WXAPPInfo app) throws WXOrderException {
      Map<String, String> map = new HashMap<String, String>();
      map.put("appid", app.getAppId());
      map.put("mch_id", app.getMchId());
      map.put("nonce_str", StringUtil.getRandomCode(32));
      map.put("out_refund_no", refundOrderNo);
      map.put("sign", WXUtil.getSignMD5(map, app.getMchKey()));
      String result = post("https://api.mch.weixin.qq.com/pay/refundquery", WXUtil.loadWXMessage(map));
      System.out.println("订单查询结果:" + result);
      Map<String, String> resultMap = null;
      try {
         resultMap = WXUtil.parseXML(result);
      } catch (Throwable e) {
         try {
            result = new String(result.getBytes("GBK"), "UTF-8");
         } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
         }
         resultMap = WXUtil.parseXML(result);
      }
      if ("SUCCESS".equalsIgnoreCase(resultMap.get("return_code"))
            && "SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) {
         if ("SUCCESS".equalsIgnoreCase(resultMap.get("refund_status_0")))// 退款成功
            return true;
         else
            return false;
      } else {
         throw new WXOrderException(100, "微信支付接口出错:" + result);
      }
   }
}