Диагностика задачи: зачем менять стоимость товара после оплаты
В WooCommerce стандартный сценарий — итоговая стоимость заказа фиксируется при оформлении и не меняется после оплаты. Однако в ряде бизнес-задач возникает необходимость динамически корректировать стоимость товара уже после оплаты: например, учесть скидки по постоплате, добавить дополнительные услуги, пересчитать цену при изменении курса валют или учесть бонусы. Важно понимать, что прямое изменение стоимости товара после оплаты может влиять на отчёты и учёт.
Основные признаки необходимости изменения стоимости после оплаты:
- Заказ оплачен, но требуется корректировка цены для бухгалтерии;
- Нужно изменить цену в заказе без повторной оплаты;
- Необходимо интегрировать с внешними системами, рассчитывающими цену по факту;
- Требуется автоматизировать изменение стоимости для определённых статусов заказа.
Пошаговое решение: использование хука woocommerce_order_status_changed
Для изменения стоимости товара в заказе после оплаты оптимально использовать хук woocommerce_order_status_changed. Он срабатывает при смене статуса заказа, например, с processing на completed. Это позволяет своевременно вносить изменения.
Пример кода для изменения цены товара после оплаты:
add_action('woocommerce_order_status_changed', 'custom_change_order_item_price_after_payment', 10, 4);function custom_change_order_item_price_after_payment($order_id, $old_status, $new_status, $order) { if ($new_status === 'completed') { foreach ($order->get_items() as $item_id => $item) { // Получаем текущую цену товара в заказе $original_price = $item->get_subtotal() / $item->get_quantity(); // Логика изменения цены, например, уменьшаем на 10% $new_price = round($original_price * 0.9, 2); // Устанавливаем новую цену для позиции заказа $item->set_subtotal($new_price * $item->get_quantity()); $item->set_total($new_price * $item->get_quantity()); $item->save(); } // Пересчитываем итоги заказа $order->calculate_totals(); $order->save(); }}Объяснение:
- Хук срабатывает при смене статуса заказа.
- В примере скидка 10% применяется только при переводе в статус
completed. - Мы корректируем цену каждого товара, меняя subtotal и total у позиции.
- Пересчитываем итоговую стоимость заказа.
Как проверить, что решение сработало
- Оформите тестовый заказ с оплатой (например, через режим песочницы платежного шлюза).
- После смены статуса на completed проверьте детали заказа в админке WooCommerce — должна отобразиться скорректированная цена.
- Проверьте итоговую сумму заказа, она должна измениться согласно логике в коде.
- Если есть интеграция с внешними сервисами бухгалтерии, сверяйте данные с их учётом.
Частые ошибки и как их исправить
- Изменение цены не отображается: возможно, не вызван
$item->save()или$order->save(). Проверьте, что оба метода вызываются после изменения. - Цена меняется несколько раз: хук срабатывает при каждом изменении статуса. Добавьте дополнительную проверку, чтобы изменение происходило только один раз (например, проверять предыдущий статус).
- Итоговая сумма заказа не пересчитана: вызов
$order->calculate_totals()обязателен, иначе изменения не отразятся в итогах. - Конфликты с другими плагинами: некоторые плагины кэшируют цены или перезаписывают их после оплаты. В таком случае используйте хук с более высоким приоритетом или фильтруйте изменения.
Проверка и отладка
Для отладки вставьте error_log() или используйте плагин Query Monitor, чтобы убедиться, что функция срабатывает:
error_log('Изменение цены для заказа ID ' . $order_id);Проверьте логи сервера PHP для подтверждения выполнения кода.
Практические советы по безопасности и производительности
- Не изменяйте цены в заказах, если они уже были оплачены в реальной системе — это может привести к расхождениям в учёте.
- Сохраняйте исходные цены в мета данных заказа, если планируете динамические изменения, чтобы иметь возможность восстановить данные.
- Избегайте сложных и длительных операций в хуках, чтобы не замедлять процесс обработки заказа.
- Проверяйте права пользователя, если вносите изменения через пользовательский интерфейс.
Альтернативные подходы: плагин vs код
| Метод | Преимущества | Недостатки | Пример |
|---|---|---|---|
| Ручное изменение через админку | Простота, не требует кода | Невозможно автоматизировать, ошибки при масштабах | Редактирование позиции заказа вручную |
| Плагин для динамических цен | Готовое решение, поддержка | Может конфликтовать, требует настройки | WooCommerce Dynamic Pricing |
| Код на хуках (как в статье) | Гибкость, контроль, бесплатно | Требует навыков программирования, поддержка на разработчике | Пример в статье |