В чем суть задачи: изменение цены в зависимости от количества
В стандартном WooCommerce цена товара фиксирована и не меняется при выборе количества товара на странице. Но бывают задачи, когда цена должна меняться динамически, например, при покупке от 5 единиц — скидка 10%, от 10 — 20% и т.п. Это удобно для оптовых покупателей и стимулирует большие заказы.
Диагностика: как понять, что стандартного функционала недостаточно
Если вы хотите, чтобы цена менялась прямо на странице товара без перехода в корзину или оформление заказа, стандартный WooCommerce не предлагает такой возможности. При изменении количества цена не обновляется автоматически, что может запутать пользователя и снизить конверсию.
Проверьте, изменяется ли цена динамически на странице товара при изменении количества — если нет, значит, пора внедрять кастомное решение.
Пошаговое решение: реализация динамического обновления цены товара по количеству
1. Добавляем JavaScript для отслеживания изменения количества
В файл вашей темы functions.php или в подключаемый скрипт добавьте регистрацию и подключение JS-файла:
function wpfront_enqueue_quantity_price_script() {
if ( is_product() ) {
wp_enqueue_script( 'wpfront-quantity-price', get_stylesheet_directory_uri() . '/js/quantity-price.js', array( 'jquery' ), null, true );
wp_localize_script( 'wpfront-quantity-price', 'wpfront_params', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'product_id' => get_the_ID(),
'nonce' => wp_create_nonce( 'wpfront_quantity_price_nonce' )
) );
}
}
add_action( 'wp_enqueue_scripts', 'wpfront_enqueue_quantity_price_script' );2. Скрипт quantity-price.js для отправки ajax-запроса
jQuery(document).ready(function($) {
var qty_field = $('form.cart').find('input.qty');
var price_html = $('.woocommerce-Price-amount.amount').first();
qty_field.on('change input', function() {
var qty = parseInt($(this).val());
if (qty && qty > 0) {
$.ajax({
url: wpfront_params.ajax_url,
type: 'POST',
data: {
action: 'wpfront_get_dynamic_price',
product_id: wpfront_params.product_id,
quantity: qty,
nonce: wpfront_params.nonce
},
success: function(response) {
if (response.success) {
price_html.html(response.data);
}
}
});
}
});
});3. Обработка ajax-запроса в PHP
Добавьте в functions.php следующий код:
function wpfront_get_dynamic_price() {
check_ajax_referer( 'wpfront_quantity_price_nonce', 'nonce' );
$product_id = intval( $_POST['product_id'] );
$quantity = intval( $_POST['quantity'] );
if ( ! $product_id || ! $quantity ) {
wp_send_json_error();
}
$product = wc_get_product( $product_id );
if ( ! $product ) {
wp_send_json_error();
}
$price = $product->get_regular_price();
// Правила скидок по количеству
if ( $quantity >= 10 ) {
$price = $price * 0.8; // 20% скидка
} elseif ( $quantity >= 5 ) {
$price = $price * 0.9; // 10% скидка
}
$total_price = $price * $quantity;
$formatted_price = wc_price( $total_price );
wp_send_json_success( $formatted_price );
}
add_action( 'wp_ajax_wpfront_get_dynamic_price', 'wpfront_get_dynamic_price' );
add_action( 'wp_ajax_nopriv_wpfront_get_dynamic_price', 'wpfront_get_dynamic_price' );Проверка результата после внедрения
- Откройте страницу товара в браузере.
- Измените количество товара в поле выбора количества.
- Обратите внимание, что цена подстраивается автоматически и отображается итоговая стоимость с учетом скидок.
- Проверьте консоль браузера на наличие ошибок JS или ajax-запросов.
Частые ошибки и способы их устранения
- Цена не меняется: Проверьте подключение JS, наличие ajax-обработчика, корректность селекторов в скрипте.
- Ajax-запросы возвращают ошибку 403: Убедитесь, что nonce передается и проверяется правильно.
- Цена отображается некорректно: Используйте функцию
wc_price()для форматирования цены, учитывайте валюту и локализацию. - Влияние на другие плагины: Тестируйте на чистой среде, чтобы исключить конфликты с другими скриптами.
Практические советы по производительности и безопасности
- Кешируйте результаты расчётов для популярных количеств, чтобы снизить нагрузку на сервер.
- Используйте
wp_localize_scriptдля передачи параметров AJAX, избегайте хардкода в JS. - Проверяйте и фильтруйте все входящие данные (quantity, product_id).
- Минимизируйте объем JS и запускайте его только на страницах товаров.
Сравнение вариантов реализации динамического изменения цены
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Код на AJAX (как в статье) | Обновление цены на лету без перезагрузки страницы | Гибкость, независимость от плагинов, полный контроль | Требует навыков JS и PHP, возможны конфликты с темой |
| Плагины для оптовых скидок | Готовые решения для скидок по количеству | Простота внедрения, поддержка | Могут быть тяжелыми, не всегда гибкие |
| Изменение цены через фильтры WooCommerce | Изменение цены при добавлении в корзину (без динамики на странице) | Простая реализация, работает на сервере | Цена не изменяется на странице товара |