{{wikiTitle}}
订单流程说明
复制链接
编辑文档
CRMEB PRO 订单流程说明
概述
本文档详细描述 CRMEB PRO 系统中订单从创建到完成的完整处理流程,包括订单状态变化、核心业务逻辑和相关代码位置。
订单状态流转图
┌──────────────────────────────────────────────────────────┐
│ 订单生命周期 │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 创建订单 (status=0) │
│ 未支付状态 │
└───────────────────────────┬──────────────────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 支付成功 │ │ 取消订单 │ │ 超时自动取消 │
│ (paid=1) │ │ (is_del=1) │ │ (定时任务) │
└──────┬───────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 待发货 (status=0, paid=1) │
└───────────────────────────┬──────────────────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 发货/自提 │ │ 申请退款 │ │ 改价 │
│ (status=1) │ │(refund_status)│ │ (price修改) │
└──────┬───────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 待收货 (status=1) │
│ (快递配送/门店自提/同城配送) │
└───────────────────────────┬──────────────────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 确认收货 │ │ 自动收货 │ │ 申请售后 │
│ (status=2) │ │ (定时任务) │ │(refund_status)│
└──────┬───────┘ └──────┬───────┘ └──────────────┘
│ │
└────────┬───────────┘
▼
┌──────────────────────────────────────────────────────────┐
│ 待评价 (status=2) │
└───────────────────────────┬──────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ 已完成 (status=3) │
│ (评价后完成) │
└──────────────────────────────────────────────────────────┘
订单状态说明
主状态 (status)
| 状态值 | 说明 | 业务场景 |
|---|---|---|
| 0 | 待发货 | 已支付,等待商家发货 |
| 1 | 待收货 | 已发货,等待用户收货 |
| 2 | 待评价 | 已收货,等待用户评价 |
| 3 | 已完成 | 订单完成 |
支付状态 (paid)
| 状态值 | 说明 |
|---|---|
| 0 | 未支付 |
| 1 | 已支付 |
退款状态 (refund_status)
| 状态值 | 说明 |
|---|---|
| 0 | 未退款 |
| 1 | 申请退款中 |
| 2 | 部分退款 |
| 3 | 已退款 |
配送方式 (shipping_type)
| 状态值 | 说明 |
|---|---|
| 1 | 快递发货 |
| 2 | 门店自提 |
| 3 | 同城配送 |
订单核心流程
1. 购物车加入
相关文件:
- 控制器:
app/controller/api/v1/order/StoreCart.php - 服务层:
app/services/order/StoreCartServices.php - DAO:
app/dao/order/StoreCartDao.php
流程:
// 加入购物车
public function add(Request $request)
{
// 1. 获取参数
[$productId, $cartNum, $productAttrUnique, $type, ...] = $request->postMore([...], true);
// 2. 验证商品
// 3. 检查库存
// 4. 添加/更新购物车
/** @var StoreCartServices $cartServices */
$cartServices = app()->make(StoreCartServices::class);
$cartId = $cartServices->setCart($uid, $productId, $cartNum, $productAttrUnique, $type);
// 5. 触发事件
event('cart.add', [$uid, $productId, $cartNum]);
return app('json')->success('添加成功', ['cartId' => $cartId]);
}
2. 订单确认页
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderCreateServices.php
流程:
// 订单确认
public function confirm(Request $request)
{
// 1. 获取购物车数据
[$cartId, $new, $addressId, ...] = $request->postMore([...], true);
/** @var StoreOrderCreateServices $createServices */
$createServices = app()->make(StoreOrderCreateServices::class);
// 2. 获取确认页数据
$data = $createServices->getOrderConfirmData($uid, $cartId, $new, $addressId);
// 返回数据包含:
// - 商品信息
// - 地址信息
// - 优惠券信息
// - 运费信息
// - 可用积分
// - 价格计算
return app('json')->success($data);
}
3. 订单计算
相关文件:
- 服务层:
app/services/order/StoreOrderComputedServices.php
流程:
// 计算订单金额
public function computedOrder(int $uid, string $key, array $data)
{
// 1. 获取购物车数据
$cartGroup = $this->getCacheOrderInfo($uid, $key);
// 2. 计算商品金额
$totalPrice = $this->getCartTotalPrice($cartGroup['cartInfo']);
// 3. 计算优惠券抵扣
$couponPrice = $this->getCouponPrice($data['couponId'], $totalPrice);
// 4. 计算积分抵扣
$integralPrice = $this->getIntegralPrice($data['useIntegral'], $uid, $totalPrice);
// 5. 计算运费
$postagePrice = $this->getPostagePrice($cartGroup, $data['addressId']);
// 6. 计算最终支付金额
$payPrice = bcsub(bcadd($totalPrice, $postagePrice, 2), bcadd($couponPrice, $integralPrice, 2), 2);
return [
'total_price' => $totalPrice,
'coupon_price' => $couponPrice,
'integral_price' => $integralPrice,
'postage_price' => $postagePrice,
'pay_price' => $payPrice,
];
}
4. 创建订单
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderCreateServices.php
流程:
// 创建订单
public function create(Request $request, string $key)
{
// 1. 获取参数
[$addressId, $couponId, $payType, $useIntegral, $mark, ...] = $request->postMore([...], true);
/** @var StoreOrderCreateServices $createServices */
$createServices = app()->make(StoreOrderCreateServices::class);
// 2. 创建订单(事务处理)
$order = $createServices->createOrder($uid, $key, [
'addressId' => $addressId,
'couponId' => $couponId,
'payType' => $payType,
'useIntegral' => $useIntegral,
'mark' => $mark,
// ...
]);
// 3. 触发订单创建事件
event('order.create', [$order]);
return app('json')->success(['orderId' => $order['order_id']]);
}
订单创建核心逻辑:
// app/services/order/StoreOrderCreateServices.php
public function createOrder(int $uid, string $key, array $data)
{
return $this->transaction(function () use ($uid, $key, $data) {
// 1. 获取购物车数据
$cartGroup = $this->getCacheOrderInfo($uid, $key);
// 2. 生成订单号
$orderId = $this->getNewOrderId();
// 3. 计算订单金额
$priceData = $this->computedOrder($uid, $key, $data);
// 4. 创建订单主表数据
$orderData = [
'order_id' => $orderId,
'uid' => $uid,
'real_name' => $address['real_name'],
'user_phone' => $address['phone'],
'user_address' => $address['province'] . $address['city'] . $address['district'] . $address['detail'],
'total_num' => $cartGroup['totalNum'],
'total_price' => $priceData['total_price'],
'pay_price' => $priceData['pay_price'],
'pay_postage' => $priceData['postage_price'],
'coupon_price' => $priceData['coupon_price'],
'deduction_price' => $priceData['integral_price'],
'pay_type' => $data['payType'],
'mark' => $data['mark'],
'add_time' => time(),
'unique' => md5(time() . $uid),
// ...
];
// 5. 保存订单
$order = $this->dao->save($orderData);
// 6. 保存订单商品信息
$this->saveOrderCartInfo($order['id'], $uid, $cartGroup['cartInfo']);
// 7. 扣除优惠券
if ($data['couponId']) {
$this->useCoupon($data['couponId'], $uid, $orderId);
}
// 8. 扣除积分
if ($data['useIntegral']) {
$this->deductIntegral($uid, $priceData['use_integral']);
}
// 9. 清除购物车
$this->clearCart($uid, $cartGroup['cartIds']);
// 10. 记录订单状态
$this->saveOrderStatus($order['id'], 'create', '订单创建成功');
return $order;
});
}
5. 订单支付
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/pay/PayServices.php - 服务层:
app/services/pay/OrderPayServices.php
流程:
// 订单支付
public function pay(Request $request)
{
// 1. 获取参数
[$uni, $payType, $from] = $request->postMore([...], true);
// 2. 获取订单
$orderInfo = $this->services->getOne(['order_id' => $uni, 'uid' => $uid]);
// 3. 检查订单状态
if ($orderInfo['paid']) {
throw new ApiException('订单已支付');
}
// 4. 调用支付
/** @var OrderPayServices $payServices */
$payServices = app()->make(OrderPayServices::class);
$result = $payServices->pay($payType, $orderInfo, $from);
return app('json')->success($result);
}
支付服务逻辑:
// app/services/pay/PayServices.php
public function pay(string $payType, string $openid, string $orderId, string $price, string $successAction, string $body)
{
switch ($payType) {
case 'weixin':
case 'routine':
// 微信支付
return Payment::jsPay($openid, $orderId, $price, $successAction, $body);
case 'weixinh5':
// 微信H5支付
return Payment::paymentOrder(null, $orderId, $price, $successAction, $body, '', 'MWEB');
case 'alipay':
// 支付宝支付
return AliPayService::instance()->create($body, $orderId, $price, $successAction);
case 'yue':
// 余额支付
return $this->yuePayment($orderId, $price);
default:
throw new ValidateException('支付方式不存在');
}
}
6. 支付回调
相关文件:
- 控制器:
app/controller/api/v1/Pay.php - 服务层:
app/services/pay/PayNotifyServices.php - 监听器:
app/listener/pay/PayNotifyListener.php
流程:
// 支付回调处理
public function notify($type)
{
// 1. 验证签名
// 2. 获取订单信息
// 3. 更新订单支付状态
/** @var PayNotifyServices $notifyServices */
$notifyServices = app()->make(PayNotifyServices::class);
$result = $notifyServices->wechatNotify($type);
// 4. 触发支付成功事件
event('order.pay', [$orderInfo]);
return $result;
}
订单支付成功处理:
// app/listener/order/Pay.php
public function handle($event): void
{
[$orderInfo] = $event;
// 1. 发送支付成功通知
$this->sendPayNotice($orderInfo);
// 2. 赠送积分
$this->giveIntegral($orderInfo);
// 3. 计算分销佣金
$this->calculateCommission($orderInfo);
// 4. 更新用户消费统计
$this->updateUserPayCount($orderInfo);
// 5. 打印订单小票
$this->printOrder($orderInfo);
}
7. 订单发货
相关文件:
- 控制器:
app/controller/admin/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderDeliveryServices.php
流程:
// 订单发货
public function delivery_keep(int $id)
{
// 1. 获取订单
$orderInfo = $this->services->get($id);
// 2. 验证订单状态
if ($orderInfo['status'] != 0 || !$orderInfo['paid']) {
throw new AdminException('订单状态错误');
}
// 3. 执行发货
/** @var StoreOrderDeliveryServices $deliveryServices */
$deliveryServices = app()->make(StoreOrderDeliveryServices::class);
$deliveryServices->delivery($id, $data);
// 4. 触发发货事件
event('order.delivery', [$orderInfo]);
return app('json')->success('发货成功');
}
发货处理逻辑:
// app/services/order/StoreOrderDeliveryServices.php
public function delivery(int $id, array $data)
{
return $this->transaction(function () use ($id, $data) {
// 1. 更新订单状态
$this->dao->update($id, [
'status' => 1,
'delivery_type' => $data['delivery_type'],
'delivery_name' => $data['delivery_name'],
'delivery_id' => $data['delivery_id'],
'delivery_sn' => $data['delivery_sn'] ?? '',
]);
// 2. 记录订单状态
$this->saveOrderStatus($id, 'delivery', '订单已发货');
// 3. 发送发货通知
$this->sendDeliveryNotice($id);
// 4. 同步小程序发货信息
$this->syncRoutineShipping($id);
});
}
8. 确认收货
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderTakeServices.php
流程:
// 确认收货
public function take(Request $request)
{
[$orderId] = $request->postMore([...], true);
/** @var StoreOrderTakeServices $takeServices */
$takeServices = app()->make(StoreOrderTakeServices::class);
$takeServices->takeOrder($orderId, $uid);
// 触发收货事件
event('order.take', [$orderInfo]);
return app('json')->success('收货成功');
}
收货处理逻辑:
// app/services/order/StoreOrderTakeServices.php
public function takeOrder(string $orderId, int $uid)
{
return $this->transaction(function () use ($orderId, $uid) {
// 1. 获取订单
$orderInfo = $this->getOrderByOrderId($orderId, $uid);
// 2. 验证订单状态
if ($orderInfo['status'] != 1) {
throw new ApiException('订单状态错误');
}
// 3. 更新订单状态
$this->dao->update($orderInfo['id'], ['status' => 2]);
// 4. 记录状态
$this->saveOrderStatus($orderInfo['id'], 'take', '用户确认收货');
// 5. 结算分销佣金
$this->settleBrokerage($orderInfo);
// 6. 赠送收货积分/优惠券
$this->giveAward($orderInfo);
});
}
9. 订单评价
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderCommentServices.php
流程:
// 订单评价
public function comment(Request $request)
{
[$orderId, $commentData] = $request->postMore([...], true);
/** @var StoreOrderCommentServices $commentServices */
$commentServices = app()->make(StoreOrderCommentServices::class);
$commentServices->comment($uid, $orderId, $commentData);
// 触发评价事件
event('order.comment', [$orderInfo]);
return app('json')->success('评价成功');
}
10. 订单退款
相关文件:
- 控制器:
app/controller/api/v1/order/StoreOrder.php - 服务层:
app/services/order/StoreOrderRefundServices.php
流程:
// 申请退款
public function applyRefund(int $id, Request $request)
{
[$refundReason, $refundReasonWap, $refundReasonWapImg, $text] = $request->postMore([...], true);
/** @var StoreOrderRefundServices $refundServices */
$refundServices = app()->make(StoreOrderRefundServices::class);
$refundServices->applyRefund($id, $uid, [
'refund_reason' => $refundReason,
'refund_reason_wap' => $refundReasonWap,
'refund_reason_wap_img' => $refundReasonWapImg,
'text' => $text,
]);
// 触发退款申请事件
event('order.applyRefund', [$orderInfo]);
return app('json')->success('申请成功');
}
订单相关数据表
| 表名 | 说明 |
|---|---|
eb_store_order |
订单主表 |
eb_store_order_cart_info |
订单商品信息表 |
eb_store_order_status |
订单状态记录表 |
eb_store_order_refund |
订单退款表 |
eb_store_order_invoice |
订单发票表 |
订单队列任务
| 队列任务 | 说明 | 位置 |
|---|---|---|
OrderPaySuccessJob |
支付成功处理 | app/jobs/order/ |
OrderCreateJob |
订单创建后处理 | app/jobs/order/ |
OrderRefundJob |
退款处理 | app/jobs/order/ |
OrderTakeJob |
收货处理 | app/jobs/order/ |
OrderCancelJob |
订单取消处理 | app/jobs/order/ |
订单相关事件
| 事件名 | 说明 | 触发时机 |
|---|---|---|
cart.add |
加入购物车 | 添加购物车时 |
order.create |
订单创建 | 订单创建成功后 |
order.pay |
订单支付 | 支付成功后 |
order.delivery |
订单发货 | 发货成功后 |
order.take |
订单收货 | 确认收货后 |
order.comment |
订单评价 | 评价提交后 |
order.cancel |
订单取消 | 订单取消后 |
order.refund |
订单退款 | 退款成功后 |
order.applyRefund |
申请退款 | 申请退款后 |
定时任务
| 任务 | 说明 | 执行周期 |
|---|---|---|
| 订单超时取消 | 未支付订单自动取消 | 每分钟 |
| 自动收货 | 发货后超时自动收货 | 每分钟 |
| 自动完成 | 收货后超时自动完成 | 每分钟 |
| 拼团超时处理 | 拼团失败自动退款 | 每分钟 |
注意事项
- 订单号唯一性:订单号通过时间戳+随机数生成,高并发场景需要确保唯一性检查
- 库存扣减时机:库存在支付成功后扣减,而非下单时扣减,避免恶意占用库存
- 事务处理:订单创建涉及多表操作(订单表、购物车、优惠券、积分等),必须使用事务确保数据一致性
- 金额计算精度:使用
bcmath扩展进行金额计算,避免浮点数精度问题 - 状态流转限制:订单状态只能按照预定流程流转,避免跳跃式状态变更
- 退款限制:退款金额不能超过实际支付金额,部分退款需要记录已退金额
- 定时任务依赖:订单超时取消、自动收货等功能依赖定时任务,确保 Swoole 或 Cron 正常运行
- 并发防护:高并发下单场景使用 Redis 分布式锁防止超卖和重复下单
常见问题
Q: 订单创建成功但购物车商品未清除?
A: 检查clearCart方法是否正确执行,确认购物车 ID 传递是否正确,事务是否正常提交Q: 支付成功后订单状态未更新?
A: 检查支付回调是否正常接收,PaySuccessServices中的状态更新逻辑是否执行,查看日志排查问题Q: 订单超时未自动取消?
A: 确认定时任务是否正常运行,检查OrderCancelJob队列任务是否正常消费,查看后台订单超时时间配置Q: 如何修改订单自动收货的天数?
A: 在后台「系统设置 - 交易设置」中修改自动收货天数配置Q: 订单退款后如何恢复库存?
A: 退款成功后系统会触发order.refund事件,在监听器中处理库存回滚逻辑Q: 如何获取订单的完整流转记录?
A: 查询eb_store_order_status表,该表记录了订单的所有状态变更历史
评论({{cateWiki.comment_num}})
最新
最早
{{cateWiki.page_view_num}}人看过该文档
评论(0)
最新
最早
314人看过
登录/注册
即可发表评论
{{item.user ? item.user.nickname : ''}}
(自评)
{{item.content}}
搜索结果
为您找到{{wikiCount}}条结果
{{item.page_view_num}}
{{item.like ? item.like.like_num : 0}}
{{item.comment ? item.comment.comment_num : 0}}
位置:
{{path.name}}
{{(i+1) == getCataloguePathData(item.catalogue).length ? '':'/'}}
