total_price 全链路(超详细版)
1. 业务定义(一句话)
⚡⚡⚡ total_price 是订单应付金额,由9个 current_* 字段按固定顺序求和得出,并将负结果保护为 0,是支付对账和退款口径的核心基准。
2. 9个字段的组成与正负
| 序号 | 字段名 | 含义 | 典型符号 | 在公式中的方向 |
|---|---|---|---|---|
| 1 | current_subtotal_price | 商品行小计 | 正 (+) | 加 |
| 2 | current_shipping_price | 运费 | 正 (+) | 加 |
| 3 | current_insurance_price | 运费险 | 正 (+) | 加 |
| 4 | current_tip_price | 小费 | 正 (+) | 加 |
| 5 | current_tax_price | 税费 | 正 (+) | 加 |
| 6 | current_coupon_price | 优惠券抵扣 | 负 (−) | 加(减负) |
| 7 | current_payment_price | 支付手续费 | 正 (+) | 加 |
| 8 | current_promotion_price | 活动优惠 | 负 (−) | 加(减负) |
| 9 | current_offer_price | 订单级插件附加/抵扣 | 可正可负 | 加 |
⚡⚡⚡ 优惠字段(coupon/promotion/offer为负)和附加费字段(其余为正)在公式中统一用加法,因为优惠字段本身存储为负数。
3. 核心计算代码(OrderService::renew)
// OrderService.php:2282-2290
$total_price = $current_subtotal_price;
$total_price += $current_shipping_price;
$total_price += $current_insurance_price;
$total_price += $current_tip_price;
$total_price += $current_tax_price;
$total_price += $current_coupon_price;
$total_price += $current_payment_price;
$total_price += $current_promotion_price;
$total_price += $current_offer_price;
// 下限保护(若优惠超过所有附加费,总价可能为负)
if ($total_price < 0) {
$total_price = 0;
}3.1 下限保护
$data['total_price'] = max($total_price, 0);当 coupon/promotion 等优惠金额之和超过 subtotal + shipping + tax + … 时,total_price 被保护为 0,不出现「商家欠买家钱」的负应付额。
4. 全链路时序图(配置 → 计算 → 落库)
flowchart TD A[current_subtotal_price] --> Z[Σ9字段求和] B[current_shipping_price] --> Z C[current_insurance_price] --> Z D[current_tip_price] --> Z E[current_tax_price] --> Z F[current_coupon_price] --> Z G[current_payment_price] --> Z H[current_promotion_price] --> Z I[current_offer_price] --> Z Z --> J{max(sum, 0)} J --> K[写 o_order.total_price] K --> L[支付/对账/退款基准]
5. 与 current_total_price 的关系
current_total_price = subtotal + shipping 仅展示
total_price = subtotal + shipping + tax + coupon + promotion + tip + payment + insurance + offer
└─ 比 current_total_price 多了7项
两者不是包含关系,是不同的用途口径:
current_total_price:让买家看到「商品+运费」大概要付多少total_price:实际支付金额,对账和退款的基准
6. 各字段的前置链路
| 字段 | 前置链路(入口方法) |
|---|---|
| current_subtotal_price | CartService::cartDataComposition |
| current_shipping_price | ShippingZoneHandlerService::getCartShippingPrice |
| current_insurance_price | InsuranceService::getInsurancePrice |
| current_tip_price | TipService::cartTipPrice |
| current_tax_price | TaxService::getCartTaxes |
| current_coupon_price | CouponHandlerService::calPreCouponPrice |
| current_payment_price | PaymentService::getPaymentFee |
| current_promotion_price | PromotionHandlerService::getCartPromotion |
| current_offer_price | OrderDiyOfferService::updateOrderInfo |
⚠️ 任意一个 current_* 字段变化后,都需要触发 renew 才能让 total_price 同步更新。
7. 字段输出结构
| 字段 | 类型 | 含义 | 示例 |
|---|---|---|---|
o_order.total_price | float | 最终应付金额(≥0) | 245.00 |
o_order.current_total_price | float | 中间展示口径(= subtotal+shipping) | 265.00 |
o_order.refund_price | float | 累计退款金额(独立字段,不在此9字段中) | 80.00 |
⚡ refund_price 独立于 total_price 体系:退款不改变 total_price,只在退款流程中用于计算可退额度。
8. 边界场景说明
8.1 所有优惠叠加导致 total_price < 0
max(sum, 0) 保护,总价显示为 0(通常意味着需要运营端介入调整优惠策略)。
8.2 某个字段未更新导致 total_price 不一致
例:coupon 已使用但 renew 未执行,total_price 中仍含优惠前的值。排障时逐项核对9个 current_* 字段。
8.3 currency 换算影响
total_price 落库时使用的是订单主货币,若买家使用非主货币支付,currencyExchange 换算发生在展示层,total_price 本身始终以主货币存储。
9. 关键代码索引
| 逻辑 | 文件:行号 |
|---|---|
| total_price 9字段求和 | OrderService.php:2282-2290 |
| 下限保护 max(sum,0) | OrderService.php:2294 |
| 全部字段写回 | OrderService.php:2294-2304 |
| renew 触发入口 | OrderService::renew |
| 各字段详情见对应文档 | 见 pricing 目录下各 flow 文档 |