Диагностика проблемы: почему стандартный WooCommerce не обновляет цену при изменении количества на странице товара
По умолчанию WooCommerce рассчитывает стоимость товара, умножая цену на выбранное количество при оформлении заказа. Однако на странице самого товара стоимость не меняется динамически при изменении количества. Это может вводить пользователей в заблуждение, особенно когда есть скидки или специальные цены за объём.
Задача: реализовать динамическое обновление цены товара на странице с помощью AJAX без перезагрузки, чтобы покупатель сразу видел итоговую сумму.
Пошаговое решение: динамическое обновление цены товара по количеству
1. Добавляем JavaScript для отслеживания изменения количества
Создайте файл custom-quantity-price.js и подключите его в теме или плагине. В этом скрипте при изменении поля количества будет отправляться AJAX-запрос на сервер.
jQuery(document).ready(function($) {
$(document).on('change', 'input.qty', function() {
var qty = parseInt($(this).val());
var productID = $(this).closest('form.cart').find('input[name="add-to-cart"]').val();
if (qty > 0) {
$.ajax({
url: wc_add_to_cart_params.ajax_url,
type: 'POST',
data: {
action: 'update_price_by_quantity',
product_id: productID,
quantity: qty
},
success: function(response) {
if (response.success) {
$('.woocommerce-Price-amount.amount').first().html(response.data.price_html);
}
}
});
}
});
});2. Обработчик AJAX на стороне PHP
Добавьте следующий код в functions.php вашей темы или в плагин для обработки запроса и вычисления итоговой цены с учётом количества.
add_action('wp_ajax_update_price_by_quantity', 'update_price_by_quantity_callback');
add_action('wp_ajax_nopriv_update_price_by_quantity', 'update_price_by_quantity_callback');
function update_price_by_quantity_callback() {
if ( ! isset($_POST['product_id'], $_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();
}
// Получаем цену товара
$price = $product->get_price();
// Пример: добавим скидку 5% при покупке от 10 штук
if ($quantity >= 10) {
$price = $price * 0.95; // скидка 5%
}
$total_price = wc_price($price * $quantity);
wp_send_json_success(['price_html' => $total_price]);
}3. Подключение скрипта и передача параметров
В functions.php добавьте:
function enqueue_custom_quantity_price_script() {
if (is_product()) {
wp_enqueue_script('custom-quantity-price', get_stylesheet_directory_uri() . '/js/custom-quantity-price.js', ['jquery'], null, true);
wp_localize_script('custom-quantity-price', 'wc_add_to_cart_params', [
'ajax_url' => admin_url('admin-ajax.php'),
]);
}
}
add_action('wp_enqueue_scripts', 'enqueue_custom_quantity_price_script');Проверка результата после внедрения
- Откройте страницу товара в браузере.
- Измените количество в поле
input.qty. - Обратите внимание, что цена рядом с кнопкой «В корзину» обновляется без перезагрузки.
- Проверьте, что при количестве 10 и более применяется скидка 5% (цена уменьшается).
- В консоли браузера нет ошибок JavaScript и AJAX-запросы успешно возвращают данные.
Частые ошибки и как исправить
- AJAX-запрос не срабатывает: Убедитесь, что скрипт подключен и
wc_add_to_cart_params.ajax_urlдоступен. - Цена не обновляется на странице: Проверьте правильность селектора
.woocommerce-Price-amount.amount. В некоторых темах класс может отличаться. - Скидка не применяется: Убедитесь, что логика в PHP-функции корректно считает цену и что количество передаётся как число.
- Ошибка PHP: Включите WP_DEBUG для отладки и проверьте ошибки в логах.
Практические советы по безопасности и производительности
- Всегда проверяйте и фильтруйте входящие данные:
intval()для числовых значений. - Кешируйте результаты вычислений, если цена рассчитывается по тяжёлым формулам или с учётом внешних данных.
- Используйте nonce для защиты AJAX-запросов от CSRF-атак (в данном примере для упрощения опущено, но рекомендуется).
- Оптимизируйте селекторы jQuery — используйте делегирование для динамически загружаемых элементов.
Сравнение вариантов реализации динамического расчёта цены
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| JavaScript + AJAX | Динамическое обновление цены без перезагрузки | Улучшает UX, быстрое обновление | Требует дополнительной разработки и тестирования |
| Перезагрузка страницы | Обновление цены при изменении количества через перезагрузку | Простая реализация | Плохой пользовательский опыт, медленно |
| Плагины с динамическим ценообразованием | Использование готовых решений для сложных правил ценообразования | Готовый функционал, поддержка | Могут быть тяжелыми и дорогими |