Диагностика проблемы с неоплаченными заказами
В WooCommerce бывает ситуация, когда заказ создаётся, но платеж не проходит — например, пользователь закрыл страницу оплаты или банк отказал в транзакции. Такие заказы остаются в статусе processing или on-hold, что мешает учёту и влияет на отчётность. Нужно автоматически отменять такие заказы через определённое время, чтобы не мусорить базу и не создавать путаницу.
Как определить заказы для автоматической отмены
- Заказы со статусом
processingилиon-hold; - Которые не были оплачены в течение X часов;
- У которых нет подтверждения платежа по вебхукам или API платёжной системы.
Проверка статуса оплаты заказа
Для корректной работы нужно проверить метаданные заказа, например, наличие транзакции или подтверждения оплаты (_payment_completed, _transaction_id и т.п.).
Пошаговое решение: создание функции отмены заказов через CRON
Ниже пример кода, который отменяет неоплаченные заказы старше 6 часов со статусом processing или on-hold:
function wppay_cancel_unpaid_orders() {
$hours = 6;
$statuses = array('processing', 'on-hold');
$args = array(
'limit' => -1,
'status' => $statuses,
'date_created' => '<' . ( new WC_DateTime( "-{$hours} hours" ) )->format( 'Y-m-d H:i:s' ),
);
$orders = wc_get_orders( $args );
foreach ( $orders as $order ) {
// Проверяем, есть ли подтверждение оплаты
$payment_completed = $order->get_meta('_payment_completed');
if ( ! $payment_completed ) {
$order->update_status( 'cancelled', 'Автоматическая отмена: неоплачен более 6 часов' );
}
}
}
// Регистрируем CRON задачу при активации темы или плагина
function wppay_schedule_cron() {
if ( ! wp_next_scheduled( 'wppay_cancel_unpaid_orders_hook' ) ) {
wp_schedule_event( time(), 'hourly', 'wppay_cancel_unpaid_orders_hook' );
}
}
add_action( 'wp', 'wppay_schedule_cron' );
add_action( 'wppay_cancel_unpaid_orders_hook', 'wppay_cancel_unpaid_orders' );
Объяснение кода
- Получаем заказы со статусом
processingиon-holdстарше 6 часов; - Проверяем мета-ключ
_payment_completed, который должен ставиться вашим платёжным плагином при успешном платеже; - Если оплаты нет, меняем статус заказа на
cancelledс комментарием; - CRON запускается каждый час.
Как проверить, что решение работает
- Создайте тестовый заказ и не завершайте оплату;
- Убедитесь, что заказ попадает в статус
processingилиon-hold; - Подождите 6 часов или измените условие времени в коде на 1 минуту для теста (например,
-1 minuteвместо-6 hours); - Запустите CRON вручную через WP-CLI:
wp cron event run wppay_cancel_unpaid_orders_hook; - Проверьте, что статус заказа изменился на
cancelled.
Частые ошибки и способы их исправления
- CRON-задача не запускается: убедитесь, что в WordPress включён WP-Cron, либо настройте системный CRON для вызова
wp-cron.php; - Метаданные оплаты не выставляются: проверьте, что платёжный плагин корректно устанавливает мета-ключ
_payment_completedили используйте другой уникальный признак успешной оплаты; - Не все заказы обрабатываются: убедитесь, что аргументы
wc_get_ordersкорректны, и статусы совпадают с теми, которые реально используются в магазине; - Отмена заказа приводит к ошибкам: проверьте, что нет конфликтов с другими плагинами, которые могут блокировать смену статуса.
Практические советы по безопасности и производительности
- Не увеличивайте слишком часто частоту CRON-задачи — достаточно 1 раз в час, чтобы не нагружать базу;
- Используйте индексы по дате создания заказа в базе данных для быстрого поиска;
- Для больших магазинов используйте пагинацию в
wc_get_ordersс параметрамиlimitиoffsetдля обработки заказов партиями; - Логируйте действия функции отмены заказов в отдельный файл для последующего аудита;
- Проверяйте, чтобы платёжный плагин корректно обрабатывал отмену заказа и не оставлял за собой незавершённые транзакции.
Сравнение способов реализации автоматической отмены заказов
| Способ | Описание | Плюсы | Минусы |
|---|---|---|---|
| CRON-задание через wp_schedule_event | Автоматический запуск функции отмены в WordPress | Простота, интеграция с WP | Зависит от WP-Cron, нагрузка на сайт при большом количестве заказов |
| Системный CRON + WP-CLI | Вызов скрипта через системные задачи сервера | Надёжность, стабильность | Требует доступа к серверу, знания CLI |
| Плагин для управления заказами | Готовые решения с интерфейсом | Удобство для пользователей без кода | Может быть ресурсозатратным и дорогим |