如何在 WC_Shipping_Method calculate_shipping() 方法中获取购物车小计

How to get cart subtotal inside WC_Shipping_Method calculate_shipping() method

所以我试图创建一个 woocommerce 运输方法,该方法采用购物车小计并收取购物车小计的用户定义百分比作为运费。作为迈向这个目标的第一步,我做的事情基本上是这样的

class Subtotal_Percentage_Method extends WC_Shipping_Method {
    // to store percentage
    private $percentage_rate
    // constructor that handles settings
    // here is where i start calculation
    public function calculate_shipping($packages = array()) {
        $cost = $this->percentage_rate * 1000;
        add_rate(array(
            'id' => $this->id,
            'label' => $this->title,
            'cost' => $cost
        ));
    }
}

这个有效。但是,当我更改 calculate_shipping 方法以在计算中使用购物车小计时,它不起作用

public function calculate_shipping($packages = array()) {
    $subtotal = WC()->cart->subtotal;
    $cost = $subtotal * $this->percentage_rate / 100;
    add_rate(array(
        'id' => $this->id,
        'label' => $this->title,
        'cost' => $cost
    ));
}

任何人都可以告诉我我做错了什么吗?

由于这与运输包裹有关(因为购物车商品可以拆分(划分)到多个运输包裹中),您需要使用 calculate_shipping() 方法中包含的变量 $packages 参数。

因此,如果不使用 WC_Cart 对象方法,您的代码将略有不同:

public function calculate_shipping( $packages = array() ) {
    $total = $total_tax = 0; // Initializing

    // Loop through shipping packages
    foreach( $packages as $key => $package ){
            // Loop through cart items for this package
        foreach( $package['contents'] as $item ){
            $total      += $item['total']; // Item subtotal discounted
            $total_tax  += $item['total_tax']; // Item subtotal tax discounted
        }
    }

    add_rate( array(
        'id'       => $this->id,
        'label'    => $this->title,
        'cost'     => $total * $this->percentage_rate / 100,
        // 'calc_tax' => 'per_item'
    ) );
}

代码进入您的活动子主题(活动主题)的 functions.php 文件。已测试并有效。

注意:此处计算的是购物车商品折扣后小计(不含税)。您可以在 购物车商品小计后轻松添加 ,替换为:

'cost'     => $total * $this->percentage_rate / 100,
 

作者:

'cost'     => ($total + $total_tax) * $this->percentage_rate / 100,

You can see how are made the shipping packages looking to:
WC_Cart get_shipping_packages() method source code

If you want to handle also shipping classes and more, check:
WC_Shipping_Flat_Rate calculate_shipping() method source code.