feat: 重新梳理订单支付流程

pull/1121/head
梁宇奇 2025-04-10 18:07:44 +08:00
parent 6cdd1c1592
commit 5cb0a8e0bf
14 changed files with 274 additions and 89 deletions

View File

@ -9,6 +9,7 @@ import com.ruoyi.xkt.domain.AlipayCallback;
import com.ruoyi.xkt.domain.StoreOrder;
import com.ruoyi.xkt.enums.EProcessStatus;
import com.ruoyi.xkt.manager.impl.AliPaymentMangerImpl;
import com.ruoyi.xkt.service.IAlipayCallbackService;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
@ -37,6 +38,8 @@ public class AlipayController extends XktBaseController {
@Autowired
private IStoreOrderService storeOrderService;
@Autowired
private IAlipayCallbackService alipayCallbackService;
@Autowired
private AliPaymentMangerImpl paymentManger;
/**
@ -85,7 +88,25 @@ public class AlipayController extends XktBaseController {
return FAILURE;
}
//5. 处理支付宝回调信息
paymentManger.processAlipayCallback(alipayCallback);
AlipayCallback info = alipayCallbackService.getByNotifyId(alipayCallback.getNotifyId());
if (info == null) {
//保存到数据库
info = alipayCallback;
alipayCallbackService.insertAlipayCallback(info);
}
if (!"TRADE_SUCCESS".equals(info.getTradeStatus())) {
//非交易支付成功的回调不处理
return SUCCESS;
}
if (info.getRefundFee() != null && !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) {
//如果有退款金额,可能是部分退款的回调,这里不做处理
return SUCCESS;
}
if (EProcessStatus.INIT.getValue().equals(info.getProcessStatus())) {
alipayCallbackService.processOrderPay(info);
} else {
logger.warn("支付回调重复请求处理: {}", info.getId());
}
return SUCCESS;
} else {
logger.info("支付宝验签未通过:{}", params);

View File

@ -11,9 +11,10 @@ import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddReqVO;
import com.ruoyi.web.controller.xkt.vo.order.StoreOrderPayReqVO;
import com.ruoyi.web.controller.xkt.vo.order.StoreOrderPayRespVO;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResult;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.enums.EPayPage;
import com.ruoyi.xkt.manager.PaymentManager;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
@ -26,6 +27,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
/**
@ -44,28 +46,30 @@ public class StoreOrderController extends XktBaseController {
@PreAuthorize("@ss.hasPermi('system:order:add')")
@Log(title = "订单", businessType = BusinessType.INSERT)
@ApiOperation("创建订单并发起支付")
@ApiOperation("创建订单")
@PostMapping("create")
public R<StoreOrderPayRespVO> create(@RequestBody StoreOrderAddReqVO vo) {
public R<StoreOrderPayRespVO> create(@Valid @RequestBody StoreOrderAddReqVO vo) {
StoreOrderAddDTO dto = BeanUtil.toBean(vo, StoreOrderAddDTO.class);
dto.setOrderUserId(SecurityUtils.getUserId());
//初始化订单
StoreOrderInfo orderInfo = storeOrderService.createOrder(dto);
//发起支付
PaymentManager paymentManager = getPaymentManager(EPayChannel.of(vo.getPayChannel()));
String rtnStr = paymentManager.payForOrder(orderInfo.getOrder().getId(), EPayFrom.of(vo.getPayFrom()));
//创建订单并根据参数决定是否发起支付
StoreOrderAddResult result = storeOrderService.createOrder(dto, vo.getBeginPay(),
EPayChannel.of(vo.getPayChannel()), EPayPage.of(vo.getPayFrom()));
//返回信息
StoreOrderPayRespVO respVO = new StoreOrderPayRespVO(orderInfo.getOrder().getId(), rtnStr);
StoreOrderPayRespVO respVO = new StoreOrderPayRespVO(result.getOrderInfo().getOrder().getId(),
result.getPayRtnStr());
return success(respVO);
}
@PreAuthorize("@ss.hasPermi('system:order:add')")
@Log(title = "订单", businessType = BusinessType.OTHER)
@ApiOperation("重新发起订单支付")
@ApiOperation("支付订单")
@PostMapping("pay")
public R<StoreOrderPayRespVO> pay(@RequestBody StoreOrderPayReqVO vo) {
public R<StoreOrderPayRespVO> pay(@Valid @RequestBody StoreOrderPayReqVO vo) {
PaymentManager paymentManager = getPaymentManager(EPayChannel.of(vo.getPayChannel()));
String rtnStr = paymentManager.payForOrder(vo.getStoreOrderId(), EPayFrom.of(vo.getPayFrom()));
//订单支付状态->支付中
StoreOrderInfo storeOrderInfo = storeOrderService.preparePayOrder(vo.getStoreOrderId());
//调用支付
String rtnStr = paymentManager.payOrder(storeOrderInfo, EPayPage.of(vo.getPayFrom()));
StoreOrderPayRespVO respVO = new StoreOrderPayRespVO(vo.getStoreOrderId(), rtnStr);
return success(respVO);
}

View File

@ -4,6 +4,9 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
@ -17,6 +20,7 @@ public class StoreOrderAddReqVO {
/**
* ID
*/
@NotNull(message = "档口ID不能为空")
@ApiModelProperty(value = "档口ID")
private Long storeId;
/**
@ -27,41 +31,49 @@ public class StoreOrderAddReqVO {
/**
* ID
*/
@NotNull(message = "物流ID不能为空")
@ApiModelProperty(value = "物流ID")
private Long expressId;
/**
* -
*/
@NotEmpty(message = "收货人名称不能为空")
@ApiModelProperty(value = "收货人-名称")
private String destinationContactName;
/**
* -
*/
@NotEmpty(message = "收货人电话不能为空")
@ApiModelProperty(value = "收货人-电话")
private String destinationContactPhoneNumber;
/**
* -
*/
@NotEmpty(message = "收货人省编码不能为空")
@ApiModelProperty(value = "收货人-省编码")
private String destinationProvinceCode;
/**
* -
*/
@NotEmpty(message = "收货人市编码不能为空")
@ApiModelProperty(value = "收货人-市编码")
private String destinationCityCode;
/**
* -
*/
@NotEmpty(message = "收货人区县编码不能为空")
@ApiModelProperty(value = "收货人-区县编码")
private String destinationCountyCode;
/**
* -
*/
@NotEmpty(message = "收货人详细地址不能为空")
@ApiModelProperty(value = "收货人-详细地址")
private String destinationDetailAddress;
/**
* [1: 2:]
*/
@NotNull(message = "发货方式不能为空")
@ApiModelProperty(value = "发货方式[1:货其再发 2:有货先发]")
private Integer deliveryType;
/**
@ -72,12 +84,20 @@ public class StoreOrderAddReqVO {
/**
*
*/
@Valid
@NotEmpty(message = "订单明细不能为空")
@ApiModelProperty(value = "明细列表")
private List<Detail> detailList;
@NotNull(message = "是否发起支付不能为空")
@ApiModelProperty(value = "是否发起支付")
private Boolean beginPay;
@NotNull(message = "支付渠道不能为空")
@ApiModelProperty(value = "支付渠道[1:支付宝]")
private Integer payChannel;
@NotNull(message = "支付来源不能为空")
@ApiModelProperty(value = "支付来源[1:电脑网站 2:手机网站]")
private Integer payFrom;
@ -85,9 +105,11 @@ public class StoreOrderAddReqVO {
@Data
public static class Detail {
@NotNull(message = "商品颜色尺码ID不能为空")
@ApiModelProperty(value = "商品颜色尺码ID")
private Long storeProdColorSizeId;
@NotNull(message = "商品数量不能为空")
@ApiModelProperty(value = "商品数量")
private Integer goodsQuantity;
}

View File

@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author liangyq
* @date 2025-04-07 18:16
@ -12,12 +14,15 @@ import lombok.Data;
@Data
public class StoreOrderPayReqVO {
@NotNull(message = "订单ID不能为空")
@ApiModelProperty(value = "订单ID")
private Long storeOrderId;
@NotNull(message = "支付渠道不能为空")
@ApiModelProperty(value = "支付渠道[1:支付宝]")
private Integer payChannel;
@NotNull(message = "支付来源不能为空")
@ApiModelProperty(value = "支付来源[1:电脑网站 2:手机网站]")
private Integer payFrom;
}

View File

@ -1,23 +1,27 @@
package com.ruoyi.common.utils;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.PatternMatchUtils;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.PatternMatchUtils;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
*
*
* @author ruoyi
*/
@Slf4j
public class SecurityUtils
{
@ -66,6 +70,25 @@ public class SecurityUtils
}
}
/**
*
*
* @return
*/
public static String getUsernameSafe() {
String username = null;
try {
Authentication auth = getAuthentication();
if (auth != null) {
LoginUser user = (LoginUser) auth.getPrincipal();
username = Optional.ofNullable(user).map(LoginUser::getUsername).orElse(null);
}
} catch (Exception e) {
log.error("获取用户账户异常", e);
}
return username;
}
/**
*
**/

View File

@ -0,0 +1,23 @@
package com.ruoyi.xkt.dto.order;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liangyq
* @date 2025-04-03 13:46
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StoreOrderAddResult {
/**
*
*/
private StoreOrderInfo orderInfo;
/**
*
*/
private String payRtnStr;
}

View File

@ -12,6 +12,7 @@ import lombok.Getter;
public enum EOrderAction {
ADD_ORDER(1, "下单"),
PAID_ORDER(2, "支付"),
;
private final Integer value;

View File

@ -9,7 +9,7 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
public enum EPayFrom {
public enum EPayPage {
WEB(1, "电脑网站"),
WAP(2, "手机网站"),
@ -18,8 +18,8 @@ public enum EPayFrom {
private final Integer value;
private final String label;
public static EPayFrom of(Integer value) {
for (EPayFrom e : EPayFrom.values()) {
public static EPayPage of(Integer value) {
for (EPayPage e : EPayPage.values()) {
if (e.getValue().equals(value)) {
return e;
}

View File

@ -1,7 +1,8 @@
package com.ruoyi.xkt.manager;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.enums.EPayPage;
/**
* @author liangyq
@ -18,10 +19,10 @@ public interface PaymentManager {
/**
*
*
* @param storeOrderId
* @param order
* @param payFrom
* @return ///&
*/
String payForOrder(Long storeOrderId, EPayFrom payFrom);
String payOrder(StoreOrderInfo order, EPayPage payFrom);
}

View File

@ -1,6 +1,5 @@
package com.ruoyi.xkt.manager.impl;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
@ -8,23 +7,18 @@ import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xkt.domain.AlipayCallback;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.dto.finance.AlipayReqDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.enums.EPayPage;
import com.ruoyi.xkt.enums.EPayStatus;
import com.ruoyi.xkt.manager.PaymentManager;
import com.ruoyi.xkt.service.IAlipayCallbackService;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
/**
* @author liangyq
* @date 2025-04-06 19:36
@ -33,6 +27,9 @@ import java.math.BigDecimal;
@Getter
@Component
public class AliPaymentMangerImpl implements PaymentManager {
private static final String DEFAULT_FORMAT = "json";
private static final String PAY_PRODUCT_CODE = "FAST_INSTANT_TRADE_PAY";
/**
* ID,APPIDAPPID
*/
@ -74,29 +71,25 @@ public class AliPaymentMangerImpl implements PaymentManager {
@Value("${alipay.gatewayUrl:https://openapi-sandbox.dl.alipaydev.com/gateway.do}")
private String gatewayUrl;
@Autowired
private IStoreOrderService storeOrderService;
@Autowired
private IAlipayCallbackService alipayCallbackService;
@Override
public EPayChannel channel() {
return EPayChannel.ALI_PAY;
}
@Override
public String payForOrder(Long storeOrderId, EPayFrom payFrom) {
Assert.notNull(storeOrderId);
public String payOrder(StoreOrderInfo orderInfo, EPayPage payFrom) {
Assert.notNull(orderInfo);
Assert.notNull(payFrom);
//订单状态更新为支付中
StoreOrderInfo order = storeOrderService.preparePayOrder(storeOrderId);
if (!EPayStatus.PAYING.getValue().equals(orderInfo.getOrder().getPayStatus())) {
throw new ServiceException("订单[" + orderInfo.getOrder().getOrderNo() + "]支付状态异常");
}
AlipayReqDTO reqDTO = new AlipayReqDTO();
reqDTO.setOutTradeNo(order.getOrder().getOrderNo());
reqDTO.setTotalAmount(order.getOrder().getTotalAmount().toPlainString());
reqDTO.setSubject("代发订单" + order.getOrder().getOrderNo());
reqDTO.setProductCode("FAST_INSTANT_TRADE_PAY"); //这个是固定的
reqDTO.setOutTradeNo(orderInfo.getOrder().getOrderNo());
reqDTO.setTotalAmount(orderInfo.getOrder().getTotalAmount().toPlainString());
reqDTO.setSubject("代发订单" + orderInfo.getOrder().getOrderNo());
reqDTO.setProductCode(PAY_PRODUCT_CODE); //这个是固定的
String reqStr = JSON.toJSONString(reqDTO);
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", charset,
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, DEFAULT_FORMAT, charset,
alipayPublicKey, signType);
switch (payFrom) {
case WEB:
@ -126,19 +119,4 @@ public class AliPaymentMangerImpl implements PaymentManager {
}
}
public void processAlipayCallback(AlipayCallback alipayCallback) {
AlipayCallback info = alipayCallbackService.getByNotifyId(alipayCallback.getNotifyId());
if (info == null) {
//保存到数据库
info = alipayCallback;
alipayCallbackService.insertAlipayCallback(info);
}
if (info.getRefundFee() != null &&
!NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) {
//如果有退款金额,可能是部分退款的回调,这里不做处理
return;
}
//TODO
}
}

View File

@ -24,4 +24,10 @@ public interface IAlipayCallbackService {
*/
int insertAlipayCallback(AlipayCallback alipayCallback);
/**
*
*
* @param info
*/
void processOrderPay(AlipayCallback info);
}

View File

@ -2,7 +2,10 @@ package com.ruoyi.xkt.service;
import com.ruoyi.xkt.domain.StoreOrder;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResult;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayPage;
/**
* @author liangyq
@ -12,10 +15,14 @@ public interface IStoreOrderService {
/**
*
*
* @param storeOrderAddDTO
* @param storeOrderAddDTO
* @param beginPay
* @param payChannel
* @param payPage
* @return
*/
StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO);
StoreOrderAddResult createOrder(StoreOrderAddDTO storeOrderAddDTO, boolean beginPay, EPayChannel payChannel,
EPayPage payPage);
/**
*
@ -31,4 +38,13 @@ public interface IStoreOrderService {
* @param storeOrderId
*/
StoreOrderInfo preparePayOrder(Long storeOrderId);
/**
*
* TODO
*
* @param storeOrderId
* @return
*/
StoreOrderInfo paySuccess(Long storeOrderId);
}

View File

@ -2,8 +2,14 @@ package com.ruoyi.xkt.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.xkt.domain.AlipayCallback;
import com.ruoyi.xkt.domain.StoreOrder;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EProcessStatus;
import com.ruoyi.xkt.mapper.AlipayCallbackMapper;
import com.ruoyi.xkt.service.IAlipayCallbackService;
import com.ruoyi.xkt.service.IFinanceBillService;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -18,6 +24,10 @@ public class AlipayCallbackServiceImpl implements IAlipayCallbackService {
@Autowired
private AlipayCallbackMapper alipayCallbackMapper;
@Autowired
private IStoreOrderService storeOrderService;
@Autowired
private IFinanceBillService financeBillService;
@Override
@ -33,4 +43,18 @@ public class AlipayCallbackServiceImpl implements IAlipayCallbackService {
Assert.notNull(alipayCallback);
return alipayCallbackMapper.insert(alipayCallback);
}
@Transactional
@Override
public void processOrderPay(AlipayCallback info) {
//更新回调状态
info.setProcessStatus(EProcessStatus.SUCCESS.getValue());
alipayCallbackMapper.updateById(info);
//更新订单状态
StoreOrder order = storeOrderService.getByOrderNo(info.getOutTradeNo());
Assert.notNull(order);
StoreOrderInfo orderInfo = storeOrderService.paySuccess(order.getId());
//创建收款单
financeBillService.createCollectionBillAfterOrderPaid(orderInfo, info.getId(), EPayChannel.ALI_PAY);
}
}

View File

@ -13,9 +13,11 @@ import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.xkt.domain.*;
import com.ruoyi.xkt.dto.express.ExpressContactDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderAddResult;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.dto.order.StoreOrderOperationRecordAddDTO;
import com.ruoyi.xkt.enums.*;
import com.ruoyi.xkt.manager.PaymentManager;
import com.ruoyi.xkt.mapper.*;
import com.ruoyi.xkt.service.IExpressService;
import com.ruoyi.xkt.service.IOperationRecordService;
@ -40,21 +42,24 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
@Autowired
private StoreOrderDetailMapper storeOrderDetailMapper;
@Autowired
private IExpressService expressService;
@Autowired
private IOperationRecordService operationRecordService;
@Autowired
private StoreProductMapper storeProductMapper;
@Autowired
private StoreProductColorSizeMapper storeProductColorSizeMapper;
@Autowired
private StoreProductColorPriceMapper storeProductColorPriceMapper;
@Autowired
private IExpressService expressService;
@Autowired
private IOperationRecordService operationRecordService;
@Autowired
private IVoucherSequenceService voucherSequenceService;
@Autowired
private List<PaymentManager> paymentManagers;
@Transactional
@Override
public StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO) {
public StoreOrderAddResult createOrder(StoreOrderAddDTO storeOrderAddDTO, boolean beginPay, EPayChannel payChannel,
EPayPage payPage) {
Long orderUserId = storeOrderAddDTO.getOrderUserId();
Long storeId = storeOrderAddDTO.getStoreId();
Long expressId = storeOrderAddDTO.getExpressId();
@ -81,7 +86,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
orderDetail.setStoreProdColorSizeId(spcs.getId());
orderDetail.setStoreProdId(spcs.getStoreProdId());
orderDetail.setDetailStatus(EOrderStatus.PENDING_PAYMENT.getValue());
orderDetail.setPayStatus(EPayStatus.INIT.getValue());
orderDetail.setPayStatus(beginPay ? EPayStatus.PAYING.getValue() : EPayStatus.INIT.getValue());
orderDetail.setExpressStatus(EExpressStatus.INIT.getValue());
//计算明细费用
BigDecimal goodsPrice = calcPrice(orderUserId, spcs);
@ -122,7 +127,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
order.setOrderNo(orderNo);
order.setOrderType(EOrderType.SALES_ORDER.getValue());
order.setOrderStatus(EOrderStatus.PENDING_PAYMENT.getValue());
order.setPayStatus(EPayStatus.INIT.getValue());
order.setPayStatus(beginPay ? EPayStatus.PAYING.getValue() : EPayStatus.INIT.getValue());
order.setOrderRemark(storeOrderAddDTO.getOrderRemark());
order.setGoodsQuantity(orderGoodsQuantity);
order.setGoodsAmount(orderGoodsAmount);
@ -160,7 +165,14 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
});
//操作记录
addOperationRecords(orderId, orderDetailIdList, orderUserId, new Date(), EOrderAction.ADD_ORDER);
return new StoreOrderInfo(order, orderDetailList);
StoreOrderInfo orderInfo = new StoreOrderInfo(order, orderDetailList);
String rtnStr = null;
if (beginPay) {
//发起支付
PaymentManager paymentManager = getPaymentManager(payChannel);
rtnStr = paymentManager.payOrder(orderInfo, payPage);
}
return new StoreOrderAddResult(orderInfo, rtnStr);
}
@Override
@ -178,33 +190,64 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
Assert.isTrue(EOrderType.SALES_ORDER.getValue().equals(order.getOrderType()),
"非销售订单无法发起支付");
Assert.isTrue(BeanValidators.exists(order), "订单不存在");
checkPreparePayStatus(order.getPayStatus());
order.setPayStatus(EPayStatus.PAYING.getValue());
int orderSuccess = storeOrderMapper.updateById(order);
if (orderSuccess == 0) {
throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG);
}
List<StoreOrderDetail> orderDetails = storeOrderDetailMapper.selectList(
Wrappers.lambdaQuery(StoreOrderDetail.class)
.eq(StoreOrderDetail::getStoreOrderId, storeOrderId)
.eq(SimpleEntity::getDelFlag, Constants.UNDELETED));
checkPreparePayStatus(order.getPayStatus());
StoreOrder updateOrder = new StoreOrder();
updateOrder.setId(storeOrderId);
updateOrder.setPayStatus(EPayStatus.PAYING.getValue());
updateOrder.setVersion(order.getVersion());
int orderSuccess = storeOrderMapper.updateById(updateOrder);
if (orderSuccess == 0) {
throw new ServiceException("系统繁忙请稍后再试");
}
for (StoreOrderDetail orderDetail : orderDetails) {
checkPreparePayStatus(orderDetail.getPayStatus());
StoreOrderDetail orderDetailUpdate = new StoreOrderDetail();
orderDetailUpdate.setId(orderDetail.getId());
orderDetailUpdate.setPayStatus(EPayStatus.PAYING.getValue());
orderDetailUpdate.setVersion(orderDetail.getVersion());
int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetailUpdate);
orderDetail.setPayStatus(EPayStatus.PAYING.getValue());
int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetail);
if (orderDetailSuccess == 0) {
throw new ServiceException("系统繁忙请稍后再试");
throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG);
}
}
return new StoreOrderInfo(order, orderDetails);
}
@Transactional
@Override
public StoreOrderInfo paySuccess(Long storeOrderId) {
Assert.notNull(storeOrderId);
StoreOrder order = storeOrderMapper.selectById(storeOrderId);
Assert.isTrue(EOrderType.SALES_ORDER.getValue().equals(order.getOrderType()),
"订单类型异常");
Assert.isTrue(BeanValidators.exists(order), "订单不存在");
Assert.isTrue(order.getPayStatus().equals(EPayStatus.PAYING.getValue()), "订单支付状态异常");
order.setPayStatus(EPayStatus.PAID.getValue());
//TODO 暂时使用总金额
order.setRealTotalAmount(order.getTotalAmount());
int orderSuccess = storeOrderMapper.updateById(order);
if (orderSuccess == 0) {
throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG);
}
List<StoreOrderDetail> orderDetails = storeOrderDetailMapper.selectList(
Wrappers.lambdaQuery(StoreOrderDetail.class)
.eq(StoreOrderDetail::getStoreOrderId, storeOrderId)
.eq(SimpleEntity::getDelFlag, Constants.UNDELETED));
List<Long> orderDetailIdList = new ArrayList<>(orderDetails.size());
for (StoreOrderDetail orderDetail : orderDetails) {
Assert.isTrue(orderDetail.getPayStatus().equals(EPayStatus.PAYING.getValue()),
"订单明细支付状态异常");
orderDetail.setPayStatus(EPayStatus.PAID.getValue());
orderDetail.setRealTotalAmount(orderDetail.getTotalAmount());
int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetail);
if (orderDetailSuccess == 0) {
throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG);
}
orderDetailIdList.add(orderDetail.getId());
}
//操作记录
addOperationRecords(storeOrderId, orderDetailIdList, null, new Date(), EOrderAction.PAID_ORDER);
return new StoreOrderInfo(order, orderDetails);
}
private void checkPreparePayStatus(Integer payStatus) {
if (!EPayStatus.INIT.getValue().equals(payStatus) && !EPayStatus.PAYING.getValue().equals(payStatus)) {
throw new ServiceException("订单状态异常无法发起支付");
@ -328,4 +371,22 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
}
return spcsMap;
}
/**
*
*
* @param payChannel
* @return
*/
private PaymentManager getPaymentManager(EPayChannel payChannel) {
if (payChannel == null) {
throw new ServiceException("请先选择支付渠道");
}
for (PaymentManager paymentManager : paymentManagers) {
if (paymentManager.channel() == payChannel) {
return paymentManager;
}
}
throw new ServiceException("未知支付渠道");
}
}