Selaa lähdekoodia

定金支付逻辑

lishiqiang 1 viikko sitten
vanhempi
commit
d1eb27379f
17 muutettua tiedostoa jossa 371 lisäystä ja 4 poistoa
  1. 1 0
      ship-module-trade/ship-module-trade-api/src/main/java/com/yc/ship/module/trade/enums/TradeOrderOperateTypeEnum.java
  2. 9 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/OtcTradeOrderController.java
  3. 6 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/ShipTradeOrderCreateReqVO.java
  4. 7 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderPdaRespVO.java
  5. 6 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderRespNewVO.java
  6. 6 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderRespVO.java
  7. 9 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/app/order/TradeOrderController.java
  8. 10 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/dal/dataobject/order/TradeOrderDO.java
  9. 5 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/otc/OtcTradeOrderService.java
  10. 22 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/otc/impl/OtcTradeOrderServiceImpl.java
  11. 2 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/PayPlatService.java
  12. 7 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/TradeOrderPayService.java
  13. 2 1
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/AdvancePayTypeServiceImpl.java
  14. 2 1
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/CreditPayTypeServiceImpl.java
  15. 98 0
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/PayPlatServiceImpl.java
  16. 178 2
      ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/TradeOrderPayServiceImpl.java
  17. 1 0
      ship-server-web/src/main/resources/application.yaml

+ 1 - 0
ship-module-trade/ship-module-trade-api/src/main/java/com/yc/ship/module/trade/enums/TradeOrderOperateTypeEnum.java

@@ -42,6 +42,7 @@ public enum TradeOrderOperateTypeEnum {
     GUIDE_REFUND(28, "导游代退,退款金额{refundAmount},原订单支付金额{payAmount},变更为{newPayAmount}"),
     ORDER_MODIFY(29, "修改订单,修改记录:{content},结果:{result}"),
     ORDER_AUDIT(30, "订单审核,结果:{result}"),
+    ORDER_DEPOSI_PAY(31, "订单定金支付,支付方式:{payType},金额:{payAmount}"),
     ;
 
     /**

+ 9 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/OtcTradeOrderController.java

@@ -169,6 +169,15 @@ public class OtcTradeOrderController {
         return otcTradeOrderService.windowPayOrder(agencyAuthUtils.getAgencyLoginUser(), payOrderReqVO);
     }
 
+    @RequestDecryption
+    @PostMapping("/travl/payDeposiOrder")
+    @Operation(summary = "win-旅行社下单支付定金")
+    @OperateLog(type = TRADE)
+    public CommonResult<PayOrderRespVO> payDeposiOrder(@Valid @RequestBody PayOrderReqVO payOrderReqVO) {
+        log.error("payDeposiOrder:{}", JSON.toJSONString(payOrderReqVO));
+        return otcTradeOrderService.payDeposiOrder(agencyAuthUtils.getAgencyLoginUser(), payOrderReqVO);
+    }
+
     @GetMapping("/travl/queryOrderStatus")
     @Operation(summary = "win-查询订单状态")
     @OperateLog(type = API)

+ 6 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/ShipTradeOrderCreateReqVO.java

@@ -89,6 +89,12 @@ public class ShipTradeOrderCreateReqVO implements Serializable {
     @Schema(description = "定金")
     private BigDecimal deposi;
 
+    @Schema(description = "定金状态")
+    private Integer deposiStatus;
+
+    @Schema(description = "定金支付时间")
+    private BigDecimal deposiPayTime;
+
     @Schema(description = "实际总额")
     private BigDecimal realOrderMoney;
 

+ 7 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderPdaRespVO.java

@@ -441,6 +441,13 @@ public class TradeOrderPdaRespVO {
     @Schema(description = "定金")
     private BigDecimal deposi;
 
+    @Schema(description = "定金支付状态")
+    private Integer deposiStatus;
+
+
+    @Schema(description = "定金支付时间")
+    private LocalDateTime deposiPayTime;
+
     @Schema(description = "排序")
     private Integer orderSort;
 

+ 6 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderRespNewVO.java

@@ -205,4 +205,10 @@ public class TradeOrderRespNewVO {
     @Schema(description = "定金")
     private BigDecimal deposi;
 
+    @Schema(description = "定金状态0:初始  1:待支付(审核通过)2:已支付")
+    private Integer deposiStatus;
+
+    @Schema(description = "定金支付时间")
+    private LocalDateTime deposiPayTime;
+
 }

+ 6 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/admin/order/vo/order/TradeOrderRespVO.java

@@ -521,6 +521,12 @@ public class TradeOrderRespVO {
     @Schema(description = "定金")
     private BigDecimal deposi;
 
+    @Schema(description = "定金状态0:初始  1:待支付(审核通过)2:已支付")
+    private Integer deposiStatus;
+
+    @Schema(description = "定金支付时间")
+    private LocalDateTime deposiPayTime;
+
     @Schema(description = "订单序号")
     private Integer orderSort;
 

+ 9 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/controller/app/order/TradeOrderController.java

@@ -48,6 +48,15 @@ public class TradeOrderController {
         return commonResult.isSuccess() ? "success" : "fail";
     }
 
+    @PostMapping("/deposiPayNotify")
+    @Operation(summary = "定金支付通知")
+    @OperateLog(type = TRADE)
+    public String deposiPayNotify(@RequestParam Map<String, Object> map) {
+        CommonResult<?> commonResult = tradeOrderPayService.handleDeposiPayNotify(map);
+        log.error("定金支付通知,参数{},返回参数{}", map, commonResult.isSuccess());
+        return commonResult.isSuccess() ? "success" : "fail";
+    }
+
     @PostMapping("/refundNotify")
     @Operation(summary = "退款通知")
     @OperateLog(type = TRADE)

+ 10 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/dal/dataobject/order/TradeOrderDO.java

@@ -336,6 +336,16 @@ public class TradeOrderDO extends TenantBaseDO {
     @ForUpdate(fieldName = "定金")
     private BigDecimal deposi;
 
+    /**
+     * 定金状态0:初始  1:待支付(审核通过)2:已支付
+     */
+    private Integer deposiStatus;
+
+    /**
+     * 定金支付时间
+     */
+    private LocalDateTime deposiPayTime;
+
     /**
      * 排序
      */

+ 5 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/otc/OtcTradeOrderService.java

@@ -27,6 +27,11 @@ public interface OtcTradeOrderService {
      */
     CommonResult<PayOrderRespVO> windowPayOrder(LoginUser loginUser, PayOrderReqVO payOrderReqVO);
 
+    /**
+     * 定金支付
+     */
+    CommonResult<PayOrderRespVO> payDeposiOrder(LoginUser loginUser, PayOrderReqVO payOrderReqVO);
+
     /**
      * 查询订单状态
      */

+ 22 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/otc/impl/OtcTradeOrderServiceImpl.java

@@ -276,6 +276,13 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
         return tradeOrderPayService.payOrder(payOrderReqVO);
     }
 
+    @Override
+    public CommonResult<PayOrderRespVO> payDeposiOrder(LoginUser loginUser, PayOrderReqVO payOrderReqVO) {
+        //当前旅行社信息
+        initPayParams(loginUser, payOrderReqVO);
+        return tradeOrderPayService.payDeposiOrder(payOrderReqVO);
+    }
+
     private void initPayParams(LoginUser loginUser, PayOrderReqVO payOrderReqVO) {
         if (loginUser.getDistributorId() == null) {
             payOrderReqVO.setAccountType(PayAccountTypeEnum.OTC.getType());
@@ -343,6 +350,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                         .set(TradeOrderDO::getOrderStatus, TradeOrderStatusEnum.UNPAID.getStatus())
                         .set(TradeOrderDO::getAuditStatus, tradeOrderDO.getAuditStatus() + 1)
                         .set(TradeOrderDO::getUpdateTime, LocalDateTime.now())
+                        .set(TradeOrderDO::getDeposiStatus, 2)
                         .eq(TradeOrderDO::getId, orderId)
                 );
                 Map<String, Object> extMap = new HashMap<>();
@@ -352,6 +360,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                 tradeOrderMapper.update(Wrappers.<TradeOrderDO>lambdaUpdate()
                         .set(TradeOrderDO::getAuditStatus, tradeOrderDO.getAuditStatus() + 1)
                         .set(TradeOrderDO::getUpdateTime, LocalDateTime.now())
+                        .set(TradeOrderDO::getDeposiStatus, 1)
                         .eq(TradeOrderDO::getId, orderId)
                 );
                 Map<String, Object> extMap = new HashMap<>();
@@ -1376,6 +1385,11 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
             if (realOrderMoney != null) {
                 shipTradeOrderCreateReqVO.setPayAmount(realOrderMoney);
             }
+            BigDecimal deposi = createVO.getSummary().getDeposi();
+            if (deposi != null && deposi.compareTo(BigDecimal.ZERO) > 0) {
+                shipTradeOrderCreateReqVO.setDeposi(deposi);
+                shipTradeOrderCreateReqVO.setDeposiStatus(1);
+            }
             shipTradeOrderCreateReqVO.setRealMoney(realAmount);
             shipTradeOrderCreateReqVO.setIsRead(0);
             shipTradeOrderCreateReqVO.setDeposi(createVO.getSummary().getDeposi());
@@ -1496,6 +1510,9 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
             if (leaderTotalMoney != null && leaderTotalMoney.compareTo(new BigDecimal(0)) > 0) {
                 auditType = 3;
             }
+            if (deposi != null && deposi.compareTo(new BigDecimal(0)) > 0) {
+                auditType = 3;
+            }
             if (auditType > 0 && createVO.getIsYd() != 1) {
                 tradeOrderMapper.update(new UpdateWrapper<TradeOrderDO>().set("audit_type", auditType).set("order_status", TradeOrderStatusEnum.TRANSFER).set("audit_status", 1).eq("id", orderId));
             }
@@ -1598,6 +1615,7 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                 tradeOrderBindDO.setCustom("");
                 tradeOrderBindDO.setRemark("modify定金金额修改,订单原定金:" + tradeOrderDO.getDeposi() + ",订单修改后定金金额:" + shipTradeOrderCreateReqVO.getDeposi());
                 shipTradeOrderCreateReqVO.setTradeOrderBindDO(tradeOrderBindDO);
+                shipTradeOrderCreateReqVO.setDeposiStatus(1);
             } else {
                 shipTradeOrderCreateReqVO.setConfirmType(0);
             }
@@ -1759,6 +1777,10 @@ public class OtcTradeOrderServiceImpl implements OtcTradeOrderService {
                 AuditUserDO auditUserDO = auditUserMapper.selectOne(new LambdaQueryWrapperX<AuditUserDO>().eq(AuditUserDO::getType, auditType).eq(AuditUserDO::getDeleted, 0).orderByDesc(AuditUserDO::getCreateTime).last("limit 1"));
                 tradeOrderMapper.update(new UpdateWrapper<TradeOrderDO>().set("audit_type", auditType).set("audit_user", auditUserDO == null ? "" : auditUserDO.getAuditUser()).set("order_status", TradeOrderStatusEnum.TRANSFER.getStatus()).set("audit_status", 1).eq("id", neworderId));
                 msg = "修改提交成功,等待管理员审核";
+            }else if(shipTradeOrderCreateReqVO.getDeposi().compareTo(BigDecimal.ZERO) > 0 && createVO.getIsYd() != 1 && Objects.equals(tradeOrderDO.getOrderStatus(), TradeOrderStatusEnum.YD.getStatus())){
+                AuditUserDO auditUserDO = auditUserMapper.selectOne(new LambdaQueryWrapperX<AuditUserDO>().eq(AuditUserDO::getType, 3).eq(AuditUserDO::getDeleted, 0).orderByDesc(AuditUserDO::getCreateTime).last("limit 1"));
+                tradeOrderMapper.update(new UpdateWrapper<TradeOrderDO>().set("audit_type", 3).set("audit_user", auditUserDO == null ? "" : auditUserDO.getAuditUser()).set("order_status", TradeOrderStatusEnum.TRANSFER.getStatus()).set("audit_status", 1).eq("id", neworderId));
+                msg = "修改提交成功,等待管理员审核";
             }
 
             tradeOrderRoomModelMapper.deleteByOrderId(orderId);

+ 2 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/PayPlatService.java

@@ -23,6 +23,8 @@ public interface PayPlatService {
      */
     JSONObject createPayOrder(PayOrderReqVO payOrderReqVO, TradeOrderPayDO tradeOrderPayDO, TradeMchInfoDO tradeMchInfoDO);
 
+    JSONObject createDeposiPayOrder(PayOrderReqVO payOrderReqVO, TradeOrderPayDO tradeOrderPayDO, TradeMchInfoDO tradeMchInfoDO);
+
     /**
      * 创建退款
      */

+ 7 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/TradeOrderPayService.java

@@ -26,11 +26,18 @@ public interface TradeOrderPayService {
      */
     CommonResult<PayOrderRespVO> payOrder(PayOrderReqVO payOrderReqVO);
 
+    /**
+     * 定金支付
+     */
+    CommonResult<PayOrderRespVO> payDeposiOrder(PayOrderReqVO payOrderReqVO);
+
     /**
      * 处理支付成功通知,只有支付成功了,支付平台才调用
      */
     CommonResult<?> handlePayNotify(Map<String, Object> map);
 
+    CommonResult<?> handleDeposiPayNotify(Map<String, Object> map);
+
     /**
      * 支付单反查
      * @return 0待支付(轮询) 1已支付 2未支付 8888已支付等待结果(轮询)

+ 2 - 1
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/AdvancePayTypeServiceImpl.java

@@ -47,7 +47,8 @@ public class AdvancePayTypeServiceImpl implements PayTypeService {
         rechargeReqDTO.setAccountId(payOrderReqVO.getAccountId());
         rechargeReqDTO.setAccountType(payOrderReqVO.getAccountType());
         rechargeReqDTO.setAmount(tradeOrderPayDO.getPayAmount());
-        rechargeReqDTO.setRechargeType(DistributorTradeTypeEnum.BALANCE_RECHARGE.getType());//余额
+        //余额
+        rechargeReqDTO.setRechargeType(DistributorTradeTypeEnum.BALANCE_RECHARGE.getType());
         if(payOrderReqVO.getTradeType()!=null){
             rechargeReqDTO.setTradeType(payOrderReqVO.getTradeType());
         }else{

+ 2 - 1
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/CreditPayTypeServiceImpl.java

@@ -45,7 +45,8 @@ public class CreditPayTypeServiceImpl implements PayTypeService {
         rechargeReqDTO.setAccountId(payOrderReqVO.getAccountId());
         rechargeReqDTO.setAccountType(payOrderReqVO.getAccountType());
         rechargeReqDTO.setAmount(tradeOrderPayDO.getPayAmount());
-        rechargeReqDTO.setRechargeType(DistributorTradeTypeEnum.CREDIT_RECHARGE.getType());//授信
+        //授信
+        rechargeReqDTO.setRechargeType(DistributorTradeTypeEnum.CREDIT_RECHARGE.getType());
         rechargeReqDTO.setTradeType(DistributorTradeTypeEnum.CREDIT_TRANS.getType());
         rechargeReqDTO.setOrderId(String.valueOf(tradeOrderPayDO.getOrderId()));
         if(ObjectUtils.equalsAny(tradeOrderPayDO.getSellMethod(), SellMethodEnum.OTC.getType(),SellMethodEnum.OTC_MOVE_ORDER.getType()) && payOrderReqVO.getStoreId()!=null){

+ 98 - 0
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/PayPlatServiceImpl.java

@@ -146,6 +146,104 @@ public class PayPlatServiceImpl implements PayPlatService {
         }
     }
 
+    @Override
+    public JSONObject createDeposiPayOrder(PayOrderReqVO payOrderReqVO, TradeOrderPayDO tradeOrderPayDO, TradeMchInfoDO tradeMchInfoDO) {
+        try {
+            JSONObject paramMap = new JSONObject();
+            //支付平台主商户号
+            String customMchId = tradeOrderPayDO.getMerchantNo();
+            paramMap.set("channelId", tradeOrderPayDO.getChannelId());
+            paramMap.set("goods", payOrderReqVO.getPayParams().getParam());
+            paramMap.set("mchId", customMchId);
+            // 商户订单号
+            paramMap.set("mchOrderNo", tradeOrderPayDO.getId());
+            //分
+            paramMap.set("amount", tradeOrderPayDO.getPayAmount().multiply(new BigDecimal(100)).intValue());
+            // 币种, cny-人民币
+            paramMap.set("currency", "cny");
+            // 用户地址,IP或手机号
+            payOrderReqVO.getPayParams().setClientIp(ServletUtils.getClientIP());
+            paramMap.set("clientIp",  payOrderReqVO.getPayParams().getClientIp());
+
+            paramMap.set("msgType", payOrderReqVO.getPayParams().getMsgType());
+            //个人网银使用
+            paramMap.set("channelType", payOrderReqVO.getPayParams().getChannelType());
+            paramMap.set("returnUrl", payOrderReqVO.getPayParams().getPayReturnUrl());
+            //支付码
+            if(StringUtil.isNotEmpty(payOrderReqVO.getPayCode())) {
+                paramMap.set("payCode", payOrderReqVO.getPayCode());
+            }
+            // 主账号金额
+            paramMap.set("platformAmount", tradeOrderPayDO.getPayAmount().multiply(new BigDecimal(100)).intValue());
+
+            //设备--操作系统
+            ClientInfo clientInfo = new ClientInfo(ServletUtils.getUserAgent());
+            payOrderReqVO.getPayParams().setDevice(clientInfo.getOSName());
+            paramMap.set("device", payOrderReqVO.getPayParams().getDevice());
+
+            paramMap.set("subject",  payOrderReqVO.getPayParams().getSubject());
+            paramMap.set("body",  payOrderReqVO.getPayParams().getBody());
+            // 回调URL
+            paramMap.set("notifyUrl", payNotifyUrl.replace("payNotify", "deposiPayNotify"));
+
+            //扩展参数1
+            paramMap.set("param1", tradeOrderPayDO.getPaymentType());
+            //扩展参数2
+            paramMap.set("param2", payOrderReqVO.getPayParams().getParam());
+            //过期时间
+            paramMap.set("expireTime", "1800");
+            if( payOrderReqVO.getPayParams().getExtra() == null){
+                payOrderReqVO.getPayParams().setExtra(new JSONObject());
+            }
+            JSONObject extra = payOrderReqVO.getPayParams().getExtra();
+            extra.set("openId", tradeOrderPayDO.getOpenId());
+            //ALIPAY_WAP需要的参数
+            extra.set("productId", payOrderReqVO.getPayParams().getProductId());
+            extra.set("tradeChannel", payOrderReqVO.getPayParams().getTradeChannel());
+            extra.set("tranCode", payOrderReqVO.getPayParams().getTranCode());
+
+            extra.set("appId", payOrderReqVO.getPayParams().getAppId());
+
+            // 附加参数 经纬度信息也在extra参数中
+            paramMap.set("extra", extra);
+            String reqSign = PayDigestUtil.getSign(paramMap, tradeMchInfoDO.getReqKey());
+            // 签名
+            paramMap.set("sign", reqSign);
+            String reqJsonStr = paramMap.toString();
+            String reqDataEncode = "params=" + URLEncoder.encode(reqJsonStr, "UTF-8");
+            String reqData = "params=" +reqJsonStr;
+            log.info("请求支付中心下单接口,请求数据:{}", reqData);
+            String url = baseUrl + "/pay/create_order?";
+            String result = PayUtil.call4Post(url + reqDataEncode);
+            log.info("请求支付中心下单接口({}{}),响应数据:{}", url, reqDataEncode, result);
+            Map<String, Object> retMap = JSONUtil.parseObj(result);
+            if (StrUtil.equals(SUCCESS, MapUtils.getString(retMap, "retCode"))) {
+                // 补充参数
+                paramMap.set("payOrderId", MapUtils.getString(retMap, "payOrderId"));
+                if (retMap.containsKey("payOrder")) {
+                    Object payOrderStr = retMap.get("payOrder");
+                    JSONObject payOrder = JSONUtil.parseObj(payOrderStr);
+                    if (!payOrder.isEmpty()) {
+                        retMap.put("payOrder", paramMap);
+                    }
+                }
+                //非银联支付返回的支付二维码
+                if (retMap.get("payUrl") == null && retMap.get("codeUrl") != null) {
+                    retMap.put("payUrl", retMap.get("codeUrl"));
+                }
+                retMap.put("channelId", paramMap.getStr("channelId"));
+            }
+            retMap.put("mainMid", customMchId);
+            retMap.put("channelId", paramMap.getStr("channelId"));
+            return JSONUtil.parseObj(retMap);
+        } catch (ServiceException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            log.error("调用支付平台异常",ex);
+            throw exception(PAY_PLAT_UNKNOWN_EXCEPTION);
+        }
+    }
+
     @Override
     public JSONObject createRefundOrder(RefundRecordDO refundRecordDO, RefundDO refundDO, TradeOrderPayDO tradeOrderPayDO, TradeMchInfoDO tradeMchInfoDO) {
         try {

+ 178 - 2
ship-module-trade/ship-module-trade-biz/src/main/java/com/yc/ship/module/trade/service/pay/impl/TradeOrderPayServiceImpl.java

@@ -10,6 +10,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.yc.ship.framework.common.exception.ServiceException;
 import com.yc.ship.framework.common.lang.Asserts;
@@ -32,6 +33,7 @@ import com.yc.ship.module.trade.controller.admin.order.vo.order.PayOrderReqVO;
 import com.yc.ship.module.trade.controller.admin.order.vo.order.PayOrderRespVO;
 import com.yc.ship.module.trade.dal.dataobject.order.*;
 import com.yc.ship.module.trade.dal.dataobject.supplier.TradeSupplierOrderDO;
+import com.yc.ship.module.trade.dal.mysql.order.TradeOrderMapper;
 import com.yc.ship.module.trade.dal.mysql.order.TradeOrderTotalMapper;
 import com.yc.ship.module.trade.dal.mysql.order.TradeVisitorMapper;
 import com.yc.ship.module.trade.enums.*;
@@ -40,7 +42,6 @@ import com.yc.ship.module.trade.framework.common.ExceptionUtils;
 import com.yc.ship.module.trade.framework.common.TradeOrderLogUtils;
 import com.yc.ship.module.trade.service.bill.BillService;
 import com.yc.ship.module.trade.service.order.TradeOrderRepositoryService;
-import com.yc.ship.module.trade.service.order.bo.TradeOrderDetailBO;
 import com.yc.ship.module.trade.service.pay.PayPlatService;
 import com.yc.ship.module.trade.service.pay.PayTypeService;
 import com.yc.ship.module.trade.service.pay.TradeOrderPayService;
@@ -64,7 +65,6 @@ import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;
 import static com.yc.ship.module.ota.enums.ErrorCodeConstants.ORDER_PAY_AUTO_REFUND;
@@ -120,6 +120,9 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
     @Resource
     private TradeVisitorMapper tradeVisitorMapper;
 
+    @Resource
+    private TradeOrderMapper tradeOrderMapper;
+
     @Override
     public CommonResult<PayOrderRespVO> payOrder(PayOrderReqVO payOrderReqVO) {
         try {
@@ -168,6 +171,54 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
         return CommonResult.error(ORDER_PAY_FAIL);
     }
 
+    @Override
+    public CommonResult<PayOrderRespVO> payDeposiOrder(PayOrderReqVO payOrderReqVO) {
+        try {
+            Long orderId = payOrderReqVO.getOrderId();
+            String lockKey = String.format(UPDATE_ORDER_LOCK, orderId);
+            RLock lock = redissonClient.getLock(lockKey);
+            try {
+                if (lock.tryLock(60, 90, TimeUnit.SECONDS)) {
+                    //1.获取订单信息
+                    TradeOrderDO tradeOrder = tradeOrderRepositoryService.getById(payOrderReqVO.getOrderId());
+                    if (tradeOrder == null) {
+                        Asserts.isTrue(false, "订单不存在");
+                    } else {
+                        if (payOrderReqVO.getAccountId() == null && tradeOrder.getSourceId() != null) {
+                            payOrderReqVO.setAccountId(tradeOrder.getSourceId());
+                        }
+                        if (ObjectUtil.equal(tradeOrder.getDeposiStatus(), 2)) {
+                            //重复支付
+                            Asserts.isTrue(false, "定金已支付,不要重复操作");
+                        } else {
+                            //2.创建定金支付交易单
+                            payOrderReqVO.setPayAmount(tradeOrder.getDeposi());
+                            TradeOrderPayDO tradeOrderPayDO = buildOrderPay(tradeOrder, payOrderReqVO);
+                            payOrderReqVO.setStoreId(tradeOrder.getStoreId());
+                            tradeOrderRepositoryService.savePayOrder(tradeOrderPayDO);
+                            payOrderReqVO.setAccountName(tradeOrder.getSourceName());
+                            return doDeposiPayOrder(tradeOrderPayDO, payOrderReqVO);
+                        }
+                    }
+                } else {
+                    log.error("订单支付失败,未获取到锁。orderId:{}", orderId);
+                    return CommonResult.error(GET_LOCK_EXCEPTION);
+                }
+            } finally {
+                if (lock.isHeldByCurrentThread() && lock.isLocked()) {
+                    lock.unlock();
+                }
+            }
+        } catch (ServiceException e) {
+            ExceptionUtils.log(log, "下单支付失败:", e);
+            return CommonResult.error(e);
+        } catch (Exception e) {
+            log.error("下单支付失败:", e);
+            return CommonResult.error(ORDER_PAY_FAIL);
+        }
+        return CommonResult.error(ORDER_PAY_FAIL);
+    }
+
     @Override
     public CommonResult<?> handlePayNotify(Map<String, Object> map) {
         PayNotifyReqBO payNotifyReqSourceBO = new PayNotifyReqBO();
@@ -215,6 +266,54 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
         return CommonResult.success(null);
     }
 
+    @Override
+    public CommonResult<?> handleDeposiPayNotify(Map<String, Object> map) {
+        PayNotifyReqBO payNotifyReqSourceBO = new PayNotifyReqBO();
+        final PayNotifyReqBO payNotifyReqBO = BeanUtil.fillBeanWithMap(map, payNotifyReqSourceBO, false);
+        String lockKey = String.format(UPDATE_PAY_ORDER_LOCK, Long.parseLong(payNotifyReqBO.getMchOrderNo()));
+        RLock lock = redissonClient.getLock(lockKey);
+        try {
+            if (lock.tryLock(60, 90, TimeUnit.SECONDS)) {
+                TradeOrderPayDO tradeOrderPayDO = tradeOrderRepositoryService.getPayOrderByIdIgnoreTenant(Long.parseLong(payNotifyReqBO.getMchOrderNo()));
+                //如果支付单已经变为已支付,订单有无效需要自动退,又没有退的时候,就需要把支付单状态改为0,重新推通知
+                if (ObjectUtils.equalsAny(tradeOrderPayDO.getPayStatus(), PaymentStatusEnum.PAID.getStatus(), PaymentStatusEnum.AUTO_REFUND.getStatus())) {
+                    //返回成功,让支付平台无需再推通知
+                    return CommonResult.success(null);
+                }
+                Asserts.isTrue(ObjectUtils.equalsAny(tradeOrderPayDO.getPayStatus(), PaymentStatusEnum.INIT.getStatus(), PaymentStatusEnum.UNPAID.getStatus()), "支付单{}当前状态不可更改{}", payNotifyReqBO.getMchOrderNo(), tradeOrderPayDO.getPayStatus());
+                TenantUtils.execute(tradeOrderPayDO.getTenantId(), () -> {
+                    if (StrUtil.isBlank(tradeOrderPayDO.getPaymentNo())) {
+                        tradeOrderPayDO.setPaymentNo(payNotifyReqBO.getPayOrderId());
+                    }
+                    //银行账单号
+                    tradeOrderPayDO.setBillNo(payNotifyReqBO.getBillNo());
+                    //同步银行返回的支付时间
+                    if (StrUtil.isNotBlank(payNotifyReqBO.getBillDate())) {
+                        try {
+                            tradeOrderPayDO.setPaymentDate(DateUtil.parseLocalDateTime(payNotifyReqBO.getBillDate(), DatePattern.PURE_DATETIME_PATTERN));
+                        } catch (Exception e) {
+                            log.error("支付平台返回的支付时间转换错误{}", payNotifyReqBO.getBillDate());
+                        }
+                    }
+                    //4.1支付成功
+                    TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getById(tradeOrderPayDO.getOrderId());
+                    updateDeposiOrderPaid(tradeOrderDO,tradeOrderPayDO);
+                });
+            }
+        } catch (ServiceException e) {
+            ExceptionUtils.log(log, "支付通知处理异常:", e);
+            return CommonResult.error(e);
+        } catch (Exception e) {
+            log.error("支付通知处理异常:{}", payNotifyReqBO.getMchOrderNo(), e);
+        } finally {
+            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+
+        return CommonResult.success(null);
+    }
+
     @Override
     @TenantIgnore
     public CommonResult<?> payOrderQuery(Long payOrderId) {
@@ -483,6 +582,28 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
         return CommonResult.success(payOrderRespVO);
     }
 
+    private CommonResult<PayOrderRespVO> doDeposiPayOrder(TradeOrderPayDO tradeOrderPayDO, PayOrderReqVO payOrderReqVO) {
+        PayOrderRespVO payOrderRespVO = new PayOrderRespVO().setOrderPayId(tradeOrderPayDO.getId()).setOrderId(tradeOrderPayDO.getOrderId());
+
+        if (needPayPlatCreateOrder(payOrderReqVO, tradeOrderPayDO)) {
+            //3.调用支付平台,其结果不用于更新订单状态,需要通过支付查询或者异步通知变更订单状态
+            Map result = useDeposiPayPlatCreatePayOrder(payOrderReqVO, tradeOrderPayDO);
+            payOrderRespVO.setPayPlatResult(result);
+            if (result != null) {
+                tradeOrderPayDO.setPayParams(JsonUtils.toJsonString(result));
+            }
+            tradeOrderRepositoryService.updatePayOrderPayParams(tradeOrderPayDO);
+        } else {
+            //4.其他支付方式
+            String tradeId = useOtherPayType(payOrderReqVO, tradeOrderPayDO);
+            tradeOrderPayDO.setPaymentNo(tradeId);
+            //4.1支付成功
+            TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getById(payOrderReqVO.getOrderId());
+            updateDeposiOrderPaid(tradeOrderDO,tradeOrderPayDO);
+        }
+        return CommonResult.success(payOrderRespVO);
+    }
+
     private CommonResult<?> afterPaySuccessWithHeldLock(TradeOrderPayDO tradeOrderPayDO) {
         //更新支付单状态
         updatePayOrderSuccess(tradeOrderPayDO);
@@ -565,6 +686,15 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
         TradeOrderLogUtils.setOrderInfo(tradeOrderDO.getId(), orderStatus, tradeOrderDO.getOrderStatus(), MapUtil.<String, Object>builder().put("payType", PayTypeEnum.valueOf(tradeOrderPayDO.getPaymentType()).getName()).put("payAmount", tradeOrderPayDO.getPayAmount()).build());
     }
 
+    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ORDER_DEPOSI_PAY)
+    public void updateDeposiOrderPaid(TradeOrderDO tradeOrderDO, TradeOrderPayDO tradeOrderPayDO) {
+        Integer orderStatus = tradeOrderDO.getOrderStatus();
+        tradeOrderMapper.update(new LambdaUpdateWrapper<TradeOrderDO>()
+                .eq(TradeOrderDO::getId, tradeOrderDO.getId()).set(TradeOrderDO::getDeposiStatus, 2).set(TradeOrderDO::getDeposiPayTime, LocalDateTime.now()));
+        //保存订单日志
+        TradeOrderLogUtils.setOrderInfo(tradeOrderDO.getId(), orderStatus, tradeOrderDO.getOrderStatus(), MapUtil.<String, Object>builder().put("payType", PayTypeEnum.valueOf(tradeOrderPayDO.getPaymentType()).getName()).put("payAmount", tradeOrderPayDO.getPayAmount()).build());
+    }
+
     @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ORDER_PAY)
     public void updateOrderPaying(TradeOrderDO tradeOrderDO, TradeOrderPayDO tradeOrderPayDO) {
         Integer orderStatus = tradeOrderDO.getOrderStatus();
@@ -709,6 +839,52 @@ public class TradeOrderPayServiceImpl implements TradeOrderPayService {
         return result;
     }
 
+    private Map useDeposiPayPlatCreatePayOrder(PayOrderReqVO payOrderReqVO, TradeOrderPayDO tradeOrderPayDO) {
+        Asserts.isTrue(payOrderReqVO.getPayParams() != null, "支付参数不能为空");
+        //获取当前租户配置的支付平台商户号
+        String mchId;
+        if (PAY_ORDER_TYPE_OTHER == tradeOrderPayDO.getOrderType()) {
+            //如果是其他支付单,获取平台配置
+            mchId = configApi.getPlatformConfigValueByKey("payPlatMchId");
+        } else {
+            //获取当前租户配置的支付平台商户号
+            mchId = configApi.getConfigValueByKey("payPlatMchId");
+        }
+        Asserts.isTrue(StrUtil.isNotBlank(mchId), "当前租户未配置商户号");
+        TradeMchInfoDO tradeMchInfoDO = tradeOrderRepositoryService.getByMchId(mchId);
+        Asserts.isTrue(tradeMchInfoDO != null, "未配置商户号信息{}", tradeMchInfoDO);
+        //根据支付方式获取channelId
+        String name = tradeOrderPayDO.getOrderType() == PAY_ORDER_TYPE_TRADE ? SellMethodEnum.valueOf(tradeOrderPayDO.getSellMethod()).name() : PaySourceEnum.valueOf(tradeOrderPayDO.getSellMethod()).name();
+        String channelId = getChannelIdByPayType(tradeOrderPayDO.getOrderType(), name, PayTypeEnum.valueOf(tradeOrderPayDO.getPaymentType()), payOrderReqVO.getPayExtraType());
+        if (tradeMchInfoDO != null) {
+            tradeOrderPayDO.setMerchantNo(tradeMchInfoDO.getMchId());
+        }
+        tradeOrderPayDO.setChannelId(channelId);
+        tradeOrderPayDO.setOpenId(payOrderReqVO.getOpenId());
+        //补充支付参数
+        if (tradeOrderPayDO.getOrderType() == PAY_ORDER_TYPE_TRADE) {
+            TradeDetailDO tradeDetailDO = tradeOrderRepositoryService.getOrderAnyDetail(tradeOrderPayDO.getOrderId());
+            PayOrderReqVO.PayParams payParams = payOrderReqVO.getPayParams();
+            payParams.setParam(tradeDetailDO.getProductName());
+            payParams.setSubject(payOrderReqVO.getAccountName());
+            payParams.setBody(tradeDetailDO.getProductName());
+            payParams.setProductId(tradeDetailDO.getProductId().toString());
+        }
+
+        JSONObject result = payPlatService.createDeposiPayOrder(payOrderReqVO, tradeOrderPayDO, tradeMchInfoDO);
+        Asserts.isTrue(StrUtil.equals(SUCCESS, MapUtils.getString(result, "retCode")), "定金支付调用支付平台失败");
+        //保存支付平台支付单号
+        String payOrderId = MapUtil.getStr(result, "payOrderId");
+        if (StrUtil.isNotBlank(payOrderId)) {
+            tradeOrderPayDO.setPaymentNo(payOrderId);
+        }
+        if (payOrderReqVO.getPayParams() != null) {
+            tradeOrderPayDO.setReqParams(JsonUtils.toJsonString(payOrderReqVO.getPayParams()));
+        }
+
+        return result;
+    }
+
     private String getChannelIdByPayType(int orderType, String name, PayTypeEnum payType, Integer payExtraType) {
         String key = name + "_" + payType.name();
         if (payExtraType != null) {

+ 1 - 0
ship-server-web/src/main/resources/application.yaml

@@ -291,6 +291,7 @@ yudao:
       - /travl-app-api/test/index # 基于名字获取租户,不许带租户编号
       - /travl-app-api/trade/orderTest # 基于名字获取租户,不许带租户编号
       - /travl-app-api/trade/payNotify
+      - /travl-app-api/trade/deposiPayNotify
       - /travl-app-api/trade/refundNotify
       - /travl-app-api/system/sms/callback/aliyun
       - /${yudao.web.admin-url}/notify/** # 统一消息服务,接收消息的接口,不需要登录