Диагностика задачи: зачем менять стоимость товара после оплаты
В WooCommerce стандартный процесс предполагает, что цена товара фиксирована на момент оформления заказа. Однако есть бизнес-сценарии, когда необходимо автоматически скорректировать стоимость после успешной оплаты — например, применить скидку за лояльность, начислить бонус, обновить цену для будущих заказов или зафиксировать цену в зависимости от динамического фактора.
Для реализации таких сценариев нужно вмешаться в логику WooCommerce после смены статуса заказа на «оплачен» и программно изменить стоимость товара или итоговую сумму заказа.
Как использовать хук woocommerce_order_status_completed для изменения стоимости
Хук woocommerce_order_status_completed срабатывает, когда статус заказа меняется на «завершён». В этот момент можно получить данные заказа, пройтись по товарам и изменить их цену.
Важно: изменить цену в заказе после оплаты — значит обновить метаданные заказа, а не товар в каталоге, иначе это повлияет на все будущие заказы.
Пример кода: изменение цены товара в заказе после оплаты
add_action('woocommerce_order_status_completed', 'change_order_item_prices_after_payment', 10, 1);
function change_order_item_prices_after_payment( $order_id ) {
$order = wc_get_order( $order_id );
foreach ( $order->get_items() as $item_id => $item ) {
// Получаем текущую цену
$old_price = $item->get_subtotal() / $item->get_quantity();
// Новая цена - например, скидка 10%
$new_price = $old_price * 0.9;
// Задаём новую цену для позиций заказа
$item->set_subtotal( $new_price * $item->get_quantity() );
$item->set_total( $new_price * $item->get_quantity() );
$item->save();
}
// Пересчитываем итоги заказа
$order->calculate_totals();
$order->save();
}Пошаговое решение задачи
- Подключитесь к серверу через FTP или используйте редактор тем/плагинов WordPress.
- Добавьте код из примера в файл
functions.phpактивной темы или создайте отдельный плагин для кастомных функций. - Измените логику в функции
change_order_item_prices_after_paymentпо вашим правилам — например, задайте другую формулу для новой цены или применяйте изменения только к определённым товарам. - Сохраните изменения и сделайте тестовый заказ в магазине, оплатив его.
- Проверьте в админке WooCommerce, что цена в заказе изменилась после перехода в статус «завершён».
Как проверить, что решение сработало
- Создайте тестовый заказ в WooCommerce с реальным или тестовым платежом.
- Оплатите заказ, дождитесь смены статуса на «завершён» (completed).
- В админке откройте заказ и проверьте цены позиций: они должны быть изменены согласно вашей логике.
- В личном кабинете пользователя тоже должны отображаться обновлённые суммы.
- Если итоговые суммы изменились — решение работает.
Частые ошибки и их исправление
- Изменение цены товара в каталоге вместо заказа: вызывайте методы изменения цены только у объекта
$itemзаказа, а не напрямую уWC_Product. Иначе цена товара изменится для всех покупателей. - Отсутствие вызова
$order->calculate_totals(): итоговые суммы заказа не обновятся, и стоимость не изменится визуально. - Изменение цены до смены статуса на completed: хук
woocommerce_order_status_completedсрабатывает после оплаты, раньше может быть неактуально. - Ошибки при сохранении заказа: всегда вызывайте
$item->save()и$order->save()после внесения изменений.
Практические советы по безопасности и производительности
- Безопасность: не меняйте цену товара в каталоге — это может привести к несоответствиям и проблемам с учётом.
- Проверяйте права пользователя и валидность
$order_idв функции, чтобы не менять чужие заказы или невалидные данные. - Оптимизация: избегайте сложных запросов и операций в хуке, если у вас большой магазин, чтобы не замедлять обработку заказов.
- Логируйте изменения цен для отладки и аудита, например, с помощью
error_log()или пользовательских логов.
Сравнение методов изменения цены после оплаты
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Изменение цены в заказе через хук | Меняем цену только в объекте заказа после оплаты | Безопасно для каталога, гибко на заказ | Не влияет на цены других заказов |
| Изменение цены товара программно | Меняем цену в WC_Product | Влияет на все заказы, удобно для акций | Риск ошибок, влияет на все покупателей |
| Использование плагинов скидок и купонов | Добавляем скидку через стандарт WooCommerce | Простота, поддержка | Меньшая гибкость, зависит от плагина |