Диагностика проблемы: почему не меняется статус заказа при отмене оплаты
В стандартной настройке WooCommerce заказ, который не был оплачен, может оставаться в статусе on-hold или pending неопределённо долго. Это приводит к загромождению базы данных и неудобствам при учёте заказов. Часто пользователи хотят, чтобы такие заказы автоматически переходили в статус cancelled или failed после определённого таймаута. Без дополнительной настройки это не происходит.
Проверить проблему можно через админку WooCommerce: зайдите в Заказы и посмотрите заказ с неоплаченным статусом, который висит долго. Если он не меняет статус сам, значит нужна автоматизация.
Пошаговое решение: как автоматически менять статус заказа при отмене оплаты
1. Добавляем функцию для смены статуса неоплаченных заказов с таймаутом
Добавьте следующий код в файл functions.php вашей дочерней темы или в кастомный плагин:
function wpkey_auto_cancel_unpaid_orders() {
$args = array(
'limit' => -1,
'status' => array('pending', 'on-hold'),
'date_created' => '<' . ( time() - 60 * 60 * 24 ), // 24 часа назад
);
$orders = wc_get_orders($args);
foreach ( $orders as $order ) {
// Проверяем, оплачены ли они
if ( 'pending' === $order->get_status() || 'on-hold' === $order->get_status() ) {
$order->update_status('cancelled', 'Автоматическое отмена неоплаченного заказа после 24 часов');
}
}
}
// Запускаем каждый час через WP Cron
add_action('wpkey_hourly_order_cancel', 'wpkey_auto_cancel_unpaid_orders');
// Регистрируем cron задачу при активации темы/плагина
function wpkey_schedule_cron() {
if ( ! wp_next_scheduled( 'wpkey_hourly_order_cancel' ) ) {
wp_schedule_event( time(), 'hourly', 'wpkey_hourly_order_cancel' );
}
}
add_action('wp', 'wpkey_schedule_cron');
// Удаляем cron задачу при деактивации
function wpkey_clear_cron() {
$timestamp = wp_next_scheduled('wpkey_hourly_order_cancel');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpkey_hourly_order_cancel');
}
}2. Как проверить, что код работает
- Создайте тестовый заказ с оплатой «Оплата при получении» или другим способом, который оставляет заказ в статусе
pendingилиon-hold. - Измените дату создания заказа в базе данных на дату более 24 часов назад (через phpMyAdmin или WP CLI).
- Запустите cron вручную с помощью WP CLI:
wp cron event run wpkey_hourly_order_cancel. - Перейдите в админку WooCommerce и убедитесь, что статус заказа изменился на
cancelled.
Частые ошибки и как их исправить
- Крон не запускается: проверьте, включён ли WP Cron в настройках сервера. На некоторых хостингах нужно настроить системный cron, чтобы вызывать
wp-cron.php. - Заказы не меняют статус: проверьте правильность статусов в коде и что заказы действительно старше 24 часов (проверьте поле
date_createdв базе). - Код добавлен в неподходящее место: всегда используйте дочернюю тему или кастомный плагин, чтобы не потерять изменения при обновлении.
Практические советы по безопасности и производительности
- Используйте WP Cron, но если сайт большой, лучше настроить системный cron для стабильности.
- Обрабатывайте не слишком много заказов за раз, чтобы не перегружать сервер (в примере
limit => -1, можно поставить например 50). - Добавьте логирование действий, чтобы отслеживать автоматические отмены и быстро находить ошибки, например через функцию
error_log()или подключив сторонний логер.
Сравнение способов реализации автоматической отмены заказов
| Метод | Плюсы | Минусы | Пример кода / плагин |
|---|---|---|---|
| WP Cron с кастомным кодом | Полный контроль, нет зависимостей | Требует знаний PHP, настройка cron | Пример выше |
| Плагин автоматического управления заказами (например, WooCommerce Cancel Abandoned Order) | Простота установки, интерфейс | Может быть тяжеловесным, ограниченная кастомизация | Clearfy Pro для оптимизации |
| Использование сторонних сервисов и Webhook | Автоматизация с внешним контролем | Сложность настройки, зависит от внешних сервисов | Webhook WooCommerce + свой сервер |