Диагностика задачи: зачем менять цену товара после оплаты
В стандартном WooCommerce цена товара фиксирована и определяется до оформления заказа. Однако бывают сценарии, когда необходимо изменить стоимость товара после оплаты: например, добавить скидку на следующий заказ, учесть бонусы или выполнить корректировку цены в зависимости от условий оплаты.
Без доработок WooCommerce не предоставляет встроенных инструментов для динамического изменения цены товара уже после оформления и оплаты заказа. В таких случаях необходимо внедрять кастомный код или использовать расширения.
Реализация автоматического изменения цены товара при оплате
Основное ограничение
Важно понимать, что конечная цена заказа фиксируется в метаданных заказа и не меняется после оплаты. Чтобы корректно изменить цену товара для будущих заказов, нужно обновлять цену товара в каталоге или добавлять динамические купоны/скидки.
Пошаговое решение: обновление цены товара после оплаты заказа
Рассмотрим пример, где после успешной оплаты заказа цена определённого товара уменьшается на 10%. Это может быть полезно для VIP клиентов или постоянных покупателей.
add_action('woocommerce_order_status_completed', 'custom_update_product_price_after_payment');
function custom_update_product_price_after_payment($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product) continue;
// Проверяем ID товара (пример: меняем только товар с ID 123)
if ($product->get_id() === 123) {
$old_price = floatval($product->get_regular_price());
$new_price = $old_price * 0.9; // скидка 10%
$product->set_regular_price($new_price);
$product->save();
}
}
}Этот код использует хук woocommerce_order_status_completed, который срабатывает при смене статуса заказа на "завершён" (оплачен). Для каждого товара в заказе проверяется ID и при совпадении цена обновляется.
Обновление цены с учётом пользовательских ролей
Если цена должна меняться только для определённых групп пользователей, можно добавить проверку роли покупателя:
add_action('woocommerce_order_status_completed', 'custom_update_price_for_vip_customers');
function custom_update_price_for_vip_customers($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
$user_id = $order->get_user_id();
if (!$user_id) return;
$user = get_userdata($user_id);
if (!$user) return;
if (in_array('vip_customer', (array) $user->roles)) {
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product) continue;
$old_price = floatval($product->get_regular_price());
$new_price = $old_price * 0.85; // скидка 15% для VIP
$product->set_regular_price($new_price);
$product->save();
}
}
}Проверка результата после внедрения
- Оформите тестовый заказ с товаром, ID которого указан в коде (например, 123).
- Оплатите заказ и убедитесь, что статус заказа сменился на «завершён».
- Перейдите в админку WooCommerce, откройте карточку товара и проверьте, изменилась ли цена на новую.
- Попробуйте оформить новый заказ с этим товаром — цена должна быть уже обновлена.
Частые ошибки и как их исправлять
- Цена не меняется после оплаты: проверьте, что заказ действительно получает статус
completed. В WooCommerce некоторые способы оплаты могут не менять статус автоматически. - Изменение цены затрагивает все пользователи: если требуется выборочная корректировка, добавьте проверку ролей или других условий.
- Цена возвращается к исходной при обновлении товара в админке: убедитесь, что нет плагинов или кэширования, которые перезаписывают цену.
- Ошибка при вызове методов продукта: проверьте, что объект
$productне равенnullи является экземпляромWC_Product.
Практические советы по безопасности и производительности
- Используйте хук
woocommerce_order_status_completed, а неwoocommerce_payment_complete, чтобы избежать проблем с неоплаченными заказами. - Обновление цен продуктов — это изменение в базе данных, избегайте частых массовых обновлений, чтобы не вызвать нагрузку.
- Кэшируйте результаты и очищайте кэш WooCommerce и сайта после изменений цены.
- Для сложных условий изменения цен рассмотрите использование динамических цен или плагинов типа Dynamic Pricing, если код становится громоздким.
Сравнение вариантов решения
| Вариант | Код | Плагин | Компромисс |
|---|---|---|---|
| Прямое изменение цены товара | + Быстрое, точное + Контроль через код | – | Цена меняется для всех, требует кастомного кода |
| Использование динамических скидок (купон или динамическая цена) | – | + Гибко + Нет изменений в товаре | Сложнее интеграция с логикой оплаты |
| Плагины динамического ценообразования | – | + Много функций + Поддержка | Платно, может быть избыточно |