package com.sandu.ximon.admin.pay.wx; import cn.dreampie.encription.EncriptionKit; import cn.hutool.core.codec.Base64; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.exception.WxPayException; import com.sandu.common.execption.BusinessException; import com.sandu.common.util.IpUtil; import com.sandu.ximon.admin.dto.wxquerydto.WxOrderDto; import com.sandu.ximon.admin.pay.wxpay.UsrWxPayConfigService; import com.sandu.ximon.dao.domain.WxConfigEntity; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.*; /** * @author chenjiantian * @date 2021/8/12 11:26 */ @Service @Slf4j @AllArgsConstructor public class WxFastPayService { private final com.github.binarywang.wxpay.service.WxPayService wxPayService; public static final String WECHAT_ORDER_PAY_CALLBACK_URL = "http://49.235.239.118:20012/callback/pay/wechatCallback"; //微信订单状态查询 public static final String WECHAT_ORDER_QUETY_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"; public static final String WECHAT_ORDER_QUETY = "?mchid="; private final UsrWxPayConfigService wxPayConfigService; /** * app支付 * * @param body 商品描述 * @param * @param totalFee 支付金额(分) * @return */ public SortedMap appPay(String body, String orderSn, int totalFee, Long poleId) { WxConfigEntity wxConfig = wxPayConfigService.getConfigByPoleId(poleId); wxConfig.setMchId(wxConfig.getMchId().trim()); WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); wxPayUnifiedOrderRequest.setBody(body); wxPayUnifiedOrderRequest.setOutTradeNo(orderSn); wxPayUnifiedOrderRequest.setTotalFee(totalFee); wxPayUnifiedOrderRequest.setOpenid("otiM54x_hc_5gbhMY5aZxo7UByNo"); wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5); wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp()); wxPayUnifiedOrderRequest.setNotifyUrl(WECHAT_ORDER_PAY_CALLBACK_URL); wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.JSAPI); try { WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest); System.out.println("********************************"); String time = String.valueOf(System.currentTimeMillis() / 1000); if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayUnifiedOrderResult.getResultCode())) { SortedMap parameters = new TreeMap<>(); parameters.put("appid", wxPayUnifiedOrderResult.getAppid()); parameters.put("noncestr", wxPayUnifiedOrderResult.getNonceStr()); // 随机字符串 parameters.put("partnerid", wxConfig.getMchId()); // 商户id // parameters.put("out_trade_no", orderId);//商户订单号 parameters.put("prepayid", wxPayUnifiedOrderResult.getPrepayId()); parameters.put("package", "Sign=WXPay"); parameters.put("timestamp", time); String sign = createSign(wxConfig.getPrivateKey(), parameters); //hashMap.put("paySign", wechatSign); parameters.put("Sign", sign); return parameters; } else { log.error("微信支付失败,{}", wxPayUnifiedOrderResult.getErrCodeDes()); throw new BusinessException("微信支付失败," + wxPayUnifiedOrderResult.getErrCodeDes()); } } catch (WxPayException e) { log.error("微信支付失败,{}", e.getErrCodeDes()); throw new BusinessException("微信支付失败," + e.getErrCodeDes()); } } /* private String createSign(SortedMap parameters) { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序) for (Object e : es) { Map.Entry entry = (Map.Entry) e; String k = (String) entry.getKey(); Object v = entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + wxPayProperties.getMchKey()); System.out.println("字符串拼接后是:" + sb.toString()); return SecureUtil.md5(sb.toString()).toUpperCase(); }*/ /** * 微信订单状态查询 * * @param poleId * @param outTradeNo * @return */ public boolean WxOrderQuery(Long poleId, String outTradeNo) { WxConfigEntity wxConfig = wxPayConfigService.getConfigByPoleId(poleId); if (wxConfig == null) { throw new BusinessException("获取微信支付配置失败"); } String s = HttpUtil.get(WECHAT_ORDER_QUETY_URL + outTradeNo + WECHAT_ORDER_QUETY + wxConfig.getMchId());//WxOrderDto WxOrderDto wxOrderDto = JSON.parseObject(s, WxOrderDto.class); if (("SUCCESS").equals(wxOrderDto.getTrade_state())) { return true; } return false; } /** * @param parameters * @return */ @SuppressWarnings("rawtypes") private String createSign(String Key, SortedMap parameters) { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + Key); System.out.println("字符串拼接后是:" + sb.toString()); String sign = EncriptionKit.encrypt(sb.toString()).toUpperCase(); return sign; } public WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData) { try { return wxPayService.parseOrderNotifyResult(xmlData); } catch (WxPayException e) { e.printStackTrace(); throw new BusinessException("解析回调结果失败," + e.getErrCodeDes()); } } public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) { try { return wxPayService.parseRefundNotifyResult(xmlData); } catch (WxPayException e) { e.printStackTrace(); throw new BusinessException("解析回调结果失败," + e.getErrCodeDes()); } } /** * 订单退款 只能退款一次 * * @param orderId * @param refundFee * @param callbackUrl * @return */ public boolean refundOrder(String orderId, String refundSn, Integer refundFee, String callbackUrl) { WxPayRefundRequest refundRequest = new WxPayRefundRequest(); refundRequest.setOutTradeNo(orderId); refundRequest.setOutRefundNo(refundSn); refundRequest.setRefundFee(refundFee); refundRequest.setTotalFee(refundFee); refundRequest.setNotifyUrl(callbackUrl); try { WxPayRefundResult wxPayRefundResult = wxPayService.refund(refundRequest); if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayRefundResult.getResultCode())) { return true; } else { log.error("微信退款失败,{}", wxPayRefundResult.getErrCodeDes()); throw new BusinessException("微信退款失败," + wxPayRefundResult.getErrCodeDes()); } } catch (WxPayException e) { log.error("微信退款失败,{}", e.getErrCodeDes()); throw new BusinessException("微信退款失败," + e.getErrCodeDes()); } } /** * 生成二维码付款 */ public String generateQRCodePay(String body, String orderId, int totalFee, String callbackUrl) { WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); wxPayUnifiedOrderRequest.setBody(body); wxPayUnifiedOrderRequest.setOutTradeNo(orderId); wxPayUnifiedOrderRequest.setTotalFee(totalFee); wxPayUnifiedOrderRequest.setProductId(orderId); wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5); wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp()); wxPayUnifiedOrderRequest.setNotifyUrl(callbackUrl); wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.NATIVE); try { WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest); if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayUnifiedOrderResult.getResultCode())) { byte[] scanPayQrcodeMode2 = wxPayService.createScanPayQrcodeMode2(wxPayUnifiedOrderResult.getCodeURL(), null, null); String encode = Base64.encode(scanPayQrcodeMode2); return encode; } else { log.error("微信支付失败,{}", wxPayUnifiedOrderResult.getErrCodeDes()); throw new BusinessException("微信支付失败," + wxPayUnifiedOrderResult.getErrCodeDes()); } } catch (WxPayException e) { log.error("微信支付失败,{}", e.getErrCodeDes()); throw new BusinessException("微信支付失败," + e.getErrCodeDes()); } } /** * 退款 * * @param totalAmount * @param refundAmount * @param outTradeNo * @param poleId * @return */ public boolean refund(Double totalAmount, Double refundAmount, String outTradeNo, Long poleId) { WxConfigEntity wxConfig = UsrWxPayConfigService.getBean().getConfigByPoleId(poleId); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String refundNo = sdf.format(new Date()); WxPayRefundRequest refundRequest = new WxPayRefundRequest(); refundRequest.setOutTradeNo(outTradeNo); refundRequest.setOutRefundNo(refundNo); refundRequest.setTotalFee(Integer.valueOf(parseWxAmount((totalAmount + "")))); refundRequest.setRefundFee(Integer.valueOf(parseWxAmount((refundAmount + "")))); try { WxPayRefundResult wxPayRefundResult = wxPayService.refund(refundRequest); if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayRefundResult.getResultCode())) { return true; } else { log.error("微信退款失败,{}", wxPayRefundResult.getErrCodeDes()); throw new BusinessException("微信退款失败," + wxPayRefundResult.getErrCodeDes()); } } catch (WxPayException e) { log.error("微信退款失败,{}", e.getErrCodeDes()); throw new BusinessException("微信退款失败," + e.getErrCodeDes()); } } /** * 转换为微信金额(分) * * @param normalAmount 0.01元 * @return */ public static String parseWxAmount(String normalAmount) { // 保留2位小数 double totalAmountDouble = Double.parseDouble(new DecimalFormat("#.00").format( Double.parseDouble(normalAmount))); String amount = (totalAmountDouble * 100) + ""; amount = amount.substring(0, amount.indexOf(".")); return amount; } @Transactional(rollbackFor = Exception.class) public SortedMap miniAppPay(String body, String orderId, int totalFee, Long poleId) { WxConfigEntity wxConfig = wxPayConfigService.getConfigByPoleId(poleId); wxConfig.setMchId(wxConfig.getMchId().trim()); WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); wxPayUnifiedOrderRequest.setBody(body); wxPayUnifiedOrderRequest.setOutTradeNo(orderId); wxPayUnifiedOrderRequest.setTotalFee(totalFee); wxPayUnifiedOrderRequest.setOpenid("otiM54x_hc_5gbhMY5aZxo7UByNo"); wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5); wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp()); wxPayUnifiedOrderRequest.setNotifyUrl(WECHAT_ORDER_PAY_CALLBACK_URL); wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.JSAPI); System.out.println("-----------"+wxPayUnifiedOrderRequest); try { WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest); String time = String.valueOf(System.currentTimeMillis() / 1000); if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayUnifiedOrderResult.getResultCode())) { SortedMap parameters = new TreeMap<>(); parameters.put("appid", wxPayUnifiedOrderResult.getAppid()); parameters.put("noncestr", wxPayUnifiedOrderResult.getNonceStr()); // 随机字符串 parameters.put("partnerid", wxConfig.getMchId()); // 商户id // parameters.put("out_trade_no", orderId);//商户订单号 parameters.put("prepayid", wxPayUnifiedOrderResult.getPrepayId()); parameters.put("package", "Sign=WXPay"); parameters.put("timestamp", time); String sign = createSign(wxConfig.getPrivateKey(), parameters); //hashMap.put("paySign", wechatSign); parameters.put("Sign", sign); return parameters; } else { log.error("微信支付失败,{}", wxPayUnifiedOrderResult.getErrCodeDes()); throw new BusinessException("微信支付失败," + wxPayUnifiedOrderResult); } } catch (WxPayException e) { log.error("微信支付失败,{}", e.getErrCodeDes()); throw new BusinessException("微信支付失败," + e.getErrCodeDes()); } } }