刘俊驰 6 月之前
父节点
当前提交
a4f2366fa3
共有 15 个文件被更改,包括 435 次插入103 次删除
  1. 24 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserOrderClient.java
  2. 71 12
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java
  3. 11 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java
  4. 1 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  5. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/RedisCacheService.java
  6. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderPaymentService.java
  7. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentCoreService.java
  8. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentOrderService.java
  9. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentMerchantConfigServiceImpl.java
  10. 14 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderPaymentServiceImpl.java
  11. 109 35
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  12. 148 50
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  13. 29 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentOrderServiceImpl.java
  14. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java
  15. 1 1
      pom.xml

+ 24 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserOrderClient.java

@@ -2,6 +2,8 @@ package com.yonge.cooleshow.admin.controller.open;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
@@ -10,6 +12,7 @@ import com.yonge.cooleshow.biz.dal.service.UserOrderPaymentService;
 import com.yonge.cooleshow.biz.dal.service.UserOrderRefundService;
 import com.yonge.cooleshow.biz.dal.service.UserOrderService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.ContractDto;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -25,6 +28,8 @@ import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
 import com.yonge.toolset.payment.core.service.PaymentClient;
 import com.yonge.toolset.payment.util.DistributedLock;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -40,6 +45,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 @RestController
@@ -54,6 +60,9 @@ public class UserOrderClient extends BaseController {
     private UserOrderRefundService userOrderRefundService;
     @Autowired
     private UserOrderService userOrderService;
+
+    @Autowired
+    private UserOrderPaymentService userOrderPaymentService;
     @Autowired
     private PaymentClient paymentClient;
     @Autowired
@@ -203,4 +212,19 @@ public class UserOrderClient extends BaseController {
         paymentService.setContractRecord(contract.getType(), contract.getUserId());
         return succeed(true);
     }
+
+    @ApiOperation(value = "关闭订单测试", notes = "关闭订单测试")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "orderNo", value = "订单号", dataType = "String")
+    })
+    @GetMapping("/closedV1/{orderNo}")
+    public HttpResponseResult<Boolean> testOrderClosed(@PathVariable("orderNo") String orderNo) {
+        if (!debugMode) {
+            return HttpResponseResult.failed("当前环境不允许调用");
+        }
+        // 测试订单关闭
+        userOrderPaymentService.onlyClosePaymentAndReqOpen( orderNo,"关闭订单测试");
+
+        return HttpResponseResult.succeed();
+    }
 }

+ 71 - 12
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java

@@ -11,20 +11,17 @@ import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.middleware.payment.common.api.PaymentServiceContext;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.RefundResp;
+import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
 import com.yeepay.g3.sdk.yop.encrypt.DigitalEnvelopeDTO;
 import com.yeepay.g3.sdk.yop.utils.DigitalEnvelopeUtils;
 import com.yeepay.g3.sdk.yop.utils.RSAKeyUtils;
 import com.yonge.cooleshow.biz.dal.entity.PaymentMerchantConfig;
 import com.yonge.cooleshow.biz.dal.entity.TenantMember;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
-import com.yonge.cooleshow.biz.dal.service.PaymentMerchantConfigService;
-import com.yonge.cooleshow.biz.dal.service.TenantMemberService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderRefundBillService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderService;
-import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
-import com.yonge.cooleshow.biz.dal.service.UserPaymentOrderService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.enums.EPayerType;
+import com.yonge.cooleshow.common.enums.payment.EPaymentStatus;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -33,12 +30,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
 
 import javax.servlet.http.HttpServletRequest;
 import java.security.PrivateKey;
@@ -101,6 +94,60 @@ public class UserPaymentClient {
         return paymentServiceContext.getPaymentService(vendor).returnNotifyResult(request);
     }
 
+    /**
+     * 关闭订单测试
+     * @param orderNo 订单号
+     * @return R<UserPaymentOrderVo.UserPaymentOrder>
+     */
+    @ApiOperation(value = "关闭订单测试", notes = "关闭订单测试")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "orderNo", value = "订单号", dataType = "String")
+    })
+    @GetMapping("/closed/{orderNo}")
+    public R<Object> testOrderClosed(@PathVariable("orderNo") String orderNo) {
+
+        // 支付订单详情
+        UserPaymentOrderWrapper.UserPaymentOrder paymentOrder = userPaymentOrderService.getUserPaymentOrderByOrderNo( orderNo);
+        if (Objects.isNull(paymentOrder)) {
+            throw BizException.from("订单不存在");
+        }
+
+        // 测试订单关闭
+        PaymentResp paymentResp = userPaymentCoreService.closedPayment( paymentOrder);
+
+        return R.from(paymentResp);
+    }
+
+    @ApiOperation(value = "关单消息回调", notes = "三方支付平台关单消息通知")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "vendor", value = "服务提供方", dataType = "String")
+    })
+    @RequestMapping(value = "/closed/callback/{vendor}", method = {RequestMethod.GET, RequestMethod.POST})
+    public String closed(@PathVariable("vendor") String vendor, HttpServletRequest request) {
+
+        // 支付回调消息
+        PaymentResp paymentResp = paymentServiceContext.getPaymentService(vendor).callbackNotifyForClosed(request);
+        // 关单回调对象为空或关闭失败,直接返回忽略后续流程
+        if (Objects.isNull(paymentResp) || paymentResp.getPaymentStatus() != PaymentStatus.CLOSED) {
+            return null;
+        }
+        log.info("closed vendor={}, paymentResp={}", vendor, JSON.toJSONString(paymentResp));
+
+        // 支付订单确认
+        UserPaymentOrderWrapper.UserPaymentOrder paymentOrder = userPaymentOrderService.getUserPaymentOrderByTranNo(paymentResp.getTransNo());
+        if (Objects.isNull(paymentOrder) || paymentOrder.getStatus() == EPaymentStatus.PAID || paymentOrder.getStatus() == EPaymentStatus.CLOSED) {
+            return paymentResp.getMsg();
+        }
+        // 关单订单编号
+        paymentResp.setMerOrderNo(paymentOrder.getOrderNo());
+
+        // 执行支付回调流程
+        userPaymentCoreService.executePaymentCallback(paymentResp);
+
+        return paymentServiceContext.getPaymentService(vendor).returnNotifyResult(request);
+    }
+
+
     @ApiOperation(value = "用户付款", notes = "用户付款")
     @PostMapping("/executePayment/v2")
     public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderWrapper.PaymentOrderReqConfig config,
@@ -274,4 +321,16 @@ public class UserPaymentClient {
         }
         return null;
     }
+
+    @ApiOperation(value = "订单付款状态", notes = "订单付款状态")
+    @PostMapping("/paymentStatus/{orderNo}")
+    public R<Boolean> paymentStatus(@PathVariable("orderNo") String orderNo) {
+
+
+        // 用户订单支付状态
+
+        userPaymentCoreService.paymentStatus(orderNo);
+
+        return R.from(false);
+    }
 }

+ 11 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.student.controller;
 
 import cn.hutool.extra.servlet.ServletUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.microsvc.toolkit.common.response.template.R;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
@@ -392,5 +393,15 @@ public class UserOrderController extends BaseController {
         return HttpResponseResult.succeed(orderPayTypeResp);
     }
 
+    @ApiOperation(value = "订单定时同步测试", notes = "订单定时同步测试")
+    @GetMapping("/payment/testPaymentSync")
+    public R<JSONObject> testPaymentSync() {
+
+        // 定时扫描待支付订单是否已超时
+        userPaymentCoreService.scanPaymentTimeoutOrderRecord();
+
+        return R.defaultR();
+    }
+
 
 }

+ 1 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java

@@ -478,5 +478,6 @@ public interface SysConfigConstant {
      */
     String TENANT_ALBUM_MUSIC_TYPE_CATEGORY = "tenant_album_music_type_category";
     String COURSE_SUBJECT_MAP = "course_subject_map";
+    String ADAPAY_CLOSE_ORDER_NOTIFY = "adapay_close_order_notify";
     String LOGOFF_IMG = "logoff_img";
 }

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/RedisCacheService.java

@@ -47,7 +47,7 @@ public interface RedisCacheService {
      * @param userId 用户Id
      * @return String
      */
-    String getUserPaymentConfig(String userId, String orderType);
+    String getUserPaymentConfig(String userId, String orderNo);
 
     /**
      * 删除用户支付配置

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderPaymentService.java

@@ -59,6 +59,8 @@ public interface UserOrderPaymentService extends IService<UserOrderPayment> {
     Boolean closePaymentAndReqOpen(String orderNo, String reason);
 
 
+    UserOrderPayment onlyClosePaymentAndReqOpen(String orderNo, String reason);
+
     /***
      * 创建付款单
      * @author liweifan

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentCoreService.java

@@ -4,6 +4,7 @@ import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.RefundResp;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 用户支付订单服务
@@ -85,4 +86,17 @@ public interface UserPaymentCoreService {
     void refundPayment(String orderNo,  String reason);
 
     void refundOnly(String reason, String orderNo);
+
+
+    /**
+     * 关闭订单
+     *
+     * @param userInfo     JwtUserInfo
+     * @param paymentOrder UserPaymentOrder
+     * @return PaymentResp
+     */
+    PaymentResp closedPayment( UserPaymentOrderWrapper.UserPaymentOrder paymentOrder);
+
+    @Transactional
+    void paymentStatus(String orderNo);
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentOrderService.java

@@ -59,4 +59,6 @@ public interface UserPaymentOrderService   {
      *
      */
     void save(UserPaymentOrderWrapper.UserPaymentOrder orderReq);
+
+    UserPaymentOrderWrapper.UserPaymentOrder getUserPaymentOrderByTranNo(String transNo);
 }

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentMerchantConfigServiceImpl.java

@@ -10,6 +10,8 @@ import com.microsvc.toolkit.middleware.payment.impl.AliPaymentServicePlugin;
 import com.microsvc.toolkit.middleware.payment.impl.WxPaymentServicePlugin;
 import com.microsvc.toolkit.middleware.payment.impl.YeepayPaymentServicePlugin;
 import com.microsvc.toolkit.middleware.payment.properties.PayConfigProperties;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.enums.EPayerType;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +38,9 @@ public class PaymentMerchantConfigServiceImpl extends ServiceImpl<PaymentMerchan
     @Autowired
     private PayConfigProperties properties;
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
     @PostConstruct
     public void init(){
         List<PaymentMerchantConfig> list = this.list();
@@ -43,6 +48,7 @@ public class PaymentMerchantConfigServiceImpl extends ServiceImpl<PaymentMerchan
         if(CollectionUtils.isEmpty(list)) {
             return;
         }
+        String notify = sysConfigService.findConfigValue(SysConfigConstant.ADAPAY_CLOSE_ORDER_NOTIFY);
 
         List<String> pluginNames = Lists.newArrayList();
         for (PaymentMerchantConfig config : list) {
@@ -58,6 +64,7 @@ public class PaymentMerchantConfigServiceImpl extends ServiceImpl<PaymentMerchan
                 adapayPayConfig.setMerchantId(config.getApiKey());
                 adapayPayConfig.setPayNotifyUrl(properties.getPayNotifyUrl());
                 adapayPayConfig.setRefundNotifyUrl(properties.getRefundNotifyUrl());
+                adapayPayConfig.setClosedNotifyUrl(notify);
                 adapayPayConfig.setKeyPublic(config.getRsaPublicKey());
                 adapayPayConfig.setKeyPrivate(config.getRsaPrivateKey());
                 adapayPayConfig.setWxAppId(config.getWxAppId());

+ 14 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderPaymentServiceImpl.java

@@ -94,9 +94,19 @@ public class UserOrderPaymentServiceImpl extends ServiceImpl<UserOrderPaymentDao
 
     @Override
     public Boolean closePaymentAndReqOpen(String orderNo, String reason) {
+        UserOrderPayment userOrderPayment = onlyClosePaymentAndReqOpen(orderNo, reason);
+        if (userOrderPayment != null) {
+            updateById(userOrderPayment);
+        }
+        return true;
+    }
+
+
+    @Override
+    public UserOrderPayment onlyClosePaymentAndReqOpen(String orderNo, String reason) {
         UserOrderPayment orderPayment = baseMapper.selectOne(Wrappers.<UserOrderPayment>lambdaQuery().eq(UserOrderPayment::getOrderNo, orderNo).eq(UserOrderPayment::getStatus, TradeStatusEnum.pending));
         if (null == orderPayment) {
-            return true;
+            return null;
         }
         //更新付款单
         orderPayment.setStatus(TradeStatusEnum.close);
@@ -123,8 +133,7 @@ public class UserOrderPaymentServiceImpl extends ServiceImpl<UserOrderPaymentDao
                 }
             }
         }
-        updateById(orderPayment);
-        return true;
+        return orderPayment;
     }
 
     @Override
@@ -198,7 +207,8 @@ public class UserOrderPaymentServiceImpl extends ServiceImpl<UserOrderPaymentDao
     @Transactional(rollbackFor = Exception.class)
     public void executePaymentCallBack(PaymentCallBack data) {
         UserOrderVo userOrderVo = userOrderService.getUserOrderByPaymentNoOrTransNo(data.getPaymentNo(), data.getId());
-        if (OrderStatusEnum.WAIT_PAY.equals(userOrderVo.getStatus()) || OrderStatusEnum.PAYING.equals(userOrderVo.getStatus())) {
+        if (OrderStatusEnum.WAIT_PAY.equals(userOrderVo.getStatus()) || OrderStatusEnum.PAYING.equals(userOrderVo.getStatus())
+            || OrderStatusEnum.PAID.equals(userOrderVo.getStatus())) {
             if (TradeStatusEnum.succeeded.equals(data.getStatus())) {//支付成功
                 paymentSucceededHandle(data);
             } else if (TradeStatusEnum.failed.equals(data.getStatus())) {//支付失败

+ 109 - 35
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java

@@ -269,8 +269,20 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public UserOrderVo detailApp(UserOrder param) {
+
         UserOrderVo userOrderVo = baseMapper.detailApp(param);
+
+        if (userOrderVo.getStatus() == OrderStatusEnum.PAYING ) {
+            if (userOrderVo.getPaymentVersion() == EPaymentVersion.V1) {
+                paymentStatus(userOrderVo.getOrderNo());
+
+            } else if (userOrderVo.getPaymentVersion() == EPaymentVersion.V2) {
+                userPaymentCoreService.paymentStatus(userOrderVo.getOrderNo());
+            }
+        }
+        userOrderVo = baseMapper.detailApp(param);
         userOrderDetail(userOrderVo);
         return userOrderVo;
     }
@@ -838,6 +850,58 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         }
     }
 
+    private void paymentStatus(String orderNo) {
+        UserOrderVo detail = detail(orderNo, null);
+        if (null == detail) {
+            return;
+        }
+        if (!OrderStatusEnum.WAIT_PAY.equals(detail.getStatus())
+            && !OrderStatusEnum.PAYING.equals(detail.getStatus())) {
+            return;
+        }
+        UserOrderPayment userOrderPayment = orderPaymentService.detailByTransNoOrPaymentNo(detail.getTransNo(), detail.getPaymentNo());
+        if (userOrderPayment == null) {
+            return;
+        }
+
+        Payment param = new Payment(detail.getOpenType(),
+                PaymentClientEnum.valueOf(userOrderPayment.getPaymentClient()), detail.getPayChannel());
+        param.setId(detail.getTransNo());
+        param.setPaymentNo(detail.getPaymentNo());
+        BaseResult<Payment> res = paymentClient.queryPayment(param);
+        Payment queryPaymentData = res.getData();
+
+        //支付成功
+        if (res.getStatus() && TradeStatusEnum.succeeded.getCode().equals(queryPaymentData.getStatus().getCode())) {
+            //订单已经完成,则完成订单
+            orderSuccess(detail);
+            //付款单改为已完成状态
+            userOrderPayment.setTransNo(queryPaymentData.getId());
+            userOrderPayment.setStatus(TradeStatusEnum.succeeded);
+            userOrderPayment.setUpdateTime(new Date());
+            userOrderPayment.setArrivalTime(new Date());
+            if (queryPaymentData.getPayAmt() != null) {
+                userOrderPayment.setBackPayAmt(new BigDecimal(queryPaymentData.getPayAmt()));
+            }
+
+            ExecutePaymentCallBack executePaymentCallBack = queryPaymentData.getExecutePaymentCallBack();
+            if (null != executePaymentCallBack) {
+                userOrderPayment.setArrivalTime(executePaymentCallBack.getTradeTime());
+                if (executePaymentCallBack.getPayAmt() != null) {
+                    userOrderPayment.setBackPayAmt(
+                            new BigDecimal(executePaymentCallBack.getPayAmt()));
+                    userOrderPayment.setFeeAmt(new BigDecimal(executePaymentCallBack.getFeeAmt()));
+                }
+
+            }
+            orderPaymentService.updateById(userOrderPayment);
+        } else if (res.getStatus() && TradeStatusEnum.close ==queryPaymentData.getStatus()) {
+
+            //关闭订单
+            doOrderCancel(detail, OrderStatusEnum.CLOSE, "三方订单已关闭");
+        }
+    }
+
     /**
      * 判断订单是否完成,若订单已完成则完成订单
      *
@@ -1141,46 +1205,56 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void orderSuccess(UserOrderVo detail, PaymentCallBack data) {
-        //订单已完成
-        if (!OrderStatusEnum.WAIT_PAY.equals(detail.getStatus())
-                && !OrderStatusEnum.PAYING.equals(detail.getStatus())) {
-            return;
-        }
+    public void orderSuccess(UserOrderVo detailInfo, PaymentCallBack data) {
 
-        //修改订单状态
-        Date now = new Date();
-        detail.setStatus(OrderStatusEnum.PAID);
-        detail.setPayTime(now);
-        detail.setUpdateTime(now);
-        updateById(detail);
-
-        if (null != data) {
-            //更新付款单
-            UserOrderPayment orderPayment = orderPaymentService
-                    .detailByTransNoOrPaymentNo(data.getId(), data.getPaymentNo());
-            if (null != orderPayment) {
-                orderPayment.setTransNo(data.getId());
-                orderPayment.setStatus(TradeStatusEnum.succeeded);
-                orderPayment.setArrivalTime(now);
-                orderPayment.setUpdateTime(now);
-
-                if (null != data.getExecutePaymentCallBack()) {
-                    orderPayment.setBackPayAmt(
-                            new BigDecimal(data.getExecutePaymentCallBack().getPayAmt()));
-
-                    BigDecimal feeAmt = new BigDecimal(data.getExecutePaymentCallBack().getFeeAmt());
-                    if (BigDecimal.ZERO.compareTo(feeAmt) == 0) {
-                        orderPayment.setFeeAmt(orderPayment.getPayAmt().subtract(orderPayment.getBackPayAmt()));
-                    } else {
-                        orderPayment.setFeeAmt(feeAmt);
+        // 加订单锁
+
+        // 用户下单请求锁
+        String lockName = redisCacheService.getPaymentCacheKey(detailInfo.getOrderNo());
+        DistributedLock.of(redissonClient).runIfLockCanGet(lockName, () -> {
+
+            UserOrderVo detail= detail(detailInfo.getId());
+            //订单已完成
+            if (!OrderStatusEnum.WAIT_PAY.equals(detail.getStatus())
+                    && !OrderStatusEnum.PAYING.equals(detail.getStatus())) {
+                return;
+            }
+
+            //修改订单状态
+            Date now = new Date();
+            detail.setStatus(OrderStatusEnum.PAID);
+            detail.setPayTime(now);
+            detail.setUpdateTime(now);
+            updateById(detail);
+
+            if (null != data) {
+                //更新付款单
+                UserOrderPayment orderPayment = orderPaymentService
+                        .detailByTransNoOrPaymentNo(data.getId(), data.getPaymentNo());
+                if (null != orderPayment) {
+                    orderPayment.setTransNo(data.getId());
+                    orderPayment.setStatus(TradeStatusEnum.succeeded);
+                    orderPayment.setArrivalTime(now);
+                    orderPayment.setUpdateTime(now);
+
+                    if (null != data.getExecutePaymentCallBack()) {
+                        orderPayment.setBackPayAmt(
+                                new BigDecimal(data.getExecutePaymentCallBack().getPayAmt()));
+
+                        BigDecimal feeAmt = new BigDecimal(data.getExecutePaymentCallBack().getFeeAmt());
+                        if (BigDecimal.ZERO.compareTo(feeAmt) == 0) {
+                            orderPayment.setFeeAmt(orderPayment.getPayAmt().subtract(orderPayment.getBackPayAmt()));
+                        } else {
+                            orderPayment.setFeeAmt(feeAmt);
+                        }
                     }
+                    orderPaymentService.updateById(orderPayment);
                 }
-                orderPaymentService.updateById(orderPayment);
             }
-        }
 
-        paySuccess(detail);
+            paySuccess(detail);
+
+        },10L,TimeUnit.SECONDS);
     }
 
     /**

+ 148 - 50
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java

@@ -14,6 +14,7 @@ import com.microsvc.toolkit.middleware.payment.common.api.PaymentServiceContext;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.*;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.DivideBackStatus;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
+import com.microsvc.toolkit.middleware.payment.enums.EPaymentVendor;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
@@ -233,31 +234,8 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                 throw new BizException("无效的支付订单");
             }
 
-            // 订单已关闭返回异常信息,更新订单状态为已支付,后续流程不处理,允许用户进行退款操作
-            if (EPaymentStatus.CLOSED == paymentOrder.getStatus() && StringUtils.isNotBlank(paymentOrder.getErrorMsg())) {
-
-                // 支付成功
-                if (PaymentStatus.SUCCESSED == paymentResp.getPaymentStatus()) {
-
-
-                    // 根据支付回调消息,更新订单状态
-                    executePaymentSuccess(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(paymentOrder)), paymentResp);
-
-//                    UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
-//                        .builder()
-//                        .transNo(paymentResp.getTransNo())
-//                        .id(paymentOrder.getId())
-//                        .status(PAID)
-//                        .updateTime(DateTime.now().toDate())
-//                        .build();
-//                    userPaymentOrderService.updateById(order);
-
-                    log.error("executePaymentCallback 关单异常,更新订单状态为已支付, error={}, status={}, paymentResp={}", paymentOrder.getErrorMsg(),
-                        paymentOrder.getStatus(), JSON.toJSONString(paymentResp));
-                }
-            } else
             // 订单状态为待支付、支付中时,更新订单状态;
-            if (EPaymentStatus.WAIT_PAY == paymentOrder.getStatus() || EPaymentStatus.PAYING == paymentOrder.getStatus()) {
+            if (EPaymentStatus.WAIT_PAY == paymentOrder.getStatus() || EPaymentStatus.PAYING == paymentOrder.getStatus() || PAID == paymentOrder.getStatus()) {
 
                 // 支付成功
                 if (PaymentStatus.SUCCESSED == paymentResp.getPaymentStatus()) {
@@ -266,14 +244,14 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                 }
 
                 // 支付失败
-                if (PaymentStatus.FAILED == paymentResp.getPaymentStatus()) {
+                if (PaymentStatus.FAILED == paymentResp.getPaymentStatus() || PaymentStatus.CLOSED == paymentResp.getPaymentStatus()) {
 
                     // 支付失败,取消订单且更新订单状态
                     UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
                         .builder()
                         .transNo(paymentResp.getTransNo())
                         .id(paymentOrder.getId())
-                        .status(EPaymentStatus.FAIL)
+                        .status(PaymentStatus.FAILED == paymentResp.getPaymentStatus() ? EPaymentStatus.FAIL: EPaymentStatus.CLOSED)
                         .updateTime(DateTime.now().toDate())
                         .build();
                     userPaymentOrderService.updateById(order);
@@ -284,6 +262,13 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
 
                 log.info("executePaymentCallback WAIT_PAY, status={}, paymentResp={}", paymentOrder.getStatus(),
                     JSON.toJSONString(paymentResp));
+            } else {
+
+                // 支付成功
+                if (PaymentStatus.SUCCESSED == paymentResp.getPaymentStatus()) {
+                    // 根据支付回调消息,更新订单状态
+                    refundOnly("订单已超时,金额原路退回", paymentOrder.getOrderNo());
+                }
             }
 
         }, 60L, TimeUnit.SECONDS);
@@ -413,7 +398,15 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
 
                 // 提示订单支付已完成
                 throw new BizException("订单支付已完成");
-            }
+            } else
+
+            // 三方订单关闭
+            if ((PaymentStatus.CLOSED == paymentResp.getPaymentStatus() || PaymentStatus.FAILED == paymentResp.getPaymentStatus())
+                && EPaymentStatus.CLOSED != paymentOrder.getStatus()) {
+
+                // 更新订单状态为已关闭
+                closeWaitOrder(paymentOrder);
+            } else
 
             // 订单未支付,后续直接更新订单状态为已关闭
             if (PaymentStatus.PENDDING == paymentResp.getPaymentStatus()) {
@@ -446,8 +439,6 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                                 // 更新订单退款异常信息
                                 userPaymentOrderService.updateById(order);
 
-                                // 订单关闭后的数据处理流程
-                                userOrderService.payCancel(userOrderService.detail(order.getId()));
                             });
                             throw new BizException("查询交易中,请耐心等待!");
                         }
@@ -711,15 +702,15 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             if (EPaymentStatus.WAIT_PAY == userPaymentOrder.getStatus() || EPaymentStatus.PAYING == userPaymentOrder.getStatus()) {
 
                 // 订单完成后续流程
-                SpringContextHolder.getBean(UserPaymentCoreService.class)
+                applicationContext.getBean(UserPaymentCoreService.class)
                     .executePaymentSuccess(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(userPaymentOrder)), paymentResp);
             }
 
             // 删除支付配置
-            redisCacheService.deleteUserPaymentConfig(userId, userPaymentOrder.getOrderType().getCode());
+            redisCacheService.deleteUserPaymentConfig(userId, userPaymentOrder.getOrderNo());
 
             // 删除下单配置
-            redisCacheService.deleteUserOrderConfig(userId, userPaymentOrder.getOrderType().getCode());
+            redisCacheService.deleteUserOrderConfig(userId, userPaymentOrder.getOrderNo());
         }
 
         // 三方支付失败
@@ -734,11 +725,26 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             userPaymentOrderService.updateById(update);
 
             // 订单关闭流程
-            SpringContextHolder.getBean(UserPaymentCoreService.class)
+            applicationContext.getBean(UserPaymentCoreService.class)
                 .cancelPayment(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(userPaymentOrder)), paymentResp);
 
             // 删除本地缓存
-            redisCacheService.deleteUserPaymentConfig(userId, userPaymentOrder.getOrderType().getCode());
+            redisCacheService.deleteUserPaymentConfig(userId, userPaymentOrder.getOrderNo());
+        }
+
+        // 三方订单关闭状态
+        if (PaymentStatus.CLOSED == paymentResp.getPaymentStatus() && EPaymentStatus.CLOSED != userPaymentOrder.getStatus()) {
+
+            // 订单关闭流程
+            applicationContext.getBean(UserPaymentCoreService.class)
+                .cancelPayment(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(userPaymentOrder)), paymentResp);
+
+            // 删除本地缓存
+            redisCacheService.deleteUserPaymentConfig(userId, userPaymentOrder.getOrderNo());
+
+            // 删除下单配置
+            redisCacheService.deleteUserOrderConfig(userId, userPaymentOrder.getOrderNo());
+
         }
     }
 
@@ -923,17 +929,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             if (StringUtils.isEmpty(paymentOrder.getTransNo())
                     && (EPaymentStatus.WAIT_PAY == paymentOrder.getStatus()||EPaymentStatus.PAYING == paymentOrder.getStatus())) {
 
-                // 直接关闭订单
-                UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
-                    .builder()
-                    .id(paymentOrder.getId())
-                    .status(EPaymentStatus.CLOSED)
-                    .updateTime(DateTime.now().toDate())
-                    .build();
-                userPaymentOrderService.updateById(order);
-
-                // 订单关闭后的数据处理流程
-                userOrderService.payCancel(userOrderService.detail(order.getId()));
+                closeWaitOrder(paymentOrder);
 
             } else {
                 // 获取三方支付订单信息,根据订单状处理
@@ -953,6 +949,20 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
 
     }
 
+    private void closeWaitOrder(UserPaymentOrderWrapper.UserPaymentOrder paymentOrder) {
+        // 直接关闭订单
+        UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
+            .builder()
+            .id(paymentOrder.getId())
+            .status(EPaymentStatus.CLOSED)
+            .updateTime(DateTime.now().toDate())
+            .build();
+        userPaymentOrderService.updateById(order);
+
+        // 订单关闭后的数据处理流程
+        userOrderService.payCancel(userOrderService.detail(order.getId()));
+    }
+
 
     /**
      * 扫描支付超时定时
@@ -978,7 +988,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         UserPaymentOrderWrapper.UserPaymentOrderQuery payingQuery = UserPaymentOrderWrapper.UserPaymentOrderQuery
             .builder()
             .paymentStatus(Lists.newArrayList(OrderStatusEnum.parse(EPaymentStatus.PAYING)))
-            .endTime(DateTime.now().plusMinutes(120).toDate())
+//            .endTime(DateTime.now().plusMinutes(120).toDate())
             .build();
         // 查询支付中订单数
         userPaymentOrderService.selectPage(page, payingQuery);
@@ -1222,7 +1232,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                                     // 支付成功
                                     if (PaymentStatus.SUCCESSED == paymentResp.getPaymentStatus()) {
                                         // 根据支付回调消息,更新订单状态
-                                        SpringContextHolder.getBean(UserPaymentCoreService.class)
+                                        applicationContext.getBean(UserPaymentCoreService.class)
                                             .executePaymentSuccess(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(item)), paymentResp);
                                     }
 
@@ -1316,9 +1326,6 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         if (Objects.isNull(paymentOrder)) {
             throw new BizException("订单信息不存在");
         }
-        if (!OrderStatusEnum.PAID.getCode().equals(paymentOrder.getStatus().getCode())) {
-            throw  new BizException("订单状态异常");
-        }
         UserOrderVo detail = userOrderService.detail(paymentOrder.getId());
         if (Objects.isNull(detail)) {
             throw new BizException("订单信息不存在");
@@ -1425,4 +1432,95 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         return refundFlag;
     }
 
+    /**
+     * 关闭订单
+     *
+     * @param userInfo     JwtUserInfo
+     * @param paymentOrder UserPaymentOrder
+     * @return PaymentResp
+     */
+    @Override
+    public PaymentResp closedPayment( UserPaymentOrderWrapper.UserPaymentOrder paymentOrder) {
+
+        // 开启调试模式允许关闭订单
+        if (Optional.ofNullable(paymentServiceContext.getProperties().getDebug()).orElse(false)) {
+            // 关闭支付订单
+            PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
+                .close(paymentOrder.getTransNo(), "订单超时", paymentOrder.getOrderNo());
+            log.info("closedPayment VENDOR: {}, CHANNEL: {} paymentClose={}", paymentOrder.getPaymentVendor(),
+                paymentOrder.getPaymentChannel(), JSON.toJSONString(paymentClose));
+        }
+
+        // 查询订单信息
+        PaymentResp paymentResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
+            .query(paymentOrder.getTransNo(), paymentOrder.getOrderNo());
+        log.info("closedPayment VENDOR: {}, CHANNEL: {} paymentResp={}", paymentOrder.getPaymentVendor(),
+            paymentOrder.getPaymentChannel(), JSON.toJSONString(paymentResp));
+
+        return paymentResp;
+    }
+
+
+    @Transactional
+    @Override
+    public void paymentStatus(String orderNo) {
+
+        // 订单编号查询
+        UserPaymentOrderWrapper.UserPaymentOrder paymentOrder = userPaymentOrderService.getUserPaymentOrderByOrderNo( orderNo);
+        if (Objects.isNull(paymentOrder)) {
+            throw new BizException("订单不存在");
+        }
+
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig
+            .builder()
+            .userId(String.valueOf(paymentOrder.getUserId()))
+            .merOrderNo(orderNo)
+            .build();
+
+        // 用户下单请求锁
+        String lockName = redisCacheService.getPaymentCacheKey(orderNo);
+        DistributedLock.of(redissonClient).runIfLockCanGet(lockName, () -> {
+
+            // 已产生三方交易流水号,先判断三方订单支付状态若在支付中,则重复返回相同支付配置参数;避免用户重复支付
+            // 原生支付(微信,支付宝)流水号后产品,需要查询三方支付订单状态
+            if (StringUtils.isNotBlank(paymentOrder.getTransNo())
+                || EPaymentVendor.ORIGINAL.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())
+                || EPaymentVendor.WXPAY.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())
+                || EPaymentVendor.ALIPAY.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())) {
+
+                // 获取三方支付订单信息,根据订单状处理
+                PaymentResp paymentResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
+                    .query(paymentOrder.getTransNo(), paymentOrder.getOrderNo());
+                if (Objects.nonNull(paymentResp)) {
+                    if (PaymentStatus.PENDDING == paymentResp.getPaymentStatus()) {
+
+                        // 获取缓存配置信息
+                        String paymentConfig = redisCacheService.getUserPaymentConfig(reqConfig.getUserId(), paymentOrder.getOrderNo());
+                        if (StringUtils.isBlank(paymentConfig) && EPaymentStatus.CLOSED != paymentOrder.getStatus()) {
+                            // 支付配置已失效,待支付订单状态调整为已关闭,提醒用户重新购买
+                            PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
+                                .close(paymentOrder.getTransNo(), "支付超时", paymentOrder.getOrderNo());
+
+                            // 更新订单状态为已超时
+                            UserPaymentOrderWrapper.UserPaymentOrder update = UserPaymentOrderWrapper.UserPaymentOrder
+                                .builder()
+                                .id(paymentOrder.getId())
+                                .status(EPaymentStatus.CLOSED)
+                                .errorMsg(paymentClose.getMsg())
+                                .build();
+                            userPaymentOrderService.updateById(JSON.parseObject(update.jsonString(), UserPaymentOrderWrapper.UserPaymentOrder.class));
+
+                            // 订单关闭流程
+                            cancelPayment(UserPaymentOrderWrapper.UserPaymentOrder.from(JSON.toJSONString(paymentOrder)), paymentResp);
+                        }
+
+                    }
+
+                    // 更新用户支付订单状态
+                    updateUserPaymentOrderStatus(reqConfig.getUserId(), paymentOrder, paymentResp);
+                }
+            }
+        },10L,TimeUnit.SECONDS);
+
+    }
 }

+ 29 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentOrderServiceImpl.java

@@ -201,6 +201,7 @@ public class UserPaymentOrderServiceImpl  implements UserPaymentOrderService {
                 newestPayment.setStatus(TradeStatusEnum.succeeded);
                 break;
             case CLOSED:
+                // 关闭状态需要三方回掉
                 newestPayment.setStatus(TradeStatusEnum.close);
                 break;
             case PAYING:
@@ -246,4 +247,32 @@ public class UserPaymentOrderServiceImpl  implements UserPaymentOrderService {
         orderReq.setId(userOrder.getId());
     }
 
+    @Override
+    public UserPaymentOrderWrapper.UserPaymentOrder getUserPaymentOrderByTranNo(String transNo) {
+
+        // 查询订单信息
+        UserOrderPayment one = userOrderPaymentService.lambdaQuery()
+            .eq(UserOrderPayment::getTransNo, transNo)
+            .last("LIMIT 1")
+            .one();
+
+        if (one == null) {
+            return null;
+        }
+        UserOrder one1 = userOrderService.lambdaQuery()
+            .eq(UserOrder::getOrderNo, one.getOrderNo())
+            .last("limit 1")
+            .one();
+
+
+        if (one1.getPaymentVersion().equals(EPaymentVersion.V1)) {
+            throw new BizException("支付方式不支持");
+        }
+
+        // 查询订单支付信息
+
+        return UserPaymentOrderWrapper.UserPaymentOrder.from(one1, one);
+
+    }
+
 }

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java

@@ -340,6 +340,7 @@ public class UserPaymentOrderWrapper {
                     .activityId(getActivityId())
                     .rewardId(getRewardId())
                     .tenantId(getTenantId())
+                .reason(getErrorMsg())
                     .build();
         }
 

+ 1 - 1
pom.xml

@@ -24,7 +24,7 @@
 		<redisson.version>3.11.5</redisson.version>
 		<maven.test.skip>true</maven.test.skip>
 		<cbs.version>1.0.16</cbs.version>
-		<microsvc.version>1.0.8-RC1</microsvc.version>
+		<microsvc.version>1.1.4</microsvc.version>
 	</properties>