Диагностика задачи: зачем менять стоимость товара при выборе способа доставки
В стандартном WooCommerce цена товара фиксирована и не зависит от выбранного способа доставки. Однако в ряде бизнес-сценариев требуется динамически корректировать стоимость товара или итоговую сумму заказа в зависимости от способа доставки. Например, при выборе экспресс-доставки может добавляться дополнительная наценка на товар, или при самовывозе — скидка.
Чтобы реализовать такое поведение, нужно вмешаться в процесс расчёта стоимости заказа и применить корректировки цен до финального отображения и расчёта в корзине и на странице оформления заказа.
Как отследить выбор способа доставки в WooCommerce
Способ доставки выбирается пользователем на странице корзины (если там включён выбор способа) или оформления заказа. WooCommerce сохраняет выбранный метод в объекте WC()->session и в объекте заказа WC_Order.
Для динамического изменения цены товара на лету нужно использовать хуки, которые вызываются при обновлении корзины и расчёте итогов.
Основные хуки для изменения цены товара
woocommerce_before_calculate_totals— вызывается перед подсчётом итоговой суммы корзины. В этот момент можно изменить цену товаров.woocommerce_cart_calculate_fees— для добавления дополнительных сборов к корзине (например, наценки за доставку).
Пошаговое решение: изменение цены товара при выборе способа доставки
Рассмотрим пример, когда при выборе способа доставки с ID express_shipping мы увеличиваем цену каждого товара на 10%.
1. Добавляем код в functions.php вашей темы или в плагин
add_action('woocommerce_before_calculate_totals', 'custom_change_price_based_on_shipping', 20, 1);
function custom_change_price_based_on_shipping( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// Получаем выбранный способ доставки
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
if ( empty( $chosen_methods ) ) return;
// Проверяем, есть ли среди выбранных способ доставки express_shipping
if ( in_array( 'express_shipping', $chosen_methods ) ) {
// Применяем наценку 10% к каждому товару
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$original_price = $cart_item['data']->get_regular_price();
$new_price = $original_price * 1.10; // +10%
$cart_item['data']->set_price( $new_price );
}
}
}2. Проверяем корректность работы
- Перейдите на страницу корзины или оформления заказа.
- Выберите способ доставки
express_shipping(или замените ID на фактический из вашей настройки доставки). - Цена товаров должна измениться с увеличением на 10%.
- Если выбраны другие способы доставки — цена остаётся без изменений.
Проверка результата после внедрения
Чтобы убедиться, что всё работает корректно, сделайте следующее:
- Откройте консоль браузера и проверьте, что при переключении способа доставки корзина обновляется (нужен AJAX).
- Проверьте исходный HTML и отобразившуюся цену товара в корзине и на странице оформления.
- Попробуйте оформить заказ с разными способами доставки и проверьте итоговую сумму.
- В админке в заказе убедитесь, что цена товара соответствует с учётом наценки (если нужно, добавьте дополнительную обработку для записи цены в заказ).
Частые ошибки и как их исправить
- Цена не меняется при выборе способа доставки
Проверьте, что выбран правильный ID способа доставки в коде и что корзина обновляется AJAX-ом при смене способа. - Наценка применяется несколько раз
Избегайте повторного применения наценки, добавляя проверкуdid_action('woocommerce_before_calculate_totals'). - Изменение цены не сохраняется в заказе
Для корректного сохранения цены в заказе нужно дополнительно обработать хукwoocommerce_checkout_create_order_line_itemи задать цену там. - Конфликты с другими плагинами
Проверьте совместимость, отключая другие плагины, которые меняют цены или доставку.
Практические советы по безопасности и производительности
- Не сохраняйте цену товара в сессии вручную. Используйте хуки WooCommerce для изменения цены на лету.
- Избегайте тяжелых операций в хуках, влияющих на корзину — это замедляет загрузку страниц.
- Тестируйте изменения в разных браузерах и на мобильных устройствах.
- Если наценка зависит от внешних данных, кэшируйте результаты для повышения производительности.
Таблица сравнения подходов к изменению цены товара по способу доставки
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Изменение цены в woocommerce_before_calculate_totals | Изменение цены товара в корзине динамически | Гибко, работает сразу в корзине | Цена меняется только в сессии, нужно доработать сохранение в заказе |
Добавление сборов через woocommerce_cart_calculate_fees | Добавление дополнительной платы как отдельного сбора | Просто реализовать, отображается отдельно | Не меняет цену товара, отображается отдельной строкой |
| Создание пользовательских полей и изменение цены при сохранении заказа | Меняет цену окончательно в заказе | Цена сохраняется корректно | Сложнее в реализации, не влияет на отображение в корзине сразу |