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

Диагностика задачи: зачем менять стоимость товара по дисконным кодам

В WooCommerce стандартная система купонов позволяет назначить скидку на корзину или отдельные товары, но иногда требуется более гибкое решение — например, менять цену товара динамически при вводе определенного дисконтного кода, влияя на отображаемую стоимость прямо на странице товара и в корзине. Это полезно для закрытых акций, персональных предложений или уникальных скидок для определенных клиентов.

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

1. Создаем пользовательское поле для ввода дисконтного кода

Добавим на страницу товара поле для ввода дисконтного кода с помощью хука woocommerce_before_add_to_cart_button:

add_action('woocommerce_before_add_to_cart_button', function() {
    echo '<label for="discount_code">Дисконный код:</label>';
    echo '<input type="text" id="discount_code" name="discount_code" placeholder="Введите код скидки" />';
});

2. Обработка дисконтного кода при добавлении товара в корзину

Для передачи введенного кода в корзину и изменения цены используем хук woocommerce_add_cart_item_data, а для изменения цены — хук woocommerce_before_calculate_totals:

add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id) {
    if (!empty($_POST['discount_code'])) {
        $cart_item_data['discount_code'] = sanitize_text_field($_POST['discount_code']);
        // Добавим уникальный ключ, чтобы товары с разными кодами не сливались
        $cart_item_data['unique_key'] = md5(microtime() . rand());
    }
    return $cart_item_data;
}, 10, 3);

add_action('woocommerce_before_calculate_totals', function($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    foreach ($cart->get_cart() as $cart_item) {
        if (isset($cart_item['discount_code'])) {
            $code = $cart_item['discount_code'];
            // Здесь проверяем код и задаем новую цену
            if ($code === 'SPECIAL10') {
                $discounted_price = $cart_item['data']->get_regular_price() * 0.9; // 10% скидка
                $cart_item['data']->set_price($discounted_price);
            } elseif ($code === 'VIP20') {
                $discounted_price = $cart_item['data']->get_regular_price() * 0.8; // 20% скидка
                $cart_item['data']->set_price($discounted_price);
            }
            // Добавьте дополнительные коды по необходимости
        }
    }
});

3. Отображение дисконтного кода в корзине и оформлении заказа

Чтобы покупателю было видно, что цена изменена по дисконтному коду, добавим отображение кода в списке товаров корзины:

add_filter('woocommerce_get_item_data', function($item_data, $cart_item) {
    if (!empty($cart_item['discount_code'])) {
        $item_data[] = array(
            'key' => 'Дисконный код',
            'value' => esc_html($cart_item['discount_code'])
        );
    }
    return $item_data;
}, 10, 2);

Проверка результата после внедрения

  • Перейдите на страницу товара, введите один из заданных дисконтовых кодов (например, SPECIAL10 или VIP20) и добавьте товар в корзину.
  • В корзине цена товара должна измениться согласно заданной скидке, а под названием товара отобразится дисконтный код.
  • При оформлении заказа в деталях заказа также должен отображаться дисконтный код для каждого товара.

Частые ошибки и как исправить

  • Цена не меняется в корзине: проверьте, что функция изменения цены подключена к woocommerce_before_calculate_totals и что в ней нет ошибок. Также убедитесь, что условие проверки кода корректно.
  • Товары с разными кодами сливаются в корзине: для решения используйте уникальный ключ в данных корзины (unique_key), как показано в примере — это предотвратит объединение позиций.
  • Дисконный код не передается из формы: убедитесь, что поле ввода имеет атрибут name="discount_code" и что данные передаются через POST.
  • Цена меняется для всех товаров: проверьте, что скидка применяется только к товарам с установленным дисконтным кодом.

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

  • Используйте sanitize_text_field для обработки пользовательского ввода дисконтного кода, чтобы избежать XSS-уязвимостей.
  • Если кодов много и они регулярно меняются, храните их в отдельной таблице или опции, а не прописывайте в коде.
  • Для более сложной логики скидок используйте фильтр woocommerce_cart_calculate_fees, если нужно добавить фиксированную скидку или сбор.
  • Избегайте изменения цены товара глобально — меняйте цену только в объекте товара в корзине, чтобы не влиять на данные в базе.

Сравнение вариантов реализации

МетодПреимуществаНедостатки
Использовать стандартные купоны WooCommerceПростая настройка, интеграция с отчетамиМеньше гибкости, нельзя менять цену на странице товара
Изменять цену через woocommerce_before_calculate_totals по пользовательскому кодуГибкость, можно менять цену на летуТребует кастомного кода, сложнее поддерживать
Плагины для динамических скидокМного функций и удобный интерфейсЧасто платные, могут влиять на производительность
WooCommerce: автоматическое изменение стоимости товара по условиям корзины
09.07.2026
Оптимизация базы данных WordPress: практические советы и примеры кода
15.12.2025
Как автоматизировать рассылку новостей в WordPress
17.02.2026
WooCommerce: как добавить собственное поле в форму оформления заказа
05.06.2026
WooCommerce: как изменить стоимость товара в зависимости от количества в корзине
17.06.2026