|
|
@@ -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) {
|