package org.yeshi.utils.wx; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; 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; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; /** * 微信支付帮助类 * * @author Administrator * */ 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 map = new HashMap<>(); map.put("mch_appid", appId); map.put("mchid", mchId); map.put("nonce_str", StringUtil.getRandomCode(32)); map.put("partner_trade_no", orderNo); map.put("openid", openId); map.put("check_name", "NO_CHECK"); map.put("amount", money.multiply(new BigDecimal(100)).intValue() + ""); map.put("desc", desc); map.put("spbill_create_ip", ip); map.put("sign", WXUtil.getSignMD5(map, key)); String entity = WXUtil.loadWXMessage(map); try { String result = HttpUtil.httpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers", entity, pwd, cert); System.out.println(result); return result; } catch (Exception e) { e.printStackTrace(); } 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 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 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 produceOrder(WXPlaceOrderParams params) throws WXPlaceOrderParamsException { if (params == null) throw new WXPlaceOrderParamsException(1, "请传入下单参数"); if (params.getApp() == null) throw new WXPlaceOrderParamsException(2, "请传入下单应用信息"); if (StringUtil.isNullOrEmpty(params.getApp().getAppId())) throw new WXPlaceOrderParamsException(201, "请传入下单应用信息-appId"); if (StringUtil.isNullOrEmpty(params.getApp().getAppSecret())) throw new WXPlaceOrderParamsException(202, "请传入下单应用信息-appSecret"); if (StringUtil.isNullOrEmpty(params.getApp().getMchId())) throw new WXPlaceOrderParamsException(203, "请传入下单应用信息-mchId"); if (StringUtil.isNullOrEmpty(params.getApp().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 map = new HashMap(); map.put("appid", params.getApp().getAppId()); map.put("mch_id", params.getApp().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.getApp().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 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 map = new HashMap(); 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 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 map = new HashMap(); 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 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 map = new HashMap(); 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 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); } } }