src/main/java/cc/mrbird/febs/mall/controller/AdminMallOrderController.java
@@ -135,6 +135,18 @@ } /** * 订单列表-确认收款 * * @param id * @return */ @GetMapping("insurePay/{id}") @ControllerEndpoint(operation = "订单列表-确认收款", exceptionMessage = "操作失败") public FebsResponse insurePay(@NotNull(message = "{required}") @PathVariable Long id) { return adminMallOrderService.insurePay(id); } /** * 订单列表-取消发货 * * @param id src/main/java/cc/mrbird/febs/mall/controller/dependentStation/ApiMallOrderController.java
@@ -176,6 +176,49 @@ return new FebsResponse().success().data(iXcxPayService.getTemplateId()); } // ==================== XT 支付 ==================== /** * 创建订单并通过 XT 支付 * <p> * 流程:创建订单 → 通过 XT 支付链接 * <p> */ @ApiOperation(value = "创建订单-XT支付", notes = "创建订单并返回XT支付") @PostMapping(value = "/createOrderByXtPay") @Limit(key = "createOrderByXtPay", period = 1, count = 1, name = "XT下单", prefix = "limit", limitType = LimitType.IP) public FebsResponse createOrderByXtPay(@RequestBody @Validated XtPayCreateOrderDto lwPayDto) { // 1. 创建订单 AddOrderDto addOrderDto = lwPayDto.getOrder(); Long orderId = mallOrderInfoService.createOrder(addOrderDto); // 2. 获取订单详情 MallOrderInfo order = mallOrderInfoService.getById(orderId); if (order != null && OrderStatusEnum.WAIT_PAY.getValue() == order.getStatus() ){ return mallOrderInfoService.createOrderByXtPay(); } return new FebsResponse().fail().message("Payment channel exception"); } @ApiOperation(value = "XT支付", notes = "XT支付") @PostMapping(value = "/payOrderByXtPay", produces = "application/json") public FebsResponse payOrderByXtPay(@RequestBody @Validated ApiOrderPayDto payDto) { Long orderId = payDto.getOrderId(); Integer payType = payDto.getPayType(); // 2. 获取订单详情 MallOrderInfo order = mallOrderInfoService.getById(orderId); if (order != null && OrderConstants.PAY_TYPE_XT == payType && OrderStatusEnum.WAIT_PAY.getValue() == order.getStatus() ){ return mallOrderInfoService.createOrderByXtPay(); } return new FebsResponse().fail().message("Payment channel exception"); } // ==================== LWPAY 支付 ==================== /** @@ -260,7 +303,7 @@ result.put("orderNo", order.getOrderNo()); result.put("amount", order.getAmount()); result.put("payUrl", payUrl); return new FebsResponse().success().data(result).message("下单成功"); return new FebsResponse().success().data(result).message("success"); } catch (Exception e) { log.error("LWPAY 代收下单失败: orderId={}", orderId, e); return new FebsResponse().fail().message("Payment channel exception: " + e.getMessage()); src/main/java/cc/mrbird/febs/mall/controller/dependentStation/constant/OrderConstants.java
@@ -29,12 +29,13 @@ public static final String ORDER_STATE = "order_state"; /** * 支付方式 1-微信 2-支付宝 3-USDT * 支付方式 1-微信 2-支付宝 3-USDT 4-LWPAY支付 5-XT支付 */ public static final Integer PAY_TYPE_WECHAT = 1; public static final Integer PAY_TYPE_ALIPAY = 2; public static final Integer PAY_TYPE_USDT = 3; public static final Integer PAY_TYPE_SYSTEM = 4; public static final Integer PAY_TYPE_XT = 5; public static final String ORDER_PAY_TYPE = "order_pay_type"; public static final String TRC20_SYSTEM_ADDRESS = "pay.trc20.address"; src/main/java/cc/mrbird/febs/mall/dto/ApiOrderPayDto.java
@@ -17,6 +17,6 @@ private Long orderId; @NotNull(message = "支付方式不能为空") @ApiModelProperty(value = "支付方式 1-微信 2-支付宝 3-USDT 4-LwPAY", example = "you_ke_*****") @ApiModelProperty(value = "支付方式 1-微信 2-支付宝 3-USDT 4-LwPAY 5-XTPAY", example = "you_ke_*****") private Integer payType; } src/main/java/cc/mrbird/febs/mall/dto/XtPayCreateOrderDto.java
New file @@ -0,0 +1,18 @@ package cc.mrbird.febs.mall.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.Valid; import javax.validation.constraints.NotNull; @Data @ApiModel(value = "XtPayCreateOrderDto", description = "支付下单参数") public class XtPayCreateOrderDto { @Valid @NotNull(message = "订单信息不能为空") @ApiModelProperty(value = "订单信息", required = true) private AddOrderDto order; } src/main/java/cc/mrbird/febs/mall/service/IAdminMallOrderService.java
@@ -80,4 +80,6 @@ FebsResponse deliverPdfGoods(Long id); FebsResponse cancelDeliver(Long id); FebsResponse insurePay(Long id); } src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
@@ -48,4 +48,6 @@ FebsResponse createOrderVerify(ApiCreateOrderVerifyDto apiCreateOrderVerifyDto); FebsResponse chooseCoupon(ApiChooseCouponDto chooseCouponDto); FebsResponse createOrderByXtPay(); } src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java
@@ -5,6 +5,7 @@ import cc.mrbird.febs.common.enumerates.*; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.ValidateEntityUtils; import cc.mrbird.febs.mall.controller.dependentStation.constant.OrderConstants; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; @@ -16,6 +17,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.best.javaSdk.ClientParamEnum; @@ -31,6 +33,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @Slf4j @@ -617,6 +620,33 @@ } @Override public FebsResponse insurePay(Long id) { // 1. 查询订单 MallOrderInfo order = mallOrderInfoMapper.selectById(id); if (order == null) { return new FebsResponse().fail().message("订单不存在,刷新后重试"); } // 2. 幂等检查(避免重复回调) if (OrderStatusEnum.WAIT_PAY.getValue() != order.getStatus()) { return new FebsResponse().fail().message("订单不是代付款状态"); } // 3. 更新订单状态为待发货 mallOrderInfoMapper.update( null, Wrappers.lambdaUpdate(MallOrderInfo.class) .set(MallOrderInfo::getStatus, OrderStatusEnum.WAIT_SHIPPING.getValue()) .set(MallOrderInfo::getPayTime, new Date()) .set(MallOrderInfo::getPayMethod, "XT支付") .set(MallOrderInfo::getPayResult, "1") .eq(MallOrderInfo::getId, order.getId()) ); return new FebsResponse().success(); } @Override public void deliverGoodsByOrderNo(DeliverGoodsDto deliverGoodsDto) { MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectByOrderNo(deliverGoodsDto.getOrderNo()); if (mallOrderInfo == null) { src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -1002,4 +1002,19 @@ return new FebsResponse().success().data(objects); } @Override public FebsResponse createOrderByXtPay() { DataDictionaryCustom dataDictionaryCustom = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( "PAY_LINK", "XT_LINK" ); if (ObjectUtil.isEmpty(dataDictionaryCustom)){ return new FebsResponse().fail().message("Payment channel exception"); } if (StrUtil.isEmpty(dataDictionaryCustom.getValue())){ return new FebsResponse().fail().message("Payment channel exception"); } return new FebsResponse().success().data(dataDictionaryCustom.getValue()); } } src/main/resources/templates/febs/views/modules/order/orderList.html
@@ -357,6 +357,11 @@ cancelOrder(data.id); }); } if (layEvent === 'insurePay') { febs.modal.confirm('收款', '确认收款?', function () { insurePay(data.id); }); } if (layEvent === 'deliverPdfGoods') { febs.modal.confirm('一键发货', '确认一键发货?', function (index) { layer.close(index); @@ -396,6 +401,13 @@ function cancelOrder(id) { febs.get(ctx + 'admin/order/cancelOrder/' + id, null, function () { febs.alert.success('操作成功'); $query.click(); }); } function insurePay(id) { febs.get(ctx + 'admin/order/insurePay/' + id, null, function () { febs.alert.success('操作成功'); $query.click(); }); @@ -682,7 +694,9 @@ // {field: 'wxOrderNo', title: '支付订单号', minWidth: 120,align:'left'}, {title: '操作', templet: function (d) { if(d.status === 2){ if(d.status === 1){ return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="insurePay" shiro:hasPermission="user:update">确认收款</button>' }else if(d.status === 2){ return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="deliverGoods" shiro:hasPermission="user:update">发货</button>' +'<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="seeOrder" shiro:hasPermission="user:update">详情</button>' // +''