diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
index 2ed262cde..3581fdb91 100644
--- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
+++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
@@ -39,7 +39,7 @@ public interface ProductSkuApi {
     List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds);
 
     /**
-     * 更新 SKU 库存
+     * 更新 SKU 库存(增加 or 减少)
      *
      * @param updateStockReqDTO 更新请求
      */
diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
index 4b8410b83..500601442 100644
--- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
+++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -58,8 +58,9 @@ public interface ErrorCodeConstants {
 
     // ========== Price 相关 1011003000 ============
     ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011003000, "支付价格计算异常,原因:价格小于等于 0");
-    ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空");
+    ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空");
     ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板");
+    ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY = new ErrorCode(1011003003, "计算快递运费异常,自提点为空");
 
     // ========== 物流 Express 模块 1011004000 ==========
     ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在");
diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java
index 7754f115d..210f5c307 100644
--- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java
+++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java
@@ -15,7 +15,6 @@ import java.util.Arrays;
 @AllArgsConstructor
 public enum DeliveryTypeEnum implements IntArrayValuable {
 
-    NULL(0, "无需物流"),
     EXPRESS(1, "快递发货"),
     PICK_UP(2, "用户自提"),;
 
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
index 4f3de0c5d..b62e6eb1f 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
@@ -15,7 +15,8 @@ Authorization: Bearer {{appToken}}
 tenant-id: {{appTenentId}}
 
 {
-  "type": 0,
+  "pointStatus": true,
+  "deliveryType": 1,
   "addressId": 21,
   "items": [
     {
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
index 888a3d4df..4bbd98a27 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.trade.controller.app.order;
 
-import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
@@ -12,11 +11,8 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
-import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
-import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils;
 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
@@ -65,10 +61,7 @@ public class AppTradeOrderController {
     @PostMapping("/create")
     @Operation(summary = "创建订单")
     @PreAuthenticated
-    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.TEST)
-    public CommonResult<AppTradeOrderCreateRespVO> createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) {
-        TradeOrderLogUtils.setOrderInfo(10L, 1, 2,
-                MapUtil.<String, Object>builder().put("nickname", "小明").put("thing", "种土豆").build());
+    public CommonResult<AppTradeOrderCreateRespVO> createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) {
         TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), getClientIP(), createReqVO);
         return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));
     }
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
index 11031a884..2f4503d02 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
@@ -1,8 +1,11 @@
 package cn.iocoder.yudao.module.trade.controller.app.order.vo;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.constraints.AssertTrue;
+
 @Schema(description = "用户 App - 交易订单创建 Request VO")
 @Data
 public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO {
@@ -10,4 +13,10 @@ public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO {
     @Schema(description = "备注", example = "这个是我的订单哟")
     private String remark;
 
+    @AssertTrue(message = "配送方式不能为空")
+    @JsonIgnore
+    public boolean isDeliveryTypeNotNull() {
+        return getDeliveryType() != null;
+    }
+
 }
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
index 929a2ec19..74535d173 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
@@ -30,7 +30,7 @@ public class AppTradeOrderSettlementReqVO {
     private Boolean pointStatus;
 
     // ========== 配送相关相关字段 ==========
-    @Schema(description = "配送方式", required = true, example = "1")
+    @Schema(description = "配送方式", example = "1")
     @InEnum(value = DeliveryTypeEnum.class, message = "配送方式不正确")
     private Integer deliveryType;
 
@@ -62,6 +62,8 @@ public class AppTradeOrderSettlementReqVO {
     @Schema(description = "砍价活动编号", example = "123")
     private Long bargainActivityId;
 
+    // TODO @puhui999:可以写个参数校验,如果 seckillActivityId 或 combinationActivityId 或 combinationHeadId 的情况,items 应该只有一个
+
     @Data
     @Schema(description = "用户 App - 商品项")
     @Valid
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
index d5b9546d0..4688ca9ef 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -56,6 +56,7 @@ public interface TradeOrderConvert {
 
     @Mappings({
             @Mapping(target = "id", ignore = true),
+            @Mapping(source = "userId", target = "userId"),
             @Mapping(source = "createReqVO.couponId", target = "couponId"),
             @Mapping(target = "remark", ignore = true),
             @Mapping(source = "createReqVO.remark", target = "userRemark"),
@@ -89,22 +90,15 @@ public interface TradeOrderConvert {
     TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item);
 
     default ProductSkuUpdateStockReqDTO convert(List<TradeOrderItemDO> list) {
-        return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list));
-    }
-
-    default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) {
-        List<ProductSkuUpdateStockReqDTO.Item> items = TradeOrderConvert.INSTANCE.convertList(list);
-        items.forEach(item -> item.setIncrCount(-item.getIncrCount()));
+        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
+                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
+        return new ProductSkuUpdateStockReqDTO(items);
+    }
+    default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) {
+        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
+                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
         return new ProductSkuUpdateStockReqDTO(items);
     }
-
-    List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list);
-
-    @Mappings({
-            @Mapping(source = "skuId", target = "id"),
-            @Mapping(source = "count", target = "incrCount"),
-    })
-    ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean);
 
     default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
                                          TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) {
@@ -218,8 +212,9 @@ public interface TradeOrderConvert {
 
     default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
                                              List<CartDO> cartList) {
-        TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO();
-        reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId())
+        TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO().setUserId(userId)
+                .setCouponId(settlementReqVO.getCouponId()).setPointStatus(settlementReqVO.getPointStatus())
+                .setDeliveryType(settlementReqVO.getDeliveryType()).setAddressId(settlementReqVO.getAddressId())
                 .setItems(new ArrayList<>(settlementReqVO.getItems().size()));
         // 商品项的构建
         Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId);
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
index 9d8133ef2..bcf50c6d3 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
@@ -251,12 +251,19 @@ public class TradeOrderDO extends BaseDO {
      * 对应 taobao 的 trade.coupon_fee 字段
      */
     private Integer couponPrice;
-    // TODO 芋艿:需要记录使用的积分;
+    /**
+     * 使用的积分
+     */
+    private Integer usePoint;
     /**
      * 积分抵扣的金额,单位:分
      *
      * 对应 taobao 的 trade.point_fee 字段
      */
     private Integer pointPrice;
+//    /**
+//     * 奖励的积分 TODO 疯狂:可以使用这个字段哈;
+//     */
+//    private Integer rewardPoint;
 
 }
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
index 102418260..8f3bff38b 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -47,6 +47,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.order.*;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
+import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
 import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
 import cn.iocoder.yudao.module.trade.service.cart.CartService;
@@ -182,32 +183,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
     public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
-        // 1、执行订单创建前置处理器
-        // TODO @puhui999:最好也抽个 beforeOrderCreate 方法;不要 BO 各自处理参数岂不美哉?
-        TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO);
-        beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO));
-        beforeOrderCreateReqBO.setUserId(userId);
-        beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum));
-        // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
-        tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO));
-
-        // 2. 价格计算
+        // 0. 价格计算
         TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
 
+        // 1. 订单创建前的逻辑
+        beforeCreateTradeOrder(userId, createReqVO, calculateRespBO);
+
         // 2.1 插入 TradeOrderDO 订单
         TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
         // 2.2 插入 TradeOrderItemDO 订单项
         List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
 
-        // 3. 订单创建完后的逻辑
+        // 3. 订单创建后的逻辑
         afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
-
-        // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
         return order;
     }
 
-
     // TODO @puhui999:订单超时,自动取消;
 
     /**
@@ -234,9 +227,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
             address = validateAddress(userId, createReqVO.getAddressId());
         }
         TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address);
-        String no = orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX);
-        order.setType(validateActivity(createReqVO));
-        order.setNo(no);
+        order.setType(calculateRespBO.getType());
+        order.setNo(orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX));
         order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
         order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
         order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
@@ -252,71 +244,80 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         return order;
     }
 
-    /**
-     * 校验活动,并返回订单类型
-     *
-     * @param createReqVO 请求参数
-     * @return 订单类型
-     */
-    private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {
-        if (createReqVO.getSeckillActivityId() != null) {
-            return TradeOrderTypeEnum.SECKILL.getType();
-        }
-        if (createReqVO.getCombinationActivityId() != null) {
-            return TradeOrderTypeEnum.COMBINATION.getType();
-        }
-        // TODO 砍价敬请期待
-        return TradeOrderTypeEnum.NORMAL.getType();
-    }
-
-    private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) {
+    private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO,
+                                                         TradePriceCalculateRespBO calculateRespBO) {
         List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
         tradeOrderItemMapper.insertBatch(orderItems);
         return orderItems;
     }
 
     /**
-     * 执行创建完创建完订单后的逻辑
+     * 订单创建前,执行前置逻辑
+     *
+     * @param userId 用户编号
+     * @param createReqVO 创建订单请求
+     * @param calculateRespBO 订单价格计算结果
+     */
+    private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
+                                        TradePriceCalculateRespBO calculateRespBO) {
+        // 1. 执行订单创建前置处理器
+        TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO);
+        beforeOrderCreateReqBO.setOrderType(calculateRespBO.getType());
+        beforeOrderCreateReqBO.setUserId(userId);
+        beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum));
+        // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
+        tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO));
+
+        // 2. 下单时扣减商品库存
+        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
+    }
+
+    /**
+     * 订单创建后,执行后置逻辑
      *
      * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
      *
      * @param userId          用户编号
      * @param createReqVO     创建订单请求
-     * @param tradeOrderDO    交易订单
+     * @param order    交易订单
      * @param calculateRespBO 订单价格计算结果
      */
     private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
-                                       TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems,
+                                       TradeOrderDO order, List<TradeOrderItemDO> orderItems,
                                        TradePriceCalculateRespBO calculateRespBO) {
-        // 执行订单创建后置处理器
-        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, tradeOrderDO, orderItems.get(0))));
+        // 1. 执行订单创建后置处理器
+        // TODO @puhui999:从通用性来说,应该不用 orderItems.get(0)
+        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
+                TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems.get(0))));
 
-        // 扣减积分 TODO 芋艿:待实现,需要前置;
-        // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣
-
-        // 有使用优惠券时更新 TODO 芋艿:需要前置;
+        // 2. 有使用优惠券时更新
+        // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
         if (createReqVO.getCouponId() != null) {
             couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId)
-                    .setOrderId(tradeOrderDO.getId()));
+                    .setOrderId(order.getId()));
         }
 
-        // 下单时扣减商品库存
-        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
+        // 3. 扣减积分
+        // 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务
+        if (order.getUsePoint() != null && order.getUsePoint() > 0) {
+            memberPointApi.reducePoint(userId, calculateRespBO.getUsePoint(),
+                    MemberPointBizTypeEnum.ORDER_USE.getType(), String.valueOf(order.getId()));
+        }
 
-        // 删除购物车商品
+        // 4. 删除购物车商品
         Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
         if (CollUtil.isNotEmpty(cartIds)) {
             cartService.deleteCart(userId, cartIds);
         }
 
-        // 生成预支付
-        createPayOrder(tradeOrderDO, orderItems, calculateRespBO);
+        // 5. 生成预支付
+        createPayOrder(order, orderItems, calculateRespBO);
 
-        // 增加订单日志 TODO 芋艿:待实现
+        // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
     }
 
-
-    private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems, TradePriceCalculateRespBO calculateRespBO) {
+    private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
+                                TradePriceCalculateRespBO calculateRespBO) {
         // 创建支付单,用于后续的支付
         PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert(
                 order, orderItems, calculateRespBO, tradeOrderProperties);
@@ -344,6 +345,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
         // 校验活动
         // 1、拼团活动
+        // TODO @puhui999:这块也抽象到 handler 里
         if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
             // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
             combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now());
@@ -741,6 +743,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         couponApi.returnUsedCoupon(order.getCouponId());
 
         // 4.回滚积分:积分是支付成功后才增加的吧? 回复:每个项目不同,目前看下来,确认收货貌似更合适,我再看看其它项目的业务选择;
+        // TODO @疯狂:有赞是可配置(支付 or 确认收货),我们按照支付好列;然后这里的退积分,指的是下单时的积分抵扣。
 
         // TODO 芋艿:OrderLog
 
@@ -773,17 +776,18 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 
     @Async
     protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) {
-        int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType();
+        // TODO @疯狂:具体多少积分,需要分成 2 不分:1. 支付金额;2. 商品金额
+        int bizType = MemberPointBizTypeEnum.ORDER_REWARD.getType();
         memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId));
     }
 
     @Async
     protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) {
+        // TODO @疯狂:退款时,按照金额比例,退还积分;https://help.youzan.com/displaylist/detail_4_4-1-49185
         int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType();
         memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId));
     }
 
-
     @Async
     protected void addBrokerageAsync(Long userId, Long orderId) {
         MemberUserRespDTO user = memberUserApi.getUser(userId);
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
index ad777b380..42a2f8139 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
@@ -37,6 +37,11 @@ public class TradeCombinationHandler implements TradeOrderHandler {
 
     @Override
     public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
+        // TODO @puhui999:需要判断下;
+        if (true) {
+            return;
+        }
+
         // 创建砍价记录
         combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
     }
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
index ff5faea26..67019a49a 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.trade.service.price.bo;
 
 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 import lombok.Data;
 
 import javax.validation.Valid;
@@ -17,13 +16,6 @@ import java.util.List;
 @Data
 public class TradePriceCalculateReqBO {
 
-    /**
-     * 订单类型
-     *
-     * 枚举 {@link TradeOrderTypeEnum}
-     */
-    private Integer type;
-
     /**
      * 用户编号
      *
@@ -37,13 +29,12 @@ public class TradePriceCalculateReqBO {
      * 对应 CouponDO 的 id 编号
      */
     private Long couponId;
-
+    // TODO @疯狂:需要增加一个 PriceCalculator 实现积分扣减的计算;写回到 TradePriceCalculateRespBO 的 usePoint
     /**
-     * 收货地址编号
-     *
-     * 对应 MemberAddressDO 的 id 编号
+     * 是否使用积分
      */
-    private Long addressId;
+    @NotNull(message = "是否使用积分不能为空")
+    private Boolean pointStatus;
 
     /**
      * 配送方式
@@ -51,6 +42,18 @@ public class TradePriceCalculateReqBO {
      * 枚举 {@link DeliveryTypeEnum}
      */
     private Integer deliveryType;
+    /**
+     * 收货地址编号
+     *
+     * 对应 MemberAddressDO 的 id 编号
+     */
+    private Long addressId;
+    /**
+     * 自提门店编号
+     *
+     * 对应 PickUpStoreDO 的 id 编号
+     */
+    private Long pickUpStoreId;
 
     /**
      * 商品 SKU 数组
@@ -58,6 +61,30 @@ public class TradePriceCalculateReqBO {
     @NotNull(message = "商品数组不能为空")
     private List<Item> items;
 
+    // ========== 秒杀活动相关字段 ==========
+    /**
+     * 秒杀活动编号
+     */
+    private Long seckillActivityId;
+
+    // ========== 拼团活动相关字段 ==========
+    // TODO @puhui999:是不是拼团记录的编号哈?
+    /**
+     * 拼团活动编号
+     */
+    private Long combinationActivityId;
+
+    /**
+     * 拼团团长编号
+     */
+    private Long combinationHeadId;
+
+    // ========== 砍价活动相关字段 ==========
+    /**
+     * 砍价活动编号
+     */
+    private Long bargainActivityId;
+
     /**
      * 商品 SKU
      */
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
index 76fb68c1f..1171cd8f2 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
@@ -48,6 +48,11 @@ public class TradePriceCalculateRespBO {
      */
     private Long couponId;
 
+    /**
+     * 使用的积分
+     */
+    private Integer usePoint;
+
     /**
      * 订单价格
      */
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
index 5454c450d..7c395dbbf 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
@@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.trade.service.price.calculator;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.module.member.api.address.AddressApi;
 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService;
+import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService;
 import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
@@ -22,8 +25,7 @@ import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
 
 /**
  * 运费的 {@link TradePriceCalculator} 实现类
@@ -37,20 +39,41 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
 
     @Resource
     private AddressApi addressApi;
+
+    @Resource
+    private DeliveryPickUpStoreService deliveryPickUpStoreService;
     @Resource
     private DeliveryExpressTemplateService deliveryExpressTemplateService;
 
     @Override
     public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
-        // TODO @芋艿:如果门店自提,需要校验是否开启;
-        // 1.1 判断配送方式
-        if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) {
+        if (param.getDeliveryType() == null) {
             return;
         }
-        if (param.getAddressId() == null) {
-            throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY);
+        if (DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) {
+            calculateByPickUp(param, result);
+        } else if (DeliveryTypeEnum.EXPRESS.getMode().equals(param.getDeliveryType())) {
+            calculateExpress(param, result);
+        }
+    }
+
+    private void calculateByPickUp(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
+        if (param.getPickUpStoreId() == null) {
+            throw exception(PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY);
+        }
+        DeliveryPickUpStoreDO pickUpStore = deliveryPickUpStoreService.getDeliveryPickUpStore(param.getPickUpStoreId());
+        if (pickUpStore == null || CommonStatusEnum.DISABLE.getStatus().equals(pickUpStore.getStatus())) {
+            throw exception(PICK_UP_STORE_NOT_EXISTS);
+        }
+    }
+
+    // ========= 快递发货 ==========
+
+    private void calculateExpress(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
+        // 1. 得到收件地址区域
+        if (param.getAddressId() == null) {
+            throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY);
         }
-        // 1.2 得到收件地址区域
         AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
         Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId());
 
@@ -89,8 +112,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
             for (OrderItem orderItem : orderItems) {
                 totalCount  += orderItem.getCount();
                 totalPrice  += orderItem.getPayPrice();
-                totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount();
-                totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount();
+                if (orderItem.getWeight() != null) {
+                    totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount();
+                }
+                if (orderItem.getVolume() != null) {
+                    totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount();
+                }
             }
             // 优先判断是否包邮. 如果包邮不计算快递运费
             if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight,
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java
new file mode 100644
index 000000000..6bd479802
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.trade.service.price.calculator;
+
+import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
+import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * 使用积分的 {@link TradePriceCalculator} 实现类
+ *
+ * @author owen
+ */
+@Component
+@Order(TradePriceCalculator.ORDER_POINT_USE)
+@Slf4j
+public class TradePointUsePriceCalculator implements TradePriceCalculator {
+
+    @Override
+    public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
+        // TODO 疯狂:待实现,嘿嘿;
+        if (param.getPointStatus()) {
+            result.setUsePoint(10);
+        } else {
+            result.setUsePoint(0);
+        }
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java
index 92ae9c2ee..cddc1ea21 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java
@@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
 /**
  * 价格计算的计算器接口
  *
+ * 优惠计算顺序:
+ * 1. <a href="https://help.youzan.com/displaylist/detail_4_4-1-53316">积分抵现、会员价、优惠券、粉丝专享价、满减送哪个优先计算?</>
+ *
  * @author 芋道源码
  */
 public interface TradePriceCalculator {
@@ -13,12 +16,13 @@ public interface TradePriceCalculator {
     int ORDER_DISCOUNT_ACTIVITY = 10;
     int ORDER_REWARD_ACTIVITY = 20;
     int ORDER_COUPON = 30;
+    int ORDER_POINT_USE = 40;
     /**
      * 快递运费的计算
      *
      * 放在各种营销活动、优惠劵后面 TODO
      */
-    int ORDER_DELIVERY = 40;
+    int ORDER_DELIVERY = 50;
 
     void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result);
 
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
index bd3d3b5be..b8b9e0fb9 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
@@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
+import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
 
@@ -28,7 +29,7 @@ public class TradePriceCalculatorHelper {
                                                                List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
         // 创建 PriceCalculateRespDTO 对象
         TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
-        result.setType(param.getType());
+        result.setType(getOrderType(param));
         result.setPromotions(new ArrayList<>());
 
         // 创建它的 OrderItem 属性
@@ -69,6 +70,23 @@ public class TradePriceCalculatorHelper {
         return result;
     }
 
+    /**
+     * 计算订单类型
+     *
+     * @param param 计算参数
+     * @return 订单类型
+     */
+    private static Integer getOrderType(TradePriceCalculateReqBO param) {
+        if (param.getSeckillActivityId() != null) {
+            return TradeOrderTypeEnum.SECKILL.getType();
+        }
+        if (param.getCombinationActivityId() != null) {
+            return TradeOrderTypeEnum.COMBINATION.getType();
+        }
+        // TODO 砍价敬请期待
+        return TradeOrderTypeEnum.NORMAL.getType();
+    }
+
     /**
      * 基于订单项,重新计算 price 总价
      *
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java
index 473e3920e..b998f87b1 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java
@@ -45,7 +45,7 @@ public class TradePriceServiceImplTest extends BaseMockitoUnitTest {
     public void testCalculatePrice() {
         // 准备参数
         TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO()
-                .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L)
+                .setUserId(10L)
                 .setCouponId(20L).setAddressId(30L)
                 .setItems(Arrays.asList(
                         new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true),
diff --git a/yudao-module-member/yudao-module-member-api/pom.xml b/yudao-module-member/yudao-module-member-api/pom.xml
index 961bfb656..1f60cd0fc 100644
--- a/yudao-module-member/yudao-module-member-api/pom.xml
+++ b/yudao-module-member/yudao-module-member-api/pom.xml
@@ -21,6 +21,13 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-common</artifactId>
         </dependency>
+
+        <!-- 参数校验 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+            <optional>true</optional>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java
index 5181211f2..3eb749fb6 100644
--- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java
+++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.member.api.point;
 
 import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
 
+import javax.validation.constraints.Min;
+
 /**
  * 用户积分的 API 接口
  *
@@ -17,6 +19,18 @@ public interface MemberPointApi {
      * @param bizType 业务类型 {@link MemberPointBizTypeEnum}
      * @param bizId   业务编号
      */
-    void addPoint(Long userId, Integer point, Integer bizType, String bizId);
+    void addPoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point,
+                  Integer bizType, String bizId);
+
+    /**
+     * 减少用户积分
+     *
+     * @param userId  用户编号
+     * @param point   积分
+     * @param bizType 业务类型 {@link MemberPointBizTypeEnum}
+     * @param bizId   业务编号
+     */
+    void reducePoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point,
+                     Integer bizType, String bizId);
 
 }
diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
index 3d314a4a2..fe76cdb52 100644
--- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
+++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
@@ -17,8 +17,10 @@ import java.util.Objects;
 public enum MemberPointBizTypeEnum implements IntArrayValuable {
 
     SIGN(1, "签到", "签到获得 {} 积分", true),
-    ORDER_BUY(10, "订单消费", "下单获得 {} 积分", true),
-    ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false); // 退回积分
+    ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true),
+    ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false), // 退回积分
+    ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分
+    ;
 
     /**
      * 类型
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java
index 81eec0782..ee407eaf6 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java
@@ -31,4 +31,13 @@ public class MemberPointApiImpl implements MemberPointApi {
         memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId);
     }
 
+    @Override
+    public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) {
+        MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
+        if (bizTypeEnum == null) {
+            throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
+        }
+        memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId);
+    }
+
 }