Сборы, скидки и цена в корзине
Итог корзины WooCommerce пересчитывает сам при каждом изменении. В этот расчёт можно вмешаться в двух местах: добавить отдельную строку — сбор или скидку, либо изменить цену самой позиции. Оба хука работают и в классической, и в блочной корзине.
Код урока пишется в includes/cart.php.
Сбор
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_cart_calculate_fees', function (WC_Cart $cart) {
if ($cart->get_subtotal() < 20) {
$cart->add_fee('Малый заказ', 3.00);
}
});Хук срабатывает при каждом пересчёте и получает корзину. Метод add_fee() добавляет строку с названием и суммой. Положите в корзину одну кружку за 9,90 € и откройте /cart/: в блоке итогов появится строка «Малый заказ — 3,00 €». Добавьте ещё две — строка исчезнет.
Скидка
Сбор с отрицательной суммой работает как скидка:
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_cart_calculate_fees', function (WC_Cart $cart) {
if (is_user_logged_in() && $cart->get_subtotal() >= 50) {
$cart->add_fee('Скидка постоянному покупателю', -5.00);
}
});Вошедший покупатель с корзиной от 50 € увидит строку со знаком минус, и итог уменьшится на 5 €.
Параметры add_fee
| Аргумент | Что задаёт |
|---|---|
$name | Название строки в итогах |
$amount | Сумма, отрицательная — скидка |
$taxable | Облагается ли налогом, по умолчанию false |
$tax_class | Налоговый класс для сбора |
Сборы не хранятся в корзине: их добавляют заново при каждом пересчёте, поэтому условие всегда проверяется по текущему состоянию.
Цена позиции
Чтобы изменить цену самого товара в корзине, используют другой хук — он срабатывает до подсчёта итогов:
// wp-content/plugins/acme-shop/includes/cart.php
add_action('woocommerce_before_calculate_totals', function (WC_Cart $cart) {
foreach ($cart->get_cart() as $item) {
if ($item['quantity'] >= 10) {
$regular = (float) $item['data']->get_regular_price();
$item['data']->set_price($regular * 0.9);
}
}
});Поставьте в корзине количество кружек 10: цена за штуку станет 8,91 € вместо 9,90 €. Меняется только объект товара в корзине — save() не вызывается, и цена в каталоге остаётся прежней.
Что выбрать
| Задача | Способ |
|---|---|
| Доплата за упаковку, малый заказ | add_fee() с положительной суммой |
| Скидка на весь заказ | add_fee() с отрицательной суммой или купон |
| Оптовая цена за штуку | set_price() в woocommerce_before_calculate_totals |
| Скидка по коду | Купон — о них отдельный урок |
Цена берётся от обычной
В примере новая цена считается от get_regular_price(), а не от get_price(). Хук может сработать несколько раз за один запрос, и расчёт от текущей цены дал бы скидку на скидку: 9,90 → 8,91 → 8,02.
Частая ошибка
Сбор добавляют один раз — например, в хуке добавления товара в корзину. На следующей странице он исчезает, потому что сборы живут только в пределах одного пересчёта. Вызов add_fee() должен стоять в woocommerce_cart_calculate_fees, а условие — проверяться внутри него.