Проблема: Заказы не меняют статус автоматически после успешного платежа
В WooCommerce часто возникает ситуация, когда платежи обрабатываются вне стандартных платежных шлюзов или через кастомные методы, и статус заказа остаётся прежним, например, "Ожидает оплаты". Это приводит к путанице в учёте и задержкам в отгрузке.
Диагностика проблемы
Первым делом нужно проверить, как именно обрабатываются статусы заказов после оплаты:
- Используется ли стандартный шлюз оплаты WooCommerce или кастомный?
- Отправляет ли платежная система webhook или callback для обновления статуса?
- Есть ли в коде обработчики событий
woocommerce_payment_completeили аналогичные хуки?
Для проверки можно добавить простой лог в functions.php:
add_action('woocommerce_payment_complete', function($order_id) {
error_log('Оплата завершена для заказа #' . $order_id);
});Если сообщений в логах нет, значит событие не срабатывает, и нужно искать альтернативные методы обновления статуса.
Пошаговое решение: автоматическое изменение статуса заказа
1. Использование хука woocommerce_order_status_changed для отслеживания статуса
Этот хук срабатывает при изменении статуса заказа. Можно использовать его для запуска кастомной логики:
add_action('woocommerce_order_status_changed', function($order_id, $old_status, $new_status) {
if ($new_status === 'processing') {
// Ваш код при переходе в статус processing
}
}, 10, 3);2. Принудительное обновление статуса после получения подтверждения платежа
Если вы получаете Webhook от платежной системы, то можно программно обновить статус:
$order = wc_get_order($order_id);
if ($order && $order->get_status() === 'pending') {
$order->update_status('processing', 'Статус обновлен автоматически после подтверждения платежа');
}3. Пример обработчика webhook для PayPal или другой системы
Пример упрощённого обработчика webhook, который меняет статус заказа после успешной оплаты:
add_action('init', function() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['webhook']) && $_GET['webhook'] === 'payment') {
$order_id = intval($_POST['order_id']);
$payment_status = sanitize_text_field($_POST['payment_status']);
if ($payment_status === 'completed') {
$order = wc_get_order($order_id);
if ($order && $order->get_status() === 'pending') {
$order->update_status('processing', 'Оплата подтверждена через webhook');
wp_send_json_success('Статус обновлен');
} else {
wp_send_json_error('Заказ не найден или статус не требует обновления');
}
} else {
wp_send_json_error('Платеж не завершен');
}
exit;
}
});Проверка результата после внедрения
Чтобы удостовериться, что автоматическое изменение статусов работает:
- Отправьте тестовый заказ с ожидающим статусом.
- Симулируйте успешный платеж (например, через webhook или вручную вызовите код).
- Проверьте в административной панели WooCommerce, изменился ли статус заказа на
processingили нужный вам. - Проверьте логи сервера или включите плагин Debug Bar для отладки.
Частые ошибки и как их исправить
- Хук
woocommerce_payment_completeне срабатывает: возможно, платежная система не интегрирована с WooCommerce или используется кастомный метод оплаты. Решение — добавить свой обработчик webhook. - Статус меняется, но пользователь не видит изменений: проверьте кэширование сайта и браузера, отключите кэш для страниц заказа.
- Обработчик webhook не вызывается: проверьте, доступен ли URL для внешних запросов, нет ли блокировок на сервере (firewall, .htaccess).
- Ошибка при обновлении статуса: убедитесь, что $order существует и вы используете правильные статусы (например, 'processing', 'completed', а не 'paid').
Практические советы по безопасности и производительности
- Всегда проверяйте и валидируйте входящие данные из webhook, чтобы избежать уязвимостей.
- Используйте nonce или секретные ключи для подтверждения подлинности запросов.
- Минимизируйте работу в хуках, чтобы не замедлять обработку запросов.
- Для крупных магазинов используйте очередь задач (WP Cron или внешние сервисы) для асинхронной обработки обновлений статусов.
Сравнение вариантов решения
| Метод | Преимущества | Недостатки | Когда применять |
|---|---|---|---|
Хук woocommerce_payment_complete | Стандартный, простой в реализации | Не работает с кастомными платежами | При использовании стандартных шлюзов |
| Обработка webhook | Гибкость, работает с любыми платежами | Требует настройки внешних запросов и безопасности | Кастомные или сторонние платежные системы |
| Ручное обновление статуса через админку | Простота | Не автоматизировано, риск ошибок | Малые магазины без сложной интеграции |