Проблема: необходимость автоматического обновления статуса заказа
В стандартном WooCommerce смена статуса заказа происходит вручную или автоматически по фиксированным событиям (оплата, возврат и т.д.). Однако часто возникает задача автоматически менять статус заказа спустя заданный промежуток времени, например, переводить заказ со статусом «в обработке» в «завершён» через 7 дней после оплаты. Это особенно актуально для цифровых товаров или сервисов с фиксированным сроком выполнения.
Диагностика задачи
Чтобы реализовать автоматическую смену статуса, нужно понимать:
- Какие заказы и на каком статусе требуют изменения
- Через какое время после определённого события менять статус
- Как избежать конфликтов с другими статусами и уведомлениями
WooCommerce не имеет встроенного функционала для отложенного изменения статуса, поэтому решение реализуется с помощью планировщика задач WP-Cron и кастомного кода.
Пошаговое решение: автоматическая смена статуса заказа через WP-Cron
1. Создаём функцию для смены статуса
function wplist_change_order_status_after_delay() {
$delay_days = 7; // Количество дней до смены статуса
$target_status_from = 'processing'; // Статус, с которого меняем
$target_status_to = 'completed'; // Новый статус
$args = array(
'limit' => -1,
'status' => $target_status_from,
'date_modified' => '<' . ( time() - $delay_days * DAY_IN_SECONDS ),
);
$orders = wc_get_orders( $args );
foreach ( $orders as $order ) {
// Проверяем дату оплаты
$paid_date = $order->get_date_paid();
if ( ! $paid_date ) {
continue;
}
$paid_timestamp = $paid_date->getTimestamp();
if ( $paid_timestamp <= ( time() - $delay_days * DAY_IN_SECONDS ) ) {
$order->update_status( $target_status_to, 'Статус автоматически изменён через 7 дней после оплаты' );
}
}
}2. Регистрируем WP-Cron задачу для регулярного запуска
function wplist_schedule_order_status_change() {
if ( ! wp_next_scheduled( 'wplist_daily_order_status_change' ) ) {
wp_schedule_event( time(), 'daily', 'wplist_daily_order_status_change' );
}
}
add_action( 'wp', 'wplist_schedule_order_status_change' );
add_action( 'wplist_daily_order_status_change', 'wplist_change_order_status_after_delay' );3. Удаление задачи при деактивации (если в плагине)
function wplist_clear_scheduled_order_status_change() {
$timestamp = wp_next_scheduled( 'wplist_daily_order_status_change' );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'wplist_daily_order_status_change' );
}
}Проверка результата после внедрения
- Создайте тестовый заказ и установите статус
processing. - Установите дату оплаты заказа вручную на дату более 7 дней назад в базе данных, например через phpMyAdmin (
wp_posts.post_dateи мета_paid_date). Это нужно для тестирования. - Запустите вручную крон-задачу:
do_action('wplist_daily_order_status_change');в консоли WP CLI или добавьте временный вызов функции. - Проверьте, что статус заказа изменился на
completed. - Проверьте историю заказов и уведомления, чтобы убедиться в отсутствии ошибок.
Частые ошибки и как исправить
- WP-Cron не запускается автоматически. Причина — отсутствие трафика на сайте или неправильная настройка сервера. Решение — настроить системный cron на запуск
wp-cron.phpили запускать задачи вручную для теста. - Заказы не меняют статус. Проверьте правильность условий в коде, особенно проверку даты оплаты. Логируйте ошибки через
error_log(). - Конфликт с другими плагинами, изменяющими статусы. Изолируйте проблему, отключая плагины, и корректируйте хуки.
Практические советы по производительности и безопасности
- Ограничьте выборку заказов в функции, чтобы не грузить базу, если много заказов. Вместо
limit = -1используйте постраничный запрос и запоминайте последний обработанный ID. - Используйте транзакции или проверки состояния заказа перед обновлением, чтобы избежать гонок данных.
- Добавляйте логирование действий в отдельный файл или системный лог для отладки.
- Для безопасности не давайте возможности запускать эту функцию через фронтенд — только WP-Cron или админские хуки.
Сравнение вариантов реализации автоматической смены статуса
| Вариант | Преимущества | Недостатки |
|---|---|---|
| WP-Cron + кастомный код | Гибко, без сторонних плагинов, полностью под контролем | Зависит от WP-Cron, может не сработать без трафика |
| Плагин для автоматизации статусов | Быстрая установка, GUI | Зависимость от стороннего кода, возможные конфликты, нагрузка |
| Ручное обновление через SQL запросы | Очень быстро для администраторов | Риск ошибок, не автоматизировано |