Диагностика задачи: зачем менять стоимость товаров при оплате
В ряде случаев требуется динамически корректировать цену товара в WooCommerce в момент оформления заказа. Например, при использовании определённых способов оплаты, промокодов или условий оплаты частями. Стандартных настроек WooCommerce для этого недостаточно — нужно вмешиваться в процесс расчёта стоимости через код.
Как работает изменение цены в WooCommerce при оформлении заказа
Основной механизм — фильтр woocommerce_product_get_price, который позволяет изменить цену товара на лету. Однако для правильной работы в корзине и на странице заказа нужно также корректно обновить стоимость в объектах WC_Product и учесть цену в сессии пользователя.
Особенности реализации
- Изменения должны применяться только при выбранном способе оплаты;
- Цена должна сохраняться при пересчёте корзины и не конфликтовать с кешированием;
- Правильное отображение цены в админке и письмах — отдельный момент, обычно там берётся базовая цена.
Пошаговое решение: пример кода для изменения цены при оплате через "Наличные"
Добавляем следующий код в файл functions.php вашей темы или в кастомный плагин:
add_filter('woocommerce_product_get_price', 'custom_price_by_payment_method', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_price_by_payment_method', 10, 2);
function custom_price_by_payment_method($price, $product) {
if (is_admin()) return $price; // не меняем в админке
// Проверяем выбранный способ оплаты в сессии
if (WC()->session) {
$chosen_payment = WC()->session->get('chosen_payment_method');
if ($chosen_payment === 'cod') { // 'cod' — код способа оплаты "Наличные"
// Уменьшаем цену на 10% при оплате наличными
$price = $price * 0.9;
}
}
return $price;
}
// Обновляем выбранный способ оплаты в сессии при выборе пользователем
add_action('woocommerce_checkout_update_order_review', 'update_chosen_payment_method');
function update_chosen_payment_method($posted_data) {
parse_str($posted_data, $output);
if (isset($output['payment_method'])) {
WC()->session->set('chosen_payment_method', sanitize_text_field($output['payment_method']));
}
}В этом коде мы изменяем цену товаров на 10% скидку при выборе оплаты наличными. Метод woocommerce_checkout_update_order_review вызывается при обновлении данных на странице оформления заказа и позволяет сохранить выбранный способ оплаты в сессии.
Проверка результата после внедрения
- Перейдите в корзину и на страницу оформления заказа;
- Выберите способ оплаты «Наличные»;
- Обратите внимание, что цены товаров пересчитываются с 10% скидкой;
- При смене способа оплаты на другой цена возвращается к стандартной;
- Проверьте, что в админке и письмах цена отображается без изменений (базовая).
Частые ошибки и как их исправить
- Цена не меняется при выборе оплаты: Проверьте, что сессия WooCommerce активна и код корректно сохраняет способ оплаты в сессии.
- Цена меняется и в админке или в письмах: Добавьте условие
if (is_admin()) return $price;чтобы исключить изменения там. - Конфликты с кешированием: Если используются плагины кеша, убедитесь, что корзина и страница оформления заказа не кешируются.
- Скидка не учитывается в итогах заказа: Проверьте, что вы меняете цену через фильтры
woocommerce_product_get_priceиwoocommerce_product_get_regular_price. Для сложных скидок стоит использоватьwoocommerce_cart_calculate_fees.
Практические советы по безопасности и производительности
- Не храните важные данные в сессии без проверки и фильтрации, используйте
sanitize_text_fieldпри сохранении. - Избегайте сложных вычислений в фильтрах цены — это может замедлить загрузку страницы оформления заказа.
- Для масштабируемых решений лучше использовать встроенную систему купонов и правил скидок WooCommerce.
- Если нужна поддержка множества способов оплаты с разными правилами, рассмотрите создание отдельного класса скидок с кешированием результатов.
Сравнение способов реализации изменения цены в WooCommerce
| Метод | Преимущества | Недостатки |
|---|---|---|
Фильтр woocommerce_product_get_price | Простая реализация, работает на фронтенде | Не меняет цену в админке, может конфликтовать с кешем |
Добавление сборов через woocommerce_cart_calculate_fees | Гибко добавляет скидки/наценки в корзину | Не меняет цену товара, влияет на итоговую сумму |
| Создание кастомного плагина скидок | Масштабируемость, удобное управление | Требует больше времени на разработку |