wpstart.ru wordpress wpstart.ru

WooCommerce: автоматическое изменение стоимости товара при выборе способа доставки

Проблема: необходимость менять цену товара в зависимости от выбранного способа доставки

В стандартном WooCommerce нет встроенной функции, которая позволяла бы менять стоимость товара в корзине динамически в зависимости от выбранного метода доставки. Часто это требуется для корректного расчёта стоимости, например, для доставки с разными тарифами или дополнительными сборами.

Диагностика задачи

Перед решением важно понять, какая именно логика изменения стоимости требуется:

  • Изменять цену товара на фиксированную сумму или процент;
  • Изменять общую стоимость заказа;
  • Добавлять скрытые сборы на уровне товара;
  • Применять изменение только к определённым товарам или категориям;
  • Реагировать на выбор конкретного способа доставки.

Для проверки выбранного способа доставки можно использовать хук woocommerce_checkout_update_order_review или отслеживать данные из сессии WooCommerce.

Пошаговое решение: пример изменения цены товара при выборе способа доставки

1. Отслеживаем выбор способа доставки через AJAX

WooCommerce при выборе способа доставки обновляет данные через AJAX. Можно подключиться к этому событию и сохранить выбранный метод в сессии:

add_action('woocommerce_checkout_update_order_review', 'save_chosen_shipping_method');
function save_chosen_shipping_method($posted_data) {
    parse_str($posted_data, $output);
    if (!empty($output['shipping_method'])) {
        WC()->session->set('chosen_shipping_method', $output['shipping_method'][0]);
    }
}

2. Изменяем цену товара в корзине перед расчётом итогов

Используем хук woocommerce_before_calculate_totals, чтобы динамически менять цену товара:

add_action('woocommerce_before_calculate_totals', 'change_product_price_based_on_shipping', 20, 1);
function change_product_price_based_on_shipping($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    $chosen_shipping = WC()->session->get('chosen_shipping_method');

    if (!$chosen_shipping) return;

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $original_price = $product->get_regular_price();

        // Пример логики: если выбран способ доставки "flat_rate:5" — увеличиваем цену на 10%
        if ($chosen_shipping === 'flat_rate:5') {
            $new_price = $original_price * 1.10; // +10%
            $product->set_price($new_price);
        } else {
            // Сбрасываем цену, если другой способ доставки
            $product->set_price($original_price);
        }
    }
}

Проверка результата

  • Добавьте товар в корзину и перейдите к оформлению заказа.
  • Выберите способ доставки с ID flat_rate:5 (замените на актуальный ID вашего способа).
  • Проверьте, что цена товара изменилась на 10%.
  • Выберите другой способ доставки — цена должна вернуться к исходной.
  • Обновите страницу и убедитесь, что изменения сохраняются корректно.

Частые ошибки и их исправление

  • Цена не меняется в корзине или на странице оформления заказа. Проверьте, что хук woocommerce_before_calculate_totals подключён с приоритетом выше 10 (чтобы перекрывать другие изменения). Также убедитесь, что сессия WooCommerce корректно сохраняет выбранный способ доставки.
  • Изменения не сохраняются при обновлении страницы. Возможно, сессия не была сохранена или выбран способ доставки сбрасывается. Проверьте работу функции сохранения в сессии и правильность ключа.
  • Ошибка на странице админки или при AJAX-запросах. Добавьте проверку if (is_admin() && !defined('DOING_AJAX')) return; в обработчик изменения цены, чтобы избежать ошибок в админке.

Практические советы по безопасности и производительности

  • Изменяйте цену товара только в оперативной памяти объекта WC_Product в корзине, не сохраняйте изменения в базе данных.
  • Не используйте жёсткие ID способов доставки — получайте их динамически или документируйте, чтобы не забыть.
  • Минимизируйте количество вычислений в цикле корзины для оптимальной производительности.
  • Для более сложных сценариев рассмотрите использование пользовательских сборов (fees), если изменение цены товара не подходит.

Сравнение подходов

СпособПлюсыМинусы
Изменение цены товара через woocommerce_before_calculate_totalsГибко, напрямую меняет цену, отображается в корзинеМожно запутать пользователя, влияет на отчёты и аналитики
Добавление дополнительного сбора (fee) с учётом доставкиПрозрачно отделяет стоимость доставки от товара, проще для отчётовНе меняет цену товара, требует дополнительной настройки отображения
Использование плагинов для динамического ценообразованияРасширенный функционал, готовые решенияДополнительная нагрузка, возможны конфликты, платные решения
×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее