Диагностика проблемы: почему WooCommerce не принимает отрицательные цены
По умолчанию WooCommerce не позволяет устанавливать отрицательные значения цены для товаров. Это связано с внутренней валидацией и логикой расчёта стоимости корзины, где цена товара должна быть положительной или нулевой. Однако в ряде случаев, например, при возврате, кредитных скидках или специализированных промоакциях, может потребоваться возможность использовать отрицательные цены.
Если попытаться вручную выставить отрицательную цену в админке, WooCommerce не сохранит её, либо при оформлении заказа возникнут ошибки. Поэтому задача — обойти эти ограничения и корректно обработать отрицательные цены без нарушения логики работы магазина.
Пошаговое решение: включение и обработка отрицательных цен в WooCommerce
1. Разрешаем сохранение отрицательных цен
Первый шаг — отключить валидацию цены товара, которая не допускает отрицательных значений. Для этого добавим фильтр, который будет разрешать сохранение отрицательных цен.
add_filter('woocommerce_product_get_price', 'allow_negative_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'allow_negative_price', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'allow_negative_price', 10, 2);
function allow_negative_price($price, $product) {
return $price; // просто возвращаем цену, не изменяя
}
// Отключаем проверку валидации цены при сохранении
add_filter('woocommerce_product_validate_price', '__return_false');Фильтр woocommerce_product_validate_price не является стандартным, поэтому для отключения валидации придется использовать хук save_post_product и вручную исправлять ошибки валидации, либо напрямую обновлять мета поля цены через SQL или wp_update_post с мета.
2. Перезаписываем логику расчёта корзины для отрицательных цен
WooCommerce рассчитывает стоимость товаров и итоговую сумму, не ожидая отрицательных цен. Для корректной работы необходимо перехватить расчёты и убедиться, что отрицательные значения корректно учитываются.
add_action('woocommerce_before_calculate_totals', 'apply_negative_price_to_cart_item', 10, 1);
function apply_negative_price_to_cart_item($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
$price = $product->get_price();
if ($price < 0) {
$cart_item['data']->set_price($price);
}
}
}3. Обработка платежных шлюзов и отображение
Обратите внимание, что не все платежные шлюзы корректно обработают отрицательную итоговую сумму заказа. В таких случаях стоит предусмотреть отдельную логику либо выводить предупреждение клиенту.
Для корректного отображения цены на страницах товара и в заказах используйте фильтры:
add_filter('woocommerce_get_price_html', 'show_negative_price_html', 10, 2);
function show_negative_price_html($price_html, $product) {
$price = $product->get_price();
if ($price < 0) {
$price_html = '<span class="woocommerce-price-negative">- ' . wc_price(abs($price)) . '</span>';
}
return $price_html;
}Проверка результата после внедрения
- Создайте тестовый товар с отрицательной ценой через программное обновление мета-полей (прямо в базе или через wp-cli), например -100 руб.
- Добавьте товар в корзину и перейдите к оформлению заказа.
- Убедитесь, что сумма заказа корректно отображается с отрицательной стоимостью.
- Проверьте, что оформление заказа проходит без ошибок, либо выводится информативное предупреждение.
- Проверьте отображение отрицательной цены на странице товара, в списках и в админке WooCommerce.
Частые ошибки и как их исправить
Ошибка 1: Невозможно сохранить отрицательную цену в админке
WooCommerce по умолчанию блокирует отрицательные цены при сохранении. Решение — не менять цену через стандартный интерфейс, а использовать кастомный мета-бокс или обновлять цену программно через update_post_meta($product_id, '_price', $value) и аналогичные поля.
Ошибка 2: Итоговая сумма заказа некорректна или не отображается
Возможно, не добавлен хук woocommerce_before_calculate_totals, который применяет отрицательную цену к объекту товара в корзине. Проверьте, что хук подключён и корректно работает.
Ошибка 3: Платежный шлюз не принимает отрицательную сумму
Большинство платежных систем не поддерживают отрицательные платежи. В этом случае целесообразно реализовать отдельный тип возврата или кредитования, а не отрицательную цену товара. Можно блокировать оформление заказа с отрицательной суммой либо показывать предупреждение.
Практические советы для использования отрицательных цен в WooCommerce
- Используйте отрицательные цены только для внутренних операций, например, для возврата или учёта долгов, а не для публичной продажи.
- Разработайте отдельный интерфейс или мета-бокс для управления отрицательными ценами, чтобы не ломать стандартную логику WooCommerce.
- Проводите тщательное тестирование оформления заказа на всех используемых платежных шлюзах.
- Для безопасности ограничьте возможность выставлять отрицательные цены только администраторам или менеджерам.
- Используйте CSS для стилизации отрицательных цен, чтобы пользователь сразу понимал, что это особый случай.
Сравнение вариантов внедрения отрицательных цен
| Метод | Преимущества | Недостатки |
|---|---|---|
| Программное обновление мета-полей | Простой способ обойти валидацию, работает с любым товаром | Неудобно для менеджеров, требует доп. кода для отображения |
| Кастомный мета-бокс с разрешением отрицательных цен | Удобно для админов, можно контролировать ввод | Требует разработки интерфейса и обработки |
| Использование купонов и скидок вместо отрицательных цен | Совместимо с WooCommerce, не ломает логику | Может не подходить для всех сценариев |