total_price 全链路(超详细版)

1. 业务定义(一句话)

⚡⚡⚡ total_price 是订单应付金额,由9个 current_* 字段按固定顺序求和得出,并将负结果保护为 0,是支付对账和退款口径的核心基准。

2. 9个字段的组成与正负

序号字段名含义典型符号在公式中的方向
1current_subtotal_price商品行小计正 (+)
2current_shipping_price运费正 (+)
3current_insurance_price运费险正 (+)
4current_tip_price小费正 (+)
5current_tax_price税费正 (+)
6current_coupon_price优惠券抵扣负 (−)加(减负)
7current_payment_price支付手续费正 (+)
8current_promotion_price活动优惠负 (−)加(减负)
9current_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&#40;sum, 0&#41;}
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_priceCartService::cartDataComposition
current_shipping_priceShippingZoneHandlerService::getCartShippingPrice
current_insurance_priceInsuranceService::getInsurancePrice
current_tip_priceTipService::cartTipPrice
current_tax_priceTaxService::getCartTaxes
current_coupon_priceCouponHandlerService::calPreCouponPrice
current_payment_pricePaymentService::getPaymentFee
current_promotion_pricePromotionHandlerService::getCartPromotion
current_offer_priceOrderDiyOfferService::updateOrderInfo

⚠️ 任意一个 current_* 字段变化后,都需要触发 renew 才能让 total_price 同步更新。

7. 字段输出结构

字段类型含义示例
o_order.total_pricefloat最终应付金额(≥0)245.00
o_order.current_total_pricefloat中间展示口径(= subtotal+shipping)265.00
o_order.refund_pricefloat累计退款金额(独立字段,不在此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 文档