Диагностика проблемы: заказ WooCommerce не меняет статус после оплаты
Часто при интеграции WooCommerce с внешними платежными системами (например, Яндекс.Касса, Robokassa, PayPal) возникает ситуация, когда заказ остаётся в статусе on-hold или processing, хотя оплата уже прошла. Это мешает автоматизации обработки заказов и отправке уведомлений.
Причина обычно кроется в отсутствии корректной обработки webhook или callback уведомлений от платежной системы, либо в неправильном использовании хуков WooCommerce для смены статуса заказа.
Пошаговое решение: автоматическое изменение статуса заказа
1. Проверяем, как платежная система уведомляет сайт
Убедитесь, что ваша платежная система отправляет уведомления об успешной оплате на URL, который обрабатывается WooCommerce. Для большинства популярных шлюзов это уже настроено, но если вы используете кастомный шлюз — это нужно реализовать вручную.
2. Используем хук woocommerce_payment_complete для смены статуса
WooCommerce имеет встроенный хук woocommerce_payment_complete, который срабатывает при успешной оплате. На его основе можно принудительно менять статус заказа.
add_action('woocommerce_payment_complete', 'custom_change_order_status_after_payment');
function custom_change_order_status_after_payment($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
// Устанавливаем статус, например, completed
$order->update_status('completed', 'Статус изменён автоматически после оплаты');
}3. Альтернативно: обрабатывать webhook платежной системы
Если платежная система использует webhook, нужно в функции обработки webhook вызвать $order->payment_complete(), что триггерит смену статуса и дополнительные действия WooCommerce.
function handle_payment_webhook() {
$order_id = $_POST['order_id'] ?? 0;
if (!$order_id) wp_send_json_error('Order ID missing');
$order = wc_get_order($order_id);
if (!$order) wp_send_json_error('Order not found');
// Проверяем статус оплаты по данным webhook, здесь пример проверки
if ($_POST['payment_status'] === 'success') {
$order->payment_complete();
wp_send_json_success('Order status updated');
} else {
wp_send_json_error('Payment not successful');
}
}Проверка результата после внедрения
- Создайте тестовый заказ и оплатите через интегрированный шлюз.
- Перейдите в админку WooCommerce → Заказы и убедитесь, что статус заказа изменился на
completedили нужный вам. - При необходимости проверьте логи платежной системы и WooCommerce для подтверждения успешной обработки webhook.
Частые ошибки и как исправить
- Статус не меняется после оплаты: Проверьте, вызывается ли хук
woocommerce_payment_completeили корректно ли обрабатывается webhook. - Webhook не доходит до сайта: Проверьте URL webhook, настройки на стороне платежной системы и доступность сайта (отсутствие блокировок, SSL).
- Неправильный статус для типа товара: Для цифровых продуктов может быть полезнее устанавливать сразу
completed, для физических —processing. - Изменение статуса приводит к конфликтам с другими плагинами: Проверьте, не перезаписывает ли статус другой код, используйте приоритеты хуков.
Практические советы по безопасности и производительности
- Обязательно проверяйте подлинность webhook с помощью подписи или токена, чтобы избежать подделки запросов.
- Не меняйте статус заказа без проверки успешности оплаты, чтобы не допустить мошенничества.
- Добавляйте логирование изменений статусов заказов для быстрого обнаружения ошибок.
- Если обрабатываете webhook, используйте отдельный endpoint и минимизируйте время обработки, чтобы не тормозить сервер.
Сравнение подходов для смены статуса заказа
| Метод | Плюсы | Минусы | Пример кода |
|---|---|---|---|
Хук woocommerce_payment_complete |
Простая реализация, срабатывает на стандартных шлюзах WooCommerce | Не работает с нестандартными шлюзами без интеграции | add_action('woocommerce_payment_complete', 'function_name'); |
| Обработка webhook платежной системы | Гибкий, подходит для любых платежных систем | Сложнее реализовать, требует проверки безопасности | Функция, вызывающая $order->payment_complete() |
| Плагин для интеграции шлюза | Готовое решение, поддержка обновлений | Зависимость от стороннего кода, возможны конфликты | Зависит от плагина |