Диагностика проблемы: зачем нужно менять статус заказа автоматически
В стандартном WooCommerce смена статуса заказа происходит вручную или по отдельным событиям, например, после оплаты или отправки. Но часто возникает задача автоматически менять статус заказа через определённое время, например, переводить 'в обработке' в 'завершён' спустя 7 дней, чтобы не держать старые заказы открытыми, или автоматически отменять неоплаченные заказы через 1 день.
Это полезно для автоматизации процессов, уменьшения ручной работы и повышения точности учёта заказов.
Как реализовать автоматическое изменение статуса заказа по времени в WooCommerce
Используем WP-Cron для запуска задачи по расписанию
Чтобы изменить статус заказа через заданный промежуток времени, нужно:
- Добавить мета-данные с датой создания заказа.
- Настроить WP-Cron задачу, которая периодически проверяет заказы с определённым статусом и меняет их, если прошло нужное время.
Пример кода для автоматической смены статуса 'processing' на 'completed' через 7 дней
function set_order_completed_after_seven_days() {
$args = array(
'status' => 'processing',
'limit' => -1,
'date_created' => '<' . ( new WC_DateTime( 'now -7 days' ) )->format( 'Y-m-d H:i:s' ),
);
$orders = wc_get_orders( $args );
foreach ( $orders as $order ) {
$order->update_status( 'completed', 'Статус автоматически изменён после 7 дней.' );
}
}
add_action( 'my_daily_order_status_change_event', 'set_order_completed_after_seven_days' );
// Регистрируем ежедневный крон
function register_daily_order_status_change_event() {
if ( ! wp_next_scheduled( 'my_daily_order_status_change_event' ) ) {
wp_schedule_event( time(), 'daily', 'my_daily_order_status_change_event' );
}
}
add_action( 'wp', 'register_daily_order_status_change_event' );Автоматическое удаление крон-задачи при деактивации плагина
function deactivate_order_status_plugin() {
$timestamp = wp_next_scheduled( 'my_daily_order_status_change_event' );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'my_daily_order_status_change_event' );
}
}
register_deactivation_hook( __FILE__, 'deactivate_order_status_plugin' );Проверка результата после внедрения
Чтобы убедиться, что автоматическая смена статуса работает:
- Создайте тестовый заказ и установите статус 'processing'.
- Измените дату создания заказа в базе данных на дату старше 7 дней для проверки (например, через phpMyAdmin или WP-CLI).
- Запустите WP-Cron вручную через плагин WP Crontrol или через WP-CLI:
wp cron event run my_daily_order_status_change_event. - Проверьте, что статус заказа изменился на 'completed'.
Частые ошибки и как их исправить
- Крон не запускается автоматически: Убедитесь, что на сервере посещения сайта происходят регулярно. Если сайт мало посещаем, настройте системный cron (через crontab) для запуска WP-Cron, например:
* * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1 - Заказы не меняют статус: Проверьте, что статус в запросе
'processing'указан корректно и что даты заказов действительно старше заданного периода. - Дублирование крон-задач: Используйте
wp_next_scheduledдля предотвращения повторной регистрации одного и того же события.
Практические советы по оптимизации и безопасности
- Для больших магазинов с тысячами заказов делайте выборку порциями (
'limit' => 100, с пагинацией) чтобы уменьшить нагрузку. - Добавляйте логи (например, через
error_log()) для отладки и мониторинга. - Используйте встроенные хуки WooCommerce, например,
woocommerce_order_status_changed, чтобы запускать дополнительные действия при смене статуса. - Если безопасность критична, ограничьте доступ к cron-запросам по IP или с помощью секретных ключей.
Сравнение вариантов реализации автоматической смены статуса заказа
| Метод | Плюсы | Минусы |
|---|---|---|
| WP-Cron + код | Гибко, нет плагинов, полностью под контролем | Зависит от посещаемости сайта, может быть нагрузка при большом количестве заказов |
| Плагины автоматизации (например, AutomateWoo) | Удобный интерфейс, дополнительные функции | Платные, дополнительная нагрузка, меньшая гибкость |
| Внешние cron-задачи + API | Надёжно, не зависит от посещаемости | Сложнее в настройке, нужен внешний сервер/хостинг |