diff --git a/jzo2o-api/src/main/java/com/jzo2o/api/trade/dto/request/NativePayReqDTO.java b/jzo2o-api/src/main/java/com/jzo2o/api/trade/dto/request/NativePayReqDTO.java index 5d9106f..1cf5b59 100644 --- a/jzo2o-api/src/main/java/com/jzo2o/api/trade/dto/request/NativePayReqDTO.java +++ b/jzo2o-api/src/main/java/com/jzo2o/api/trade/dto/request/NativePayReqDTO.java @@ -2,13 +2,18 @@ package com.jzo2o.api.trade.dto.request; import com.jzo2o.api.trade.enums.PayChannelEnum; import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; import lombok.Data; import java.math.BigDecimal; +/** + * 支付服务请求参数 + * @author JIAN + */ @Data +@Builder public class NativePayReqDTO { - @ApiModelProperty(value = "商户号", required = true) private Long enterpriseId; @ApiModelProperty(value = "业务系统标识", required = true) @@ -27,5 +32,4 @@ public class NativePayReqDTO { @ApiModelProperty(value = "是否切换支付渠道", required = true) private boolean changeChannel=false; - -} +} \ No newline at end of file diff --git a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/controller/consumer/ConsumerOrdersController.java b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/controller/consumer/ConsumerOrdersController.java index b0e633f..dbb7de3 100644 --- a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/controller/consumer/ConsumerOrdersController.java +++ b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/controller/consumer/ConsumerOrdersController.java @@ -4,7 +4,9 @@ import com.jzo2o.api.orders.dto.response.OrderResDTO; import com.jzo2o.api.orders.dto.response.OrderSimpleResDTO; import com.jzo2o.common.utils.ObjectUtils; import com.jzo2o.mvc.utils.UserContext; +import com.jzo2o.orders.manager.model.dto.request.OrdersPayReqDTO; import com.jzo2o.orders.manager.model.dto.request.PlaceOrderReqDTO; +import com.jzo2o.orders.manager.model.dto.response.OrdersPayResDTO; import com.jzo2o.orders.manager.model.dto.response.PlaceOrderResDTO; import com.jzo2o.orders.manager.service.IOrdersCreateService; import com.jzo2o.orders.manager.service.IOrdersManagerService; @@ -60,4 +62,14 @@ public class ConsumerOrdersController { return ordersCreateService.placeOrder(placeOrderReqDTO); } + + @PutMapping("/pay/{id}") + @ApiOperation("订单支付") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "订单id", required = true, dataTypeClass = Long.class) + }) + public OrdersPayResDTO pay(@PathVariable("id") Long id, + @RequestBody OrdersPayReqDTO ordersPayReqDTO) { + return ordersCreateService.payOrder(id, ordersPayReqDTO); + } } \ No newline at end of file diff --git a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/IOrdersCreateService.java b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/IOrdersCreateService.java index 58079bd..d6e0b82 100644 --- a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/IOrdersCreateService.java +++ b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/IOrdersCreateService.java @@ -2,14 +2,15 @@ package com.jzo2o.orders.manager.service; import com.baomidou.mybatisplus.extension.service.IService; import com.jzo2o.orders.base.model.domain.Orders; +import com.jzo2o.orders.manager.model.dto.request.OrdersPayReqDTO; import com.jzo2o.orders.manager.model.dto.request.PlaceOrderReqDTO; +import com.jzo2o.orders.manager.model.dto.response.OrdersPayResDTO; import com.jzo2o.orders.manager.model.dto.response.PlaceOrderResDTO; /** *

* 下单服务类 *

- * * @author itcast * @since 2023-07-10 */ @@ -18,4 +19,10 @@ public interface IOrdersCreateService extends IService { * 客户端下单接口 */ PlaceOrderResDTO placeOrder(PlaceOrderReqDTO placeOrderReqDTO); + + /** + * 客户端支付接口 + * @param id 订单id + */ + OrdersPayResDTO payOrder(Long id, OrdersPayReqDTO ordersPayReqDTO); } \ No newline at end of file diff --git a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/impl/OrdersCreateServiceImpl.java b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/impl/OrdersCreateServiceImpl.java index d8f97e9..8bc800c 100644 --- a/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/impl/OrdersCreateServiceImpl.java +++ b/jzo2o-oreders/jzo2o-orders-manager/src/main/java/com/jzo2o/orders/manager/service/impl/OrdersCreateServiceImpl.java @@ -3,8 +3,13 @@ package com.jzo2o.orders.manager.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.jzo2o.api.customer.dto.response.AddressBookResDTO; import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO; +import com.jzo2o.api.trade.NativePayApi; +import com.jzo2o.api.trade.dto.request.NativePayReqDTO; +import com.jzo2o.api.trade.dto.response.NativePayResDTO; +import com.jzo2o.api.trade.enums.PayChannelEnum; import com.jzo2o.common.expcetions.CommonException; import com.jzo2o.common.expcetions.ForbiddenOperationException; +import com.jzo2o.common.utils.BeanUtils; import com.jzo2o.common.utils.DateUtils; import com.jzo2o.common.utils.ObjectUtils; import com.jzo2o.mvc.utils.UserContext; @@ -13,8 +18,11 @@ import com.jzo2o.orders.base.enums.OrderPayStatusEnum; import com.jzo2o.orders.base.enums.OrderStatusEnum; import com.jzo2o.orders.base.mapper.OrdersMapper; import com.jzo2o.orders.base.model.domain.Orders; +import com.jzo2o.orders.manager.model.dto.request.OrdersPayReqDTO; import com.jzo2o.orders.manager.model.dto.request.PlaceOrderReqDTO; +import com.jzo2o.orders.manager.model.dto.response.OrdersPayResDTO; import com.jzo2o.orders.manager.model.dto.response.PlaceOrderResDTO; +import com.jzo2o.orders.manager.porperties.TradeProperties; import com.jzo2o.orders.manager.service.IOrdersCreateService; import com.jzo2o.orders.manager.service.client.CustomerClient; import lombok.extern.slf4j.Slf4j; @@ -42,6 +50,12 @@ public class OrdersCreateServiceImpl extends ServiceImpl i private RedisTemplate redisTemplate; @Resource private TransactionTemplate transactionTemplate; + @Resource + private NativePayApi nativePayApi; + @Resource + private TradeProperties tradeProperties; + + private final String PRODUCT_APP_ID = "jzo2o.orders"; /** * 生成订单号(2位年+2位月+2位日+13位序号) @@ -110,4 +124,55 @@ public class OrdersCreateServiceImpl extends ServiceImpl i return orderToPay.getId(); })); } + + @Override + public OrdersPayResDTO payOrder(Long id, OrdersPayReqDTO ordersPayReqDTO) { + Orders orders = baseMapper.selectById(id); + if (ObjectUtils.isEmpty(orders)) { + throw new ForbiddenOperationException("订单不存在无法支付"); + } + + // 初步防止重复发起支付请求 + if (orders.getPayStatus() == OrderPayStatusEnum.PAY_SUCCESS.getStatus()) { + OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(orders, OrdersPayResDTO.class); + ordersPayResDTO.setProductOrderNo(id); + return ordersPayResDTO; + } + + // 构造公共参数 + PayChannelEnum tradingChannel = ordersPayReqDTO.getTradingChannel(); + NativePayReqDTO nativePayReqDTO = NativePayReqDTO.builder() + .productAppId(PRODUCT_APP_ID) + .productOrderNo(id) + .tradingChannel(tradingChannel) + .tradingAmount(/*orders.getRealPayAmount() 测试统一使用0.1元*/ new BigDecimal("0.1")) + .memo(orders.getServeItemName() + orders.getPurNum() + "个") + .changeChannel(tradingChannel.name().equals(orders.getTradingChannel())) + .build(); + + // 获取支付渠道对应的商户号 + if (tradingChannel == PayChannelEnum.WECHAT_PAY) { + nativePayReqDTO.setEnterpriseId(tradeProperties.getWechatEnterpriseId()); + } else if (tradingChannel == PayChannelEnum.ALI_PAY) { + nativePayReqDTO.setEnterpriseId(tradeProperties.getAliEnterpriseId()); + } else { + throw new ForbiddenOperationException("未知支付渠道无法支付"); + } + + // 支付服务获取支付二维码 + NativePayResDTO nativePayResDTO = nativePayApi.createDownLineTrading(nativePayReqDTO); + + // 更新订单表信息 + if (!lambdaUpdate().eq(Orders::getId, id) + .set(Orders::getTradingOrderNo, nativePayResDTO.getTradingOrderNo()) + .set(Orders::getTradingChannel, nativePayResDTO.getTradingChannel()) + .update()) { + log.warn("订单表更新失败(已正常生成支付二维码), 订单id: {}", id); + } + + // 组装响应信息返回 + OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(nativePayResDTO, OrdersPayResDTO.class); + ordersPayResDTO.setPayStatus(OrderPayStatusEnum.NO_PAY.getStatus()); + return ordersPayResDTO; + } } \ No newline at end of file