package com.hai.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.hai.common.exception.ErrorCode; import com.hai.common.exception.ErrorHelp; import com.hai.common.exception.SysCode; import com.hai.common.pay.util.XmlUtil; import com.hai.common.pay.util.sdk.WXPayConstants; import com.hai.common.utils.*; import com.hai.config.CommonSysConfig; import com.hai.config.CommonSysConst; import com.hai.config.HuiLianTongUnionCardConfig; import com.hai.config.UnionPayConfig; import com.hai.dao.HighGasOrderPushMapper; import com.hai.dao.OutRechargeOrderMapper; import com.hai.dao.OutRechargeOrderMapperExt; import com.hai.entity.*; import com.hai.enum_type.OrderPushType; import com.hai.model.*; import com.hai.service.*; import com.hai.service.pay.impl.GoodsOrderServiceImpl; import io.swagger.models.auth.In; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestParam; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; @Service("outRechargeOrderService") public class OutRechargeOrderServiceImpl implements OutRechargeOrderService { @Resource private OutRechargeOrderMapper outRechargeOrderMapper; @Resource private OutRechargeOrderMapperExt outRechargeOrderMapperExt; @Resource private HighUserCardService highUserCardService; @Resource private HighGasOrderPushMapper highGasOrderPushMapper; @Resource private HighUserService highUserService; @Resource private OutRechargeOrderService outRechargeOrderService; @Resource private GoodsOrderServiceImpl goodsOrderService; @Resource private HighDiscountUserRelService highDiscountUserRelService; @Resource private HighDiscountAgentCodeService highDiscountAgentCodeService; @Override public List getListRechargeOrder(Map map) { OutRechargeOrderExample example = new OutRechargeOrderExample(); OutRechargeOrderExample.Criteria criteria = example.createCriteria(); if (MapUtils.getLong(map, "userId") != null) { criteria.andUserIdEqualTo(MapUtils.getLong(map, "userId")); } if (MapUtils.getInteger(map, "status") != null) { criteria.andStatusEqualTo(MapUtils.getInteger(map, "status")); } if (MapUtils.getInteger(map, "payType") != null) { criteria.andPayTypeEqualTo(MapUtils.getInteger(map, "payType")); } if (MapUtils.getInteger(map, "code") != null) { criteria.andIdentificationCodeEqualTo(MapUtils.getLong(map, "code")); } if (MapUtils.getString(map, "orderNo") != null) { criteria.andOrderNoLike("%" + MapUtils.getString(map, "orderNo") + "%"); } if (MapUtils.getString(map, "idCard") != null) { criteria.andIdCardLike("%" + MapUtils.getString(map, "idCard") + "%"); } if (MapUtils.getString(map, "userPhone") != null) { criteria.andUserPhoneEqualTo(MapUtils.getString(map, "userPhone")); } if (MapUtils.getString(map, "rechargeContent") != null) { criteria.andRechargeContentLike("%" + MapUtils.getString(map, "rechargeContent") + "%"); } if (MapUtils.getString(map, "rechargeType") != null) { criteria.andRechargeTypeEqualTo(MapUtils.getInteger(map, "rechargeType")); } if (MapUtils.getString(map, "phone") != null) { criteria.andUserPhoneEqualTo(MapUtils.getString(map, "phone")); } if (MapUtils.getString(map, "rechargeModel") != null) { criteria.andRechargeModelEqualTo(Integer.valueOf(MapUtils.getString(map, "rechargeModel"))); } if (StringUtils.isNotBlank(map.get("payTimeS")) && StringUtils.isNotBlank(map.get("payTimeE"))) { criteria.andPayTimeBetween( DateUtil.format(map.get("payTimeS") , "yyyy-MM-dd HH:mm:ss") , DateUtil.format(map.get("payTimeE") , "yyyy-MM-dd HH:mm:ss")); } if (StringUtils.isNotBlank(map.get("createTimeS")) && StringUtils.isNotBlank(map.get("createTimeE"))) { criteria.andCreateTimedBetween( DateUtil.format(map.get("createTimeS") , "yyyy-MM-dd HH:mm:ss") , DateUtil.format(map.get("createTimeE") , "yyyy-MM-dd HH:mm:ss")); } example.setOrderByClause("create_timed desc"); return outRechargeOrderMapper.selectByExample(example); } @Override public OutRechargeOrder findByOrderId(Long orderId) { return outRechargeOrderMapper.selectByPrimaryKey(orderId); } @Override public OutRechargeOrder findByOrderNo(String orderNo) { OutRechargeOrderExample example = new OutRechargeOrderExample(); example.createCriteria().andOrderNoEqualTo(orderNo); return outRechargeOrderMapper.selectByExample(example).get(0); } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void insertOrder(OutRechargeOrder outRechargeOrder) { // 使用优惠券 if (outRechargeOrder.getMemDiscountId() != null) { HighDiscountUserRel discountUserRel = highDiscountUserRelService.getRelById(outRechargeOrder.getMemDiscountId()); discountUserRel.setUseTime(new Date()); // 使用时间 discountUserRel.setStatus(2); //状态 0:已过期 1:未使用 2:已使用 highDiscountUserRelService.updateDiscountUserRel(discountUserRel); HighDiscountAgentCode code = highDiscountAgentCodeService.getCodeById(discountUserRel.getDiscountAgentCodeId()); code.setStatus(3); highDiscountAgentCodeService.updateCode(code); } outRechargeOrderMapper.insert(outRechargeOrder); } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void updateOrder(OutRechargeOrder outRechargeOrder) { outRechargeOrderMapper.updateByPrimaryKey(outRechargeOrder); } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void updateOrderList(List rechargeOrders) throws Exception { for (OutRechargeOrder list:rechargeOrders) { if (list.getStatus() == 3) { outRechargeOrderMapper.updateByPrimaryKey(list); } else if (list.getStatus() == 6) { rechargeOrderToRefund(list.getId()); } } } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void cancelOrder(Long orderId) { OutRechargeOrder order = findByOrderId(orderId); if (order != null && order.getStatus() == 1) { order.setStatus(4); // 订单状态:1 待支付 2 已支付 3.已完成 4. 已取消 5.已退款 order.setCancelTime(new Date()); if (order.getMemDiscountId() != null) { HighDiscountUserRel rel = highDiscountUserRelService.getRelById(order.getMemDiscountId()); if (rel != null) { rel.setStatus(1); // 状态 0:已过期 1:未使用 2:已使用 rel.setUseTime(null); highDiscountUserRelService.updateDiscountUserRel(rel); HighDiscountAgentCode code = highDiscountAgentCodeService.getCodeById(rel.getDiscountAgentCodeId()); code.setStatus(2); highDiscountAgentCodeService.updateCode(code); } } updateOrder(order); } } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void finishOrder(Long orderId) { OutRechargeOrder order = findByOrderId(orderId); if (order != null) { order.setStatus(3); // 订单状态:1 待支付 2 已支付 3.已完成 4. 已取消 5.已退款 order.setFinishTime(new Date()); updateOrder(order); } } @Override public List getOrderCount(Map map) throws Exception { if(MapUtils.getLong(map, "createTimeS") != null) { map.put("createTimeS", DateUtil.date2String(new Date(MapUtils.getLong(map, "createTimeS")), "yyyy-MM-dd HH:mm:ss")); } if(MapUtils.getLong(map, "createTimeE") != null) { map.put("createTimeE", DateUtil.date2String(new Date(MapUtils.getLong(map, "createTimeE")), "yyyy-MM-dd HH:mm:ss")); } if(MapUtils.getLong(map, "payTimeS") != null) { map.put("payTimeS", DateUtil.date2String(new Date(MapUtils.getLong(map, "payTimeS")), "yyyy-MM-dd HH:mm:ss")); } if(MapUtils.getLong(map, "payTimeE") != null) { map.put("payTimeE", DateUtil.date2String(new Date(MapUtils.getLong(map, "payTimeE")), "yyyy-MM-dd HH:mm:ss")); } return outRechargeOrderMapper.selectOrderCount(map); } @Override public Long CountOrder() { OutRechargeOrderExample example = new OutRechargeOrderExample(); example.createCriteria().andStatusEqualTo(2); return outRechargeOrderMapper.countByExample(example); } @Override public List getListOrderCount(Map map) throws Exception { String finishTimeS = map.get("finishTimeS"); String finishTimeE = map.get("finishTimeE"); Integer status; if (StringUtils.isNotBlank(map.get("status"))) { status = Integer.valueOf(map.get("status")); } else { status = null; } String fTimeS; String fTimeE; if (StringUtils.isNotBlank(finishTimeS)) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date(Long.parseLong(finishTimeS))); //时 calendar.set(Calendar.HOUR_OF_DAY, 00); //分 calendar.set(Calendar.MINUTE, 00); //秒 calendar.set(Calendar.SECOND, 00); fTimeS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()); } else { fTimeS = "2010-09-13 22:36:01"; } if (StringUtils.isNotBlank(finishTimeE)) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date(Long.parseLong(finishTimeE))); //时 calendar.set(Calendar.HOUR_OF_DAY, 00); //分 calendar.set(Calendar.MINUTE, 00); //秒 calendar.set(Calendar.SECOND, 00); fTimeE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()); } else { fTimeE = DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"); } return outRechargeOrderMapperExt.getListOrderCount(fTimeS , fTimeE , status); } @Override public List getUserCountList(Map map) throws Exception { String finishTimeS = map.get("finishTimeS"); String finishTimeE = map.get("finishTimeE"); String fTimeS; String fTimeE; if (StringUtils.isNotBlank(finishTimeS)) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date(Long.parseLong(finishTimeS))); //时 calendar.set(Calendar.HOUR_OF_DAY, 00); //分 calendar.set(Calendar.MINUTE, 00); //秒 calendar.set(Calendar.SECOND, 00); fTimeS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()); } else { fTimeS = "2010-09-13 22:36:01"; } if (StringUtils.isNotBlank(finishTimeE)) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date(Long.parseLong(finishTimeE))); //时 calendar.set(Calendar.HOUR_OF_DAY, 00); //分 calendar.set(Calendar.MINUTE, 00); //秒 calendar.set(Calendar.SECOND, 00); fTimeE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()); } else { fTimeE = DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"); } return outRechargeOrderMapperExt.getListUserCount(fTimeS , fTimeE); } @Override public void hltUnionCardPay(Long userCardId, Long orderId) throws Exception { HighUserCard userCard = highUserCardService.getDetailById(userCardId); if(userCard == null) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到用户绑定的卡号信息"); } OutRechargeOrder order = findByOrderId(orderId); if (order == null) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单信息"); } String goodsDesc = "充值话费"; String tranDesc = order.getRechargeContent() + "充值" + order.getPayPrice() +"元话费"; String instCode = "11101290"; String businessType = "hisen_consume"; // 工会卡支付 JSONObject consumption = HuiLianTongUnionCardConfig.consumption(order.getOrderNo(), userCard.getCardNo(), order.getPayPrice(), businessType, instCode, goodsDesc, tranDesc); System.out.println("工会卡支付响应参数" + consumption.toJSONString()); Map dataMap = new HashMap<>(); dataMap.put("orderNo", order.getOrderNo()); dataMap.put("cardType", "ghk"); dataMap.put("cardNo", userCard.getCardNo()); dataMap.put("checkPassword", "N"); dataMap.put("tranAmount", order.getPayPrice()); dataMap.put("tranChannel", "HiSen"); dataMap.put("businessType", businessType); dataMap.put("instCode", instCode); dataMap.put("goodsDesc", goodsDesc); dataMap.put("tranDesc", tranDesc); HighGasOrderPush payPush = new HighGasOrderPush(); payPush.setType(OrderPushType.type5.getType()); payPush.setOrderNo(order.getOrderNo()); payPush.setCreateTime(new Date()); payPush.setCode(consumption.getString("respCode")); payPush.setRequestContent(JSON.toJSONString(dataMap)); payPush.setReturnContent(consumption.toJSONString()); highGasOrderPushMapper.insert(payPush); if(!consumption.getString("respCode").equals("0000")) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, consumption.getString("respMessage")); } JSONObject consumptionResult = HuiLianTongUnionCardConfig.resolveResponse(consumption.getString("data")); if (!consumptionResult.getBoolean("success")) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, consumptionResult.getString("message")); } order.setPaySerialNo(consumptionResult.getString("orderId")); // 支付流水号 order.setPayRealPrice(order.getPayPrice()); // 实付金额 if (order.getRechargeType() == 1) { JSONObject object = outRechargeOrderService.getMobile(order.getRechargeContent() , order.getOrderPrice().intValue() , order.getOrderNo() ,order.getRechargeType()); if (object.getInteger("code") != 200) { order.setRechargeStatus(1); order.setAbnormalMsg(object.getString("message")); } } order.setStatus(2); order.setPayType(2); order.setPayTime(new Date()); // 支付时间 updateOrder(order); } @Override @Transactional(propagation= Propagation.REQUIRES_NEW) public void goldPayOrder(Long userId, Long orderId) throws Exception { OutRechargeOrder order = findByOrderId(orderId); if(order == null) { throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_ORDER, ""); } // 查询用户 HighUser highUser = highUserService.findByUserId(userId); // 金币 1:100 Integer goldNum = new BigDecimal(order.getPayPrice().toString()).multiply(new BigDecimal("100")).intValue(); highUserService.goldHandle(userId, goldNum, 2, 2, order.getId()); order.setPayRealPrice(order.getPayPrice()); // 实付金额 order.setStatus(2); order.setPayType(3); order.setPayTime(new Date()); // 支付时间 outRechargeOrderService.updateOrder(order); } @Override public List getOutRechargeOrderList() { return outRechargeOrderMapper.getCloseOrder(); } @Override public OrderCountModel rechargeOrderByIndex(Integer code) { return outRechargeOrderMapper.rechargeOrderByIndex(code); } @Override public JSONObject getMobile(String phone , Integer amount , String orderNo , Integer isFast) throws Exception { if (isFast == 2) { isFast = 0; } String timestamp = String.valueOf(System.currentTimeMillis()); Map map = new HashMap<>(); map.put("mobile" , phone); map.put("amount" , amount); map.put("out_order_id" , orderNo); map.put("app_key" , CommonSysConst.getSysConfig().getCzAppKey()); map.put("timestamp" , timestamp.substring(0,timestamp.length()-3)); map.put("is_fast" , isFast); map.put("notify_url" , CommonSysConst.getSysConfig().getCzNotifyUrl()); String signStr = WxUtils.generateSignatureAppSecret(map, CommonSysConst.getSysConfig().getCzAppSecret() , WXPayConstants.SignType.MD5); map.put("sign" , signStr); return HttpsUtils.doPost(CommonSysConst.getSysConfig().getCzUrl() + "createOrder" , map); } @Override public void rechargeOrderToRefund(Long orderId) throws Exception { OutRechargeOrder order = outRechargeOrderService.findByOrderId(orderId); // 订单状态 : 1.待支付 2.已支付 3.已完成 4.已取消 5.已退款 6:退款中 if (order.getStatus() != 2) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法退款,订单不处于已支付状态"); } // 微信退款 if (order.getPayType() == 1) { Map param = new HashMap<>(); param.put("appid", "wx637bd6f7314daa46"); param.put("mch_id", "1289663601"); param.put("sub_mch_id" , "1614670195"); param.put("nonce_str", WxUtils.makeNonStr()); param.put("transaction_id", order.getPaySerialNo()); param.put("out_refund_no", "HFR"+new Date().getTime()); param.put("total_fee", String.valueOf(order.getPayRealPrice().multiply(new BigDecimal("100")).intValue())); param.put("refund_fee", String.valueOf(order.getPayRealPrice().multiply(new BigDecimal("100")).intValue())); param.put("sign_type", "HMAC-SHA256"); String signStr = WxUtils.generateSignature(param, "Skufk5oi85wDFGl888i6wsRSTkdd5df5" , WXPayConstants.SignType.HMACSHA256); param.put("sign", signStr); String resultXmL = doRefundRequest(param.get("mch_id"), WxUtils.mapToXml(param)); OrderRefundModel orderRefundModel = XmlUtil.getObjectFromXML(resultXmL, OrderRefundModel.class); if(orderRefundModel.getResult_code().equals("SUCCESS")) { order.setStatus(5); order.setRefundTime(new Date()); order.setOutRefundNo(orderRefundModel.getOut_refund_no()); order.setRefundId(orderRefundModel.getRefund_id()); order.setRefundFee(new BigDecimal(orderRefundModel.getRefund_fee()).divide(new BigDecimal("100"))); outRechargeOrderService.updateOrder(order); } else { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "退款失败!错误代码:"+orderRefundModel.getErr_code()+",错误描述"+orderRefundModel.getErr_code_des()); } } // 工会卡退款 if (order.getPayType() == 2) { JSONObject jsonObject = HuiLianTongUnionCardConfig.refund( "HFR"+new Date().getTime() , order.getOrderNo()); if (jsonObject == null) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请求超时,请重新点击"); } JSONObject dataObject = HuiLianTongUnionCardConfig.resolveResponse(jsonObject.getString("data")); if (dataObject.getBoolean("success") || Objects.equals(dataObject.getString("message"), "原交易已撤销,不可再次操作")) { order.setStatus(5); order.setRefundTime(new Date()); order.setOutRefundNo("HFR"+new Date().getTime() ); order.setRefundFee(order.getPayRealPrice()); order.setRefundId(dataObject.getString("orderId")); outRechargeOrderService.updateOrder(order); } else { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, dataObject.getString("message")); } } // 金币退款 if (order.getPayType() == 3) { if (highUserService.findGoldRepeat(3 , order.getId())) { highUserService.goldHandle(order.getUserId(), order.getPayRealPrice().multiply(BigDecimal.valueOf(100)).intValue(), 1, 3, order.getId()); }else { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已有退款记录"); } order.setStatus(5); order.setRefundTime(new Date()); order.setOutRefundNo("HFR"+new Date().getTime() ); order.setRefundFee(order.getPayRealPrice()); outRechargeOrderService.updateOrder(order); } // 银联退款 if (order.getPayType() == 4) { // 订单退款 JSONObject refund = UnionPayConfig.zwrefund(UnionPayConfig.MER_ID2, UnionPayConfig.TERM_ID2, order.getOrderNo(), order.getPaySerialNo(), order.getPayRealPrice().multiply(new BigDecimal("100")).longValue()); if (!refund.getString("resultcode").equals("W6")) { throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, refund.getString("returnmsg")); } order.setStatus(5); order.setRefundTime(new Date()); order.setOutRefundNo(refund.getString("oriwtorderid")); order.setRefundFee(order.getPayRealPrice()); outRechargeOrderService.updateOrder(order); } if (order.getMemDiscountId() != null) { HighDiscountUserRel rel = highDiscountUserRelService.getRelById(order.getMemDiscountId()); if (rel != null) { rel.setStatus(1); // 状态 0:已过期 1:未使用 2:已使用 rel.setUseTime(null); highDiscountUserRelService.updateDiscountUserRel(rel); HighDiscountAgentCode code = highDiscountAgentCodeService.getCodeById(rel.getDiscountAgentCodeId()); code.setStatus(2); highDiscountAgentCodeService.updateCode(code); } } } public String doRefundRequest(String mchId,String data) throws Exception { //小程序退款需要调用双向证书的认证 CloseableHttpClient httpClient = goodsOrderService.readCertificate(mchId); try { HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); // 设置响应头信息 httpost.addHeader("Connection", "keep-alive"); httpost.addHeader("Accept", "*/*"); httpost.addHeader("Content-Type", "text/xml"); httpost.addHeader("Host", "api.mch.weixin.qq.com"); httpost.addHeader("X-Requested-With", "XMLHttpRequest"); httpost.addHeader("Cache-Control", "max-age=0"); httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpost.setEntity(new StringEntity(data, "UTF-8")); CloseableHttpResponse response = httpClient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); } } catch (Exception e){ throw new RuntimeException(e); } finally { httpClient.close(); } } }