Диагностика задачи: зачем менять цену товара динамически при изменении количества
В стандартном WooCommerce цена товара фиксирована и изменяется только при смене вариаций или скидок. Однако, в некоторых сценариях требуется, чтобы цена автоматически корректировалась в зависимости от выбранного количества товара — например, для оптовых скидок или специальных акций. Без доработок клиент вынужден смотреть итоговую сумму в корзине, не видя изменённой цены сразу на странице товара, что ухудшает UX и может снижать конверсию.
Основная цель — показать покупателю цену за выбранное количество товара прямо на странице, динамически обновляя её при изменении поля количества.
Пошаговое решение: как реализовать динамическое изменение цены на странице товара
1. Добавляем JavaScript для отслеживания изменения количества
Необходимо навесить обработчик события на поле количества и при изменении отправлять AJAX-запрос на сервер для пересчёта цены.
jQuery(document).ready(function($) {
$('input.qty').on('change input', function() {
var quantity = parseInt($(this).val());
if (quantity < 1 || isNaN(quantity)) {
quantity = 1;
$(this).val(quantity);
}
var productId = $('form.cart').find('input[name="add-to-cart"]').val();
$.ajax({
url: wc_add_to_cart_params.ajax_url,
type: 'POST',
data: {
action: 'recalculate_price',
product_id: productId,
quantity: quantity
},
success: function(response) {
if(response.success) {
$('.woocommerce-Price-amount.amount').first().html(response.data.price_html);
}
}
});
});
});2. Создаём PHP обработчик AJAX-запроса для пересчёта цены
Этот обработчик получает ID товара и количество, рассчитывает цену с учётом возможных скидок и возвращает обновлённый HTML цены.
add_action('wp_ajax_recalculate_price', 'recalculate_price_callback');
add_action('wp_ajax_nopriv_recalculate_price', 'recalculate_price_callback');
function recalculate_price_callback() {
if (empty($_POST['product_id']) || empty($_POST['quantity'])) {
wp_send_json_error('Параметры не переданы');
}
$product_id = intval($_POST['product_id']);
$quantity = intval($_POST['quantity']);
if ($quantity < 1) {
$quantity = 1;
}
$product = wc_get_product($product_id);
if (!$product) {
wp_send_json_error('Товар не найден');
}
// Пример оптовой скидки: 5% при покупке от 10 штук
$price = $product->get_price();
if ($quantity >= 10) {
$price = $price * 0.95;
}
$total_price = $price * $quantity;
// Форматируем цену с валютой
$price_html = wc_price($total_price);
wp_send_json_success(array('price_html' => $price_html));
}3. Подключаем скрипт корректно в теме или плагине
Добавьте подключение JavaScript в functions.php или в плагине:
function enqueue_recalculate_price_script() {
if (is_product()) {
wp_enqueue_script('recalculate-price', get_stylesheet_directory_uri() . '/js/recalculate-price.js', array('jquery'), '1.0', true);
wp_localize_script('recalculate-price', 'wc_add_to_cart_params', array('ajax_url' => admin_url('admin-ajax.php')));
}
}
add_action('wp_enqueue_scripts', 'enqueue_recalculate_price_script');Проверка результата после внедрения
- Откройте страницу товара в WooCommerce.
- Измените количество товара в поле «Количество».
- Проверьте, что цена рядом с кнопкой «В корзину» обновляется автоматически без перезагрузки страницы.
- Для проверки работы оптовой скидки — попробуйте ввести количество от 10 и убедитесь, что цена пересчитывается с учётом скидки.
- Используйте инструменты разработчика браузера (Network) для проверки AJAX-запросов и ответов.
Частые ошибки и как их исправить
- Цена не обновляется: Проверьте правильность селектора
$('.woocommerce-Price-amount.amount').first()в JS — тема может использовать другой класс для цены. - AJAX-запрос возвращает ошибку: Убедитесь, что хук
add_action('wp_ajax_recalculate_price', ...)подключён и функция корректно получает параметры. - Количество не передаётся или равно нулю: В JS добавьте валидацию количества, а в PHP — защиту от некорректных значений.
- Кэширование: Если используется плагин кэширования, исключите AJAX-запросы из кэша или отключите кэширование страниц товаров.
Практические советы по производительности и безопасности
- Кэширование AJAX: не кэшируйте AJAX-запросы, иначе цена не будет обновляться корректно.
- Валидация данных: всегда проверяйте и фильтруйте входящие данные в PHP.
- Оптимизация кода: если логика скидок сложная, выносите её в отдельную функцию для удобства поддержки.
- Минификация JS: используйте минифицированную версию скрипта в продакшн.
Сравнение вариантов реализации динамического изменения цены
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Чистый JS + AJAX | Реализация через AJAX-запросы к серверу с пересчётом цены | Гибко, можно реализовать сложные правила скидок | Требует написания и поддержки кода, зависит от скорости сервера |
| Плагины оптовых скидок | Готовые решения с настройками скидок по количеству | Быстро, не требует программирования | Может быть избыточно, влияет на производительность, ограничена кастомизация |
| Изменение цены через JavaScript на клиенте | Манипуляция DOM без запросов к серверу | Быстро, не нагружает сервер | Не учитывает реальные скидки, легко обойти, небезопасно |