package com.cweb.controller.pay; 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.security.AESEncodeUtil; import com.hai.common.utils.ResponseMsgUtil; import com.hai.common.utils.WxUtils; import com.hai.config.CommonSysConst; import com.hai.config.HuiLianTongUnionCardConfig; import com.hai.config.UnionPayConfig; import com.hai.config.WxOrderConfig; import com.hai.dao.HighGasOrderRefundMapper; import com.hai.entity.HighGasOrderRefund; import com.hai.entity.HighOrder; import com.hai.entity.HighRefundAudit; import com.hai.entity.OutRechargeOrder; import com.hai.model.OrderRefundModel; import com.hai.model.ResponseData; import com.hai.service.HighRefundAuditService; import com.hai.service.OutRechargeOrderService; import com.hai.service.pay.impl.GoodsOrderServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Objects; @Controller @RequestMapping(value = "/czOrder") @Api(value = "充值回调") public class CzOrderController { private static Logger log = LoggerFactory.getLogger(TuanYouController.class); @Resource private HighGasOrderRefundMapper highGasOrderRefundMapper; @Resource private OutRechargeOrderService outRechargeOrderService; @Resource private GoodsOrderServiceImpl goodsOrderService; @RequestMapping(value = "/rechargeCallback", method = RequestMethod.POST) @ApiOperation(value = "话费充值回调") @ResponseBody public void rechargeCallback(@RequestBody String reqBodyStr, HttpServletRequest request, HttpServletResponse response) { try { JSONObject dataObject = JSONObject.parseObject(reqBodyStr, JSONObject.class); HighGasOrderRefund highGasOrderRefund = new HighGasOrderRefund(); highGasOrderRefund.setCreateTime(new Date()); highGasOrderRefund.setReturnContent(String.valueOf(dataObject)); highGasOrderRefundMapper.insert(highGasOrderRefund); // 查询订单 OutRechargeOrder order = outRechargeOrderService.findByOrderNo(dataObject.getString("out_order_id")); // 订单状态 : 订单状态 : 1.待支付 2.已支付 3.已完成 4.已取消 5.已退款 6:退款中 if (order != null && order.getStatus() == 2) { // 退单结果 true:成功 false:失败 if (dataObject.getInteger("status") == 3) { order.setStatus(3); outRechargeOrderService.updateOrder(order); } else if (dataObject.getInteger("status") == 4) { orderToRefund(order.getId()); } } response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter writer= response.getWriter(); writer.write("success"); } catch (Exception e) { log.error("WechatPayController --> wechatNotify() error!", e); } } public Boolean orderToRefund(Long orderId) { try { OutRechargeOrder order = outRechargeOrderService.findByOrderId(orderId); // 订单状态 : 1.待支付 2.已支付 3.已完成 4.已取消 5.已退款 6:退款中 if (order.getStatus() != 2) { log.error("orderToPay error!", "无法退款,订单状态错误!"); 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 { log.error("orderToPay error!", "退款失败"); 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) { log.error("orderToPay error!", "请求超时"); 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 { log.error("orderToPay error!", dataObject.getString("message")); throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, dataObject.getString("message")); } } // 银联退款 if (order.getPayType() == 4) { // 订单退款 JSONObject refund = UnionPayConfig.zwrefund(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); } return true; } catch (Exception e) { log.error("HighOrderController --> getUserOrderList() error!", e); return false; } } 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(); } } }