|  | @@ -2,15 +2,21 @@ package cn.newfeifan.mall.module.pay.service.fuyouorder;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import cn.hutool.core.date.DatePattern;
 | 
	
		
			
				|  |  |  import cn.hutool.core.date.DateUtil;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.framework.common.exception.ErrorCode;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.framework.pay.core.client.PayClient;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.dataobject.app.PayAppDO;
 | 
	
		
			
				|  |  |  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.order.PayOrderExtensionDO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.dal.mysql.order.PayOrderExtensionMapper;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.dal.mysql.order.PayOrderMapper;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.enums.order.PayOrderStatusEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.reqdata.CommonQueryDataReq;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.reqdata.WxPreCreateDataReq;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.fuiou.reqvo.SubmitOrderRequestVO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.fuiou.respVO.FuYouPayOrderSubmitRespVO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.fuiou.respVO.FuYouPaymentResponseVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.pay.fuiou.respVO.FuYouQueryPayOrderResponseVO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.service.app.PayAppService;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.service.channel.PayChannelService;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.pay.service.order.PayOrderService;
 | 
	
	
		
			
				|  | @@ -30,8 +36,11 @@ import org.springframework.validation.annotation.Validated;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.lang.reflect.Field;
 | 
	
		
			
				|  |  |  import java.time.Duration;
 | 
	
		
			
				|  |  |  import java.time.LocalDateTime;
 | 
	
		
			
				|  |  | +import java.util.HashMap;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
	
		
			
				|  |  |  import static cn.newfeifan.mall.framework.common.util.servlet.ServletUtils.getClientIP;
 | 
	
	
		
			
				|  | @@ -61,13 +70,21 @@ public class FiYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  |      @Resource
 | 
	
		
			
				|  |  |      private PayChannelService channelService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PayOrderMapper orderMapper;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  |      public String submitOrder(SubmitOrderRequestVO requestVO) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          // 1.1 获得 PayOrderDO ,并校验其是否存在
 | 
	
		
			
				|  |  |          PayOrderDO payOrder = payOrderService.validateOrderCanSubmit(requestVO.getId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PayAppDO app = appService.validPayApp(payOrder.getAppId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          payOrder.setPayOrderNo(generate(FUYOU_TRADE_ORDER_NO_PREFIX));
 | 
	
		
			
				|  |  | +        payOrder.setNotifyUrl(app.getFuyouOrderNotifyUrl());
 | 
	
		
			
				|  |  |          payOrderService.updatePayOrder(payOrder);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 1.32 校验支付渠道是否有效
 | 
	
	
		
			
				|  | @@ -83,13 +100,12 @@ public class FiYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  |                  .no(no)
 | 
	
		
			
				|  |  |                  .status(PayOrderStatusEnum.WAITING.getStatus())
 | 
	
		
			
				|  |  |                  .build();
 | 
	
		
			
				|  |  | -        orderExtensionMapper.insert(orderExtension);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          FuiouHttpPoster http = new FuiouHttpPoster();
 | 
	
		
			
				|  |  |          http.setCharset("utf-8");
 | 
	
		
			
				|  |  |          http.setUrl("https://aipay.fuioupay.com/aggregatePay/wxPreCreate");
 | 
	
		
			
				|  |  | -        requestVO.getReq().setTerm_id("88888888");
 | 
	
		
			
				|  |  | -        requestVO.getReq().setTerm_ip("192.168.8.8");
 | 
	
		
			
				|  |  | +        requestVO.getReq().setTerm_id(term_id);
 | 
	
		
			
				|  |  | +        requestVO.getReq().setTerm_ip(term_ip);
 | 
	
		
			
				|  |  |          requestVO.getReq().setRandom_str(DateUtils.getCurrentDate("yyyyMMddHHmmss")
 | 
	
		
			
				|  |  |                  + "568974");
 | 
	
		
			
				|  |  |          requestVO.getReq().setMchnt_cd(mchnt_cd);
 | 
	
	
		
			
				|  | @@ -98,27 +114,31 @@ public class FiYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  |          requestVO.getReq().setSub_appid(appid);
 | 
	
		
			
				|  |  |          requestVO.getReq().setMchnt_order_no(payOrder.getPayOrderNo());//不能重复
 | 
	
		
			
				|  |  |          requestVO.getReq().setTxn_begin_ts(DateUtils.getCurrentDate("yyyyMMddHHmmss"));
 | 
	
		
			
				|  |  | -        requestVO.getReq().setNotify_url("https://letcgo.com/fuYou/pay/order/notify");
 | 
	
		
			
				|  |  | +        requestVO.getReq().setNotify_url(app.getFuyouOrderNotifyUrl());
 | 
	
		
			
				|  |  |          requestVO.getReq().setVersion("1.0");
 | 
	
		
			
				|  |  | -        StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  | -        sb.append(requestVO.getReq().getMchnt_cd().trim()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getTrade_type().trim()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getOrder_amt().trim()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getMchnt_order_no().trim()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getTxn_begin_ts()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getGoods_des()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getTerm_id()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getTerm_ip()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getNotify_url()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getRandom_str()).append("|")
 | 
	
		
			
				|  |  | -                .append(requestVO.getReq().getVersion()).append("|")
 | 
	
		
			
				|  |  | -                .append(privateKey);
 | 
	
		
			
				|  |  | -        requestVO.getReq().setSign(MD5.MD5Encode(sb.toString()));
 | 
	
		
			
				|  |  | -        String res = null;
 | 
	
		
			
				|  |  | -            log.info("向富友发起微信支付请求 == 请求体:{}", JSON.toJSONString(requestVO.getReq()));
 | 
	
		
			
				|  |  | +        String sb = requestVO.getReq().getMchnt_cd().trim() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getTrade_type().trim() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getOrder_amt().trim() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getMchnt_order_no().trim() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getTxn_begin_ts() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getGoods_des() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getTerm_id() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getTerm_ip() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getNotify_url() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getRandom_str() + "|" +
 | 
	
		
			
				|  |  | +                requestVO.getReq().getVersion() + "|" +
 | 
	
		
			
				|  |  | +                privateKey;
 | 
	
		
			
				|  |  | +        requestVO.getReq().setSign(MD5.MD5Encode(sb));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        orderExtension.setChannelExtras(convertToMap(requestVO.getReq()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String res;
 | 
	
		
			
				|  |  | +        log.info("向富友发起微信支付请求 == 请求体:{}", JSON.toJSONString(requestVO.getReq()));
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              res = http.newPost(JSON.toJSONString(requestVO.getReq()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            orderExtension.setChannelResponse(res);
 | 
	
		
			
				|  |  | +            orderExtensionMapper.insert(orderExtension);
 | 
	
		
			
				|  |  |              log.info("向富友发起微信支付请求 == 响应体:{}", res);
 | 
	
		
			
				|  |  |              // 解析返回结果,获取参数
 | 
	
		
			
				|  |  |              ObjectMapper mapper = new ObjectMapper();
 | 
	
	
		
			
				|  | @@ -142,6 +162,34 @@ public class FiYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 将对象转成Map
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param req 支付请求对象
 | 
	
		
			
				|  |  | +     * @return Map
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private static Map<String, String> convertToMap(WxPreCreateDataReq req) {
 | 
	
		
			
				|  |  | +        Map<String, String> orderMap = new HashMap<>();
 | 
	
		
			
				|  |  | +        Class<?> orderClass = req.getClass();
 | 
	
		
			
				|  |  | +        Field[] fields = orderClass.getDeclaredFields();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            for (Field field : fields) {
 | 
	
		
			
				|  |  | +                field.setAccessible(true); // 设置可以访问私有字段
 | 
	
		
			
				|  |  | +                String fieldName = field.getName();
 | 
	
		
			
				|  |  | +                Object value = field.get(req); // 获取字段的值
 | 
	
		
			
				|  |  | +                if (value != null) {
 | 
	
		
			
				|  |  | +                    orderMap.put(fieldName, value.toString());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } catch (IllegalAccessException e) {
 | 
	
		
			
				|  |  | +            ErrorCode ERROR = new ErrorCode(1_007_901_006, "存储类型转换失败");
 | 
	
		
			
				|  |  | +            throw exception(ERROR);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return orderMap;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private PayChannelDO validateChannelCanSubmit(Long appId, String channelCode) {
 | 
	
		
			
				|  |  |          // 校验 App
 | 
	
		
			
				|  |  |          appService.validPayApp(appId);
 | 
	
	
		
			
				|  | @@ -170,16 +218,82 @@ public class FiYouPayOrderServiceImpl implements FuYouPayOrderService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PayOrderDO getPayOrderByStatus(PayOrderDO payOrderDO) {
 | 
	
		
			
				|  |  | +        // 如果订单状态为待支付,则向富友查询订单状态
 | 
	
		
			
				|  |  | +        if (payOrderDO.getStatus().equals(PayOrderStatusEnum.WAITING.getStatus())) {
 | 
	
		
			
				|  |  | +            //修改程序,当微信支付回调的时候再次向富友请求查询pay订单的支付状态
 | 
	
		
			
				|  |  | +            log.info("============支付完成查询:支付订单ID号{}", payOrderDO.getId());
 | 
	
		
			
				|  |  | +            log.info("============支付完成查询:支付订单详情{}", payOrderDO);
 | 
	
		
			
				|  |  | +            PayOrderExtensionDO payOrderExtensionDO = orderExtensionMapper.selectByPayId(payOrderDO.getId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 修改订单状态
 | 
	
		
			
				|  |  | +            updateOrderStatus(payOrderExtensionDO,payOrderDO);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return orderMapper.selectById(payOrderDO.getId());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | -     * 生成随机字符串
 | 
	
		
			
				|  |  | +     * 向富友查询支付订单状态
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param payOrderExtensionDO 支付订单扩展信息
 | 
	
		
			
				|  |  | +     * @param payOrderDO          支付订单信息
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private static String generateRandomString(int length) {
 | 
	
		
			
				|  |  | -        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 | 
	
		
			
				|  |  | -        StringBuilder sb = new StringBuilder();
 | 
	
		
			
				|  |  | -        for (int i = 0; i < length; i++) {
 | 
	
		
			
				|  |  | -            int index = (int) (characters.length() * Math.random());
 | 
	
		
			
				|  |  | -            sb.append(characters.charAt(index));
 | 
	
		
			
				|  |  | +    private void updateOrderStatus(PayOrderExtensionDO payOrderExtensionDO, PayOrderDO payOrderDO) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        FuiouHttpPoster http = new FuiouHttpPoster();
 | 
	
		
			
				|  |  | +        http.setCharset("utf-8");
 | 
	
		
			
				|  |  | +        http.setUrl("https://aipay.fuioupay.com/aggregatePay/commonQuery");
 | 
	
		
			
				|  |  | +        CommonQueryDataReq req = new CommonQueryDataReq();
 | 
	
		
			
				|  |  | +        req.setVersion("1.0");
 | 
	
		
			
				|  |  | +        req.setMchnt_cd(mchnt_cd);
 | 
	
		
			
				|  |  | +        req.setRandom_str(DateUtils.getCurrentDate("yyyyMMddHHmmss")
 | 
	
		
			
				|  |  | +                + "568974");
 | 
	
		
			
				|  |  | +        req.setOrder_type(payOrderExtensionDO.getChannelCode());
 | 
	
		
			
				|  |  | +        req.setMchnt_order_no(payOrderDO.getPayOrderNo());
 | 
	
		
			
				|  |  | +        req.setTerm_id(term_id);
 | 
	
		
			
				|  |  | +        String data = MD5.MD5Encode(req.getMchnt_cd() + "|" + req.getOrder_type() + "|" +
 | 
	
		
			
				|  |  | +                req.getMchnt_order_no() + "|" + req.getTerm_id() + "|" + req.getRandom_str() + "|" +
 | 
	
		
			
				|  |  | +                req.getVersion() + "|" + privateKey);
 | 
	
		
			
				|  |  | +        req.setSign(data);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String res;
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            res = http.newPost(JSON.toJSONString(req));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            ObjectMapper mapper = new ObjectMapper();
 | 
	
		
			
				|  |  | +            FuYouQueryPayOrderResponseVO resp = mapper.readValue(res, FuYouQueryPayOrderResponseVO.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 当响应结果为000000且交易状态为SUCCESS时才是支付成功
 | 
	
		
			
				|  |  | +            if (resp.getResult_code().equals(resultCode) && resp.getTrans_stat().equals(transStatus)) {
 | 
	
		
			
				|  |  | +                // 修改订单扩展信息
 | 
	
		
			
				|  |  | +                payOrderExtensionDO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 修改订单信息
 | 
	
		
			
				|  |  | +                payOrderDO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
 | 
	
		
			
				|  |  | +                payOrderDO.setExtensionId(payOrderExtensionDO.getId());
 | 
	
		
			
				|  |  | +                payOrderDO.setNo(payOrderExtensionDO.getNo());
 | 
	
		
			
				|  |  | +                payOrderDO.setChannelOrderNo(resp.getTransaction_id());
 | 
	
		
			
				|  |  | +                payOrderDO.setChannelUserId(resp.getBuyer_id());
 | 
	
		
			
				|  |  | +                payOrderDO.setChannelId(payOrderExtensionDO.getChannelId());
 | 
	
		
			
				|  |  | +                payOrderDO.setChannelCode(payOrderExtensionDO.getChannelCode());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                payOrderService.updatePayOrder(payOrderDO);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                // 否则支付失败, 记录错误信息
 | 
	
		
			
				|  |  | +                payOrderExtensionDO.setChannelErrorCode(resp.getResult_code());
 | 
	
		
			
				|  |  | +                payOrderExtensionDO.setChannelErrorMsg(resp.getResult_msg());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            payOrderExtensionDO.setChannelNotifyData(res);
 | 
	
		
			
				|  |  | +            orderExtensionMapper.updateById(payOrderExtensionDO);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            ErrorCode ERROR = new ErrorCode(1_007_901_006, "查询支付订单失败");
 | 
	
		
			
				|  |  | +            throw exception(ERROR);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return sb.toString();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  }
 |