Почему нужно автоматизировать изменение статуса заказа
В интернет-магазинах на WooCommerce часто возникает задача автоматически менять статус заказов по истечении определенного времени — например, переводить неоплаченные заказы в статус отмененных, или подтверждать доставленные заказы после определенного срока. Ручное обновление неудобно и может привести к ошибкам.
Диагностика проблемы: как понять, что автоматизация нужна
Если вы замечаете, что заказы долго висят в статусах pending или processing без изменений, и это мешает аналитике или блокирует товар на складе, значит пора автоматизировать процесс. Также важно выявить, какие именно статусы должны меняться, и через сколько времени.
Пример задачи
- Заказы со статусом
pending(ожидание оплаты) должны автоматически отменяться через 3 дня. - Заказы со статусом
completedдолжны автоматически переходить в статусarchived(псевдостатус, его можно реализовать через мета или тег) через 30 дней.
Решение: как реализовать автообновление статусов заказов по срокам
Для решения используем WP-Cron и стандартные функции WooCommerce. Ниже пример кода, который нужно добавить в functions.php вашей темы или в отдельный плагин.
<?php
// Планируем задачу при активации темы/плагина
add_action('wp', 'wc_schedule_order_status_update');
function wc_schedule_order_status_update() {
if (!wp_next_scheduled('wc_auto_update_order_status_hook')) {
wp_schedule_event(time(), 'daily', 'wc_auto_update_order_status_hook');
}
}
// Хук для выполнения задачи
add_action('wc_auto_update_order_status_hook', 'wc_auto_update_order_status');
function wc_auto_update_order_status() {
// Отмена заказов со статусом pending старше 3 дней
$args = [
'status' => 'pending',
'date_created' => '<' . (new WC_DateTime('-3 days'))->format('Y-m-d H:i:s'),
'limit' => -1,
];
$orders = wc_get_orders($args);
foreach ($orders as $order) {
$order->update_status('cancelled', 'Автоматическая отмена после 3 дней ожидания оплаты');
}
// Перевод completed в archived (через мета) старше 30 дней
$args2 = [
'status' => 'completed',
'date_created' => '<' . (new WC_DateTime('-30 days'))->format('Y-m-d H:i:s'),
'limit' => -1,
];
$completed_orders = wc_get_orders($args2);
foreach ($completed_orders as $order) {
// Добавим мета, имитирующую архивный статус
$order->update_meta_data('_archived_order', 'yes');
$order->save();
}
}
// Фильтр для отображения "архивных" заказов в админке (опционально)
add_filter('woocommerce_my_account_my_orders_query', 'wc_filter_archived_orders');
function wc_filter_archived_orders($args) {
// Убираем заказы с мета _archived_order = yes из списка
$args['meta_query'][] = [
'key' => '_archived_order',
'compare' => 'NOT EXISTS'
];
return $args;
}
?>Как проверить, что автообновление работает
- Проверьте в базе данных таблицу
wp_postsиwp_postmeta, что у заказов со статусомpending, созданных более 3 дней назад, статус изменился наcancelled. - Заказы со статусом
completed, созданные более 30 дней назад, должны иметь мета_archived_orderсо значениемyes. - В админке WooCommerce заказы с мета
_archived_orderне отображаются в списке по фильтру (если включен фильтр). - Для тестирования можно изменить время в коде на меньший промежуток (например, '-1 hour') и запустить
wp cron event run --due-nowчерез WP-CLI.
Частые ошибки и как их исправить
- Крон не срабатывает: Убедитесь, что на сайте включены WP Cron и нет конфликтов с плагинами кэширования или серверными настройками. Для проверки запустите
wp cron event run --due-nowвручную. - Заказы не обновляются: Проверьте правильность условий выборки заказов в
wc_get_orders, особенно параметрыdate_createdиstatus. - Проблемы с метаданными: Если не сохраняется мета, убедитесь, что вызываете
$order->save();после установки мета данных. - Отображение архивных заказов: Фильтр
woocommerce_my_account_my_orders_queryможет конфликтовать с другими плагинами — проверяйте совместимость.
Практические советы по производительности и безопасности
- При большом количестве заказов разбивайте выборку на части (пагинация) чтобы не перегружать память и время выполнения.
- Для надежности запуска задач используйте системный cron вместо WP Cron на высоконагруженных сайтах.
- Сохраняйте резервные копии базы перед массовыми изменениями статусов.
- Ограничьте права доступа к коду и админке, чтобы предотвратить несанкционированные изменения статусов.
Таблица сравнения вариантов реализации
| Метод | Преимущества | Недостатки | Рекомендации |
|---|---|---|---|
| WP-Cron + wc_get_orders | Простота реализации, не требует сторонних плагинов | Зависит от активности сайта, может не сработать вовремя | Использовать на средних и небольших сайтах |
| Системный cron + кастомный скрипт | Надежность, точное расписание | Требует доступа к серверу, более сложная настройка | Рекомендуется для крупных магазинов |
| Плагины автоматизации (например WP All Import/Export) | Графический интерфейс, дополнительные функции | Могут быть платными, нагрузка на сайт | Если нужна сложная логика без кода |