|  | @@ -0,0 +1,124 @@
 | 
	
		
			
				|  |  | +package cn.newfeifan.mall.module.pay.service.fuyouorder;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.framework.common.exception.ErrorCode;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.framework.pay.core.client.PayClient;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.api.refund.dto.PayRefundCreateReqDTO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.dataobject.channel.PayChannelDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.dataobject.order.PayOrderDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.dataobject.refund.PayRefundDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.mysql.refund.PayRefundMapper;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.redis.no.PayNoRedisDAO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.enums.fuyouorder.AfterSaleOrderTypeEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.enums.notify.PayNotifyTypeEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.enums.refund.PayRefundStatusEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.reqdata.RefundDataReq;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.respVO.FuYouPayRefundResponse;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.util.DateUtils;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.util.FuiouHttpPoster;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.util.MD5;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.service.notify.PayNotifyService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.service.order.PayOrderService;
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.databind.ObjectMapper;
 | 
	
		
			
				|  |  | +import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import javax.annotation.Resource;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.time.LocalDateTime;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.module.pay.enums.DictTypeConstants.*;
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.module.pay.enums.ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +@Slf4j
 | 
	
		
			
				|  |  | +@Service
 | 
	
		
			
				|  |  | +public class FuYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PayNoRedisDAO noRedisDAO;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PayRefundMapper refundMapper;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PayOrderService orderService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PayNotifyService notifyService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void payRefund(PayRefundCreateReqDTO reqDTO, PayOrderDO order, PayRefundDO refund, PayChannelDO channel, PayClient client) {
 | 
	
		
			
				|  |  | +        String no = noRedisDAO.generate(FUYOU_TRADE_ORDER_NO_PREFIX);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        FuiouHttpPoster http = new FuiouHttpPoster();
 | 
	
		
			
				|  |  | +        http.setCharset("utf-8");
 | 
	
		
			
				|  |  | +        http.setUrl("https://aipay.fuioupay.com/aggregatePay/commonRefund");
 | 
	
		
			
				|  |  | +        RefundDataReq req = new RefundDataReq();
 | 
	
		
			
				|  |  | +        req.setVersion(version);
 | 
	
		
			
				|  |  | +        req.setMchnt_cd(mchnt_cd);
 | 
	
		
			
				|  |  | +        req.setTerm_id(term_id);
 | 
	
		
			
				|  |  | +        req.setRandom_str(DateUtils.getCurrentDate("yyyyMMddHHmmss")
 | 
	
		
			
				|  |  | +                + "568974");
 | 
	
		
			
				|  |  | +        req.setMchnt_order_no(order.getPayOrderNo());
 | 
	
		
			
				|  |  | +        req.setRefund_order_no(no);
 | 
	
		
			
				|  |  | +        req.setOrder_type(AfterSaleOrderTypeEnum.getType(order.getChannelCode()));
 | 
	
		
			
				|  |  | +        req.setTotal_amt(order.getPrice().toString());
 | 
	
		
			
				|  |  | +        req.setRefund_amt(refund.getRefundPrice().toString());
 | 
	
		
			
				|  |  | +        StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  | +        sb.append(req.getMchnt_cd()).append("|").append(req.getOrder_type()).append("|")
 | 
	
		
			
				|  |  | +                .append(req.getMchnt_order_no()).append("|").append(req.getRefund_order_no())
 | 
	
		
			
				|  |  | +                .append("|").append(req.getTotal_amt()).append("|").append(req.getRefund_amt())
 | 
	
		
			
				|  |  | +                .append("|").append(req.getTerm_id()).append("|").append(req.getRandom_str())
 | 
	
		
			
				|  |  | +                .append("|").append(req.getVersion()).append("|").append(privateKey);
 | 
	
		
			
				|  |  | +        System.out.println("请求sign:"+ sb);
 | 
	
		
			
				|  |  | +        req.setSign(MD5.MD5Encode(sb.toString(), "UTF-8"));
 | 
	
		
			
				|  |  | +        log.info("向富友发起退款请求 == 请求体:{}", JSON.toJSONString(req));
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            String res = http.newPost(JSON.toJSONString(req));
 | 
	
		
			
				|  |  | +            log.info("向富友发起退款请求 == 响应体:{}", res);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 解析返回结果,获取参数
 | 
	
		
			
				|  |  | +            ObjectMapper mapper = new ObjectMapper();
 | 
	
		
			
				|  |  | +            FuYouPayRefundResponse resp = mapper.readValue(res, FuYouPayRefundResponse.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 创建退款单
 | 
	
		
			
				|  |  | +            PayRefundDO updateRefundObj = new PayRefundDO()
 | 
	
		
			
				|  |  | +                    .setChannelRequest(JSON.toJSONString(req))
 | 
	
		
			
				|  |  | +                    .setChannelResponse(res);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 记录异常信息
 | 
	
		
			
				|  |  | +            if (!resultCode.equals(resp.getResult_code())) {
 | 
	
		
			
				|  |  | +                updateRefundObj.setChannelErrorCode(resp.getResult_code());
 | 
	
		
			
				|  |  | +                updateRefundObj.setChannelErrorMsg(resp.getResult_msg());
 | 
	
		
			
				|  |  | +                refundMapper.updateById(updateRefundObj);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                ErrorCode ERROR = new ErrorCode(1_007_901_006, "请求退款失败");
 | 
	
		
			
				|  |  | +                throw exception(ERROR);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 1 更新 PayRefundDO
 | 
	
		
			
				|  |  | +            updateRefundObj.setPayRefundNo(no)
 | 
	
		
			
				|  |  | +                    .setSuccessTime(LocalDateTime.now())
 | 
	
		
			
				|  |  | +                    .setChannelRefundNo(resp.getRefund_id())
 | 
	
		
			
				|  |  | +                    .setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
 | 
	
		
			
				|  |  | +            int updateCounts = refundMapper.updateByIdAndStatus(refund.getId(), refund.getStatus(), updateRefundObj);
 | 
	
		
			
				|  |  | +            if (updateCounts == 0) { // 校验状态,必须是等待状态
 | 
	
		
			
				|  |  | +                throw exception(REFUND_STATUS_IS_NOT_WAITING);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            log.info("[notifyRefundSuccess][退款订单({}) 更新为退款成功]", refund.getId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 2. 更新订单
 | 
	
		
			
				|  |  | +            orderService.updateOrderRefundPrice(refund.getOrderId(), refund.getRefundPrice());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 3. 插入退款通知记录
 | 
	
		
			
				|  |  | +            notifyService.createPayNotifyTask(PayNotifyTypeEnum.REFUND.getType(),
 | 
	
		
			
				|  |  | +                    refund.getId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            log.error("向富友发起退款请求 == 异常:{}", e.getMessage());
 | 
	
		
			
				|  |  | +            ErrorCode ERROR = new ErrorCode(1_007_901_006, "异常! 请求退款失败");
 | 
	
		
			
				|  |  | +            throw exception(ERROR);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |