Диагностика проблемы: почему нужно запретить изменение цены после заказа
В WooCommerce по умолчанию цена товара фиксируется на момент оформления заказа. Однако, при определённых сценариях, например, при ручном редактировании заказа в административной панели, цена может быть изменена, что нарушает бухгалтерскую отчётность и логику работы магазина.
Если вы столкнулись с ситуацией, когда администраторы или менеджеры случайно или намеренно изменяют цену товара в уже созданном заказе, это может привести к ошибкам в учёте и проблемам с клиентами.
Пошаговое решение: блокируем изменение стоимости товара в заказе через код
Мы реализуем запрет изменения цены на уровне административной панели WooCommerce, чтобы при редактировании заказа нельзя было вручную менять цену товаров.
Шаг 1. Отключение редактирования цены в админке
Добавьте следующий код в файл functions.php вашей дочерней темы или в плагин для кастомных функций:
add_filter('woocommerce_cart_item_price', 'lock_order_item_price_display', 10, 3);
add_filter('woocommerce_order_item_get_total', 'lock_order_item_price_get', 10, 2);
// Отключаем редактирование цены в админке
add_action('woocommerce_admin_order_item_headers', function() {
echo '<style>
.wc-order-item-price input {
pointer-events: none !important;
background: #eee !important;
}
</style>';
});Этот CSS-блок сделает поле цены для товаров в заказе неактивным, что предотвратит случайное редактирование.
Шаг 2. Защита от программного изменения цены
Для дополнительной защиты можно запретить обновление стоимости товара в заказе программно, например, при сохранении заказа в админке:
add_action('woocommerce_before_save_order_items', 'prevent_order_item_price_change', 10, 1);
function prevent_order_item_price_change($order_id) {
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_id => $item) {
$original_price = $item->get_meta('_original_product_price', true);
if ($original_price === '') {
// Сохраняем изначальную цену при первом сохранении
$item->update_meta_data('_original_product_price', $item->get_total() / $item->get_quantity());
$item->save();
} else {
// Восстанавливаем оригинальную цену, если была изменена
$current_price = $item->get_total() / $item->get_quantity();
if ($current_price != $original_price) {
$item->set_total($original_price * $item->get_quantity());
$item->save();
}
}
}
}Этот хук сохраняет изначальную цену товара при первом сохранении заказа и подменяет её обратно, если кто-то пытается изменить цену вручную.
Проверка результата после внедрения
- Перейдите в админку WooCommerce > Заказы и откройте любой существующий заказ.
- Попробуйте изменить цену товара — поле должно быть неактивным.
- Если попытаться изменить цену через разработческие инструменты браузера и сохранить заказ, цена автоматически вернётся к оригинальной.
- Создайте новый заказ и убедитесь, что цена сохраняется корректно и не может быть изменена позднее.
Частые ошибки и их исправление
- Цена доступна для редактирования: проверьте, что CSS действительно подключается. Иногда темы или плагины переопределяют стили админки.
- Цена не сохраняется при создании заказа: убедитесь, что хук
woocommerce_before_save_order_itemsсрабатывает. Иногда кеширование или плагины безопасности могут блокировать сохранение метаданных. - Изменения не применяются: очистите кеш браузера, а также кеш сайта, если он используется.
Практические советы по безопасности и производительности
- Не используйте плагины, которые позволяют массовое редактирование заказов без ограничений — лучше контролировать через кастомный код.
- Храните оригинальную цену в метаданных заказа — это поможет при аудите и восстановлении истории.
- Проверяйте права пользователей. Можно расширить код для разрешения изменения цены только администраторам с определёнными ролями.
Сравнение способов решения задачи
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Отключение редактирования через CSS | Блокирует поле цены в админке визуально | Простая реализация, быстро | Можно обойти через инспектор браузера |
| Запрет изменения цены в хуке сохранения | Программная проверка и восстановление оригинальной цены | Защита от обхода, надежно | Нужно писать и тестировать код, возможна нагрузка при большом количестве заказов |
| Использование плагинов для управления заказами | Плагины с ограничениями на редактирование цен | Готовое решение, GUI | Может быть избыточно, влияет на производительность, стоимость |