Диагностика проблемы с неактивными заказами и оплатой в WooCommerce
В WooCommerce часто возникает ситуация, когда заказ создаётся, но пользователь не завершает оплату. Такие «висящие» заказы занимают ресурсы базы данных, создают путаницу в учёте и могут повлиять на аналитику и отчёты. В стандартной установке WooCommerce не реализована автоматическая отмена таких заказов и отключение возможности оплаты после определённого времени без активности.
Типичные признаки проблемы:
- Заказы в статусе
pendingилиon-holdвисят в админке по несколько дней; - Покупатели пытаются оплатить заказ спустя длительное время, и оплата проходит, хотя товар мог быть уже недоступен;
- Растёт количество неактивных заказов, что замусоривает отчёты и влияет на отчёты по остаткам на складах.
Пошаговое решение: автоматическое отключение оплаты по неактивным заказам
Реализуем скрипт, который через WP-Cron будет проверять заказы в статусе pending и если с момента создания прошло более 30 минут (настраиваемый таймаут), то переводить их в статус cancelled. Одновременно отключим возможность оплаты для таких заказов.
Шаг 1. Добавляем периодическое событие в WP-Cron
add_action('wp', 'setup_cancel_pending_orders_cron');
function setup_cancel_pending_orders_cron() {
if (!wp_next_scheduled('cancel_pending_orders_hook')) {
wp_schedule_event(time(), 'every_15_minutes', 'cancel_pending_orders_hook');
}
}
add_filter('cron_schedules', 'add_every_15_minutes_cron_schedule');
function add_every_15_minutes_cron_schedule($schedules) {
$schedules['every_15_minutes'] = array(
'interval' => 900, // 15 минут
'display' => __('Every 15 Minutes')
);
return $schedules;
}Шаг 2. Функция обработки и отмены старых заказов
add_action('cancel_pending_orders_hook', 'cancel_old_pending_orders');
function cancel_old_pending_orders() {
$timeout = 30 * MINUTE_IN_SECONDS; // 30 минут
$args = array(
'limit' => -1,
'status' => 'pending',
'date_created' => '<' . (time() - $timeout),
);
$orders = wc_get_orders($args);
foreach ($orders as $order) {
$order->update_status('cancelled', 'Автоматическая отмена неактивного заказа');
}
}Важно: Чтобы date_created работал корректно, нужно использовать параметр 'date_created' => '<' . (time() - $timeout) в формате ISO 8601. Если возникают сложности, можно фильтровать заказ вручную по дате создания.
Шаг 3. Отключаем возможность оплаты для отменённых заказов
По умолчанию, после смены статуса на cancelled оплата невозможна, но если на сайте есть кастомные решения, можно дополнительно блокировать оплату с помощью фильтра woocommerce_is_payment_required:
add_filter('woocommerce_is_payment_required', 'disable_payment_for_cancelled_orders', 10, 2);
function disable_payment_for_cancelled_orders($is_required, $order) {
if (is_a($order, 'WC_Order') && $order->has_status('cancelled')) {
return false;
}
return $is_required;
}Проверка результата после внедрения
- Создайте тестовый заказ и не завершайте оплату;
- Подождите 30 минут (можно уменьшить таймаут для теста до 1-2 минут);
- Проверьте в админке WooCommerce, что статус заказа изменился на
cancelled; - Попробуйте перейти по ссылке оплаты или повторить оплату — она должна быть отключена;
- Проверьте логи WP-Cron (например, с помощью плагина WP Crontrol), что событие сработало без ошибок.
Частые ошибки и как их исправить
- WP-Cron не срабатывает автоматически: на некоторых хостингах WP-Cron работает только при посещении сайта. Для надёжности настройте системный cron или используйте плагин WP Crontrol для контроля.
- Неправильный формат даты при запросе заказов: параметр
date_createdдолжен быть ISO8601-строкой, напримерdate('c', time() - $timeout). В противном случае запрос не сработает. - Статус заказа не меняется: проверьте, нет ли конфликтов с другими плагинами, которые блокируют смену статуса или изменяют логику заказов.
- Оплата доступна для отменённых заказов: убедитесь, что фильтр
woocommerce_is_payment_requiredподключён правильно и возвращает false для отменённых заказов.
Практические советы по безопасности и производительности
- Не устанавливайте слишком короткий таймаут для отмены заказов — клиенты могут просто не успеть оплатить;
- Добавьте логирование действий отмены заказов в файл или системные логи для аудита;
- Проверяйте нагрузку на базу — массовая обработка заказов может быть ресурсоёмкой, особенно при большом количестве;
- Вместо бесконечного получения всех заказов лучше обрабатывать их порциями, если заказов много;
- Обязательно тестируйте на копии сайта перед внедрением на рабочий магазин.
Сравнение вариантов решения
| Метод | Плюсы | Минусы |
|---|---|---|
| Плагин автоотмены заказов | Простота установки, готовый функционал, поддержка | Дополнитель нагрузка, возможные конфликты, лицензия |
| Кастомный код (как в статье) | Контроль, гибкость, минимум зависимостей | Требует навыков, нужно тестировать и поддерживать |
| Ручная отмена заказов через админку | Простота | Трудозатратно, риск забыть, неэффективно при большом объёме |