Диагностика проблемы: зачем нужно удалять неоплаченные заказы
В WooCommerce неоплаченные заказы (статус "pending" или "failed") могут накапливаться и засорять базу данных, замедляя работу сайта и усложняя управление заказами. Чаще всего требуется их удалять автоматически через определённый промежуток времени, чтобы поддерживать порядок в админке и улучшать производительность магазина.
Однако простое автоматическое удаление может привести к случайной потере важных данных, если заказ всё же будет оплачен или обработан вручную. Поэтому рекомендовано добавлять этап подтверждения удаления, например, через email-уведомление или дополнительный фильтр.
Пошаговое решение: как реализовать автоматическое удаление с подтверждением
Шаг 1. Добавляем cron-задачу для поиска и удаления старых неоплаченных заказов
Для начала зарегистрируем собственное событие cron в WordPress, которое будет запускаться раз в сутки и удалять неоплаченные заказы старше заданного срока, например 3 дней.
add_action('wp', function() {
if (!wp_next_scheduled('custom_delete_unpaid_orders')) {
wp_schedule_event(time(), 'daily', 'custom_delete_unpaid_orders');
}
});
add_action('custom_delete_unpaid_orders', function() {
$args = [
'status' => ['pending', 'failed'],
'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) {
// Добавим сюда проверку подтверждения удаления
}
});Шаг 2. Добавляем механизм подтверждения удаления через мета-поле
Чтобы не удалять заказ сразу, создадим мета-поле deletion_confirmed. При первом запуске cron мы отправим email с запросом подтверждения удаления. Только после подтверждения заказ будет удалён.
Пример отправки email:
function send_deletion_confirmation_email($order) {
$to = get_option('admin_email');
$subject = 'Подтверждение удаления неоплаченного заказа #' . $order->get_id();
$confirm_link = add_query_arg([
'confirm_delete_order' => $order->get_id(),
'nonce' => wp_create_nonce('confirm_delete_order_' . $order->get_id())
], site_url('/'));
$message = "Здравствуйте,\n\nПожалуйста, подтвердите удаление неоплаченного заказа #" . $order->get_id() . ".\nДля подтверждения перейдите по ссылке: " . $confirm_link;
wp_mail($to, $subject, $message);
}В основной функции cron дополним код:
add_action('custom_delete_unpaid_orders', function() {
$args = [
'status' => ['pending', 'failed'],
'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) {
if (!$order->get_meta('deletion_confirmed')) {
send_deletion_confirmation_email($order);
// Помечаем, что запрос отправлен
$order->update_meta_data('deletion_confirmed', 'pending');
$order->save();
}
}
});Шаг 3. Обработка подтверждения по ссылке
Добавим обработчик для GET-параметров confirm_delete_order и nonce, который при проверке nonce пометит заказ как подтверждённый для удаления и удалит его.
add_action('init', function() {
if (!empty($_GET['confirm_delete_order']) && !empty($_GET['nonce'])) {
$order_id = intval($_GET['confirm_delete_order']);
$nonce = sanitize_text_field($_GET['nonce']);
if (wp_verify_nonce($nonce, 'confirm_delete_order_' . $order_id)) {
$order = wc_get_order($order_id);
if ($order && $order->get_meta('deletion_confirmed') === 'pending') {
$order->update_meta_data('deletion_confirmed', 'confirmed');
$order->save();
// Удаляем заказ
wp_delete_post($order_id, true);
wp_redirect(add_query_arg('delete_confirmed', '1', site_url('/')));
exit;
}
}
}
});Проверка результата после внедрения
- Проверьте, что cron-задача
custom_delete_unpaid_ordersзарегистрирована: в терминале WP-CLI выполнитеwp cron event list --search=custom_delete_unpaid_orders. - Создайте тестовый заказ в статусе
pending, старше 3 дней (можно вручную изменить дату через базу данных). - Запустите cron вручную:
wp cron event run custom_delete_unpaid_ordersи убедитесь, что на email администратора приходит письмо с запросом подтверждения. - Перейдите по ссылке из письма, чтобы подтвердить удаление. После этого заказ должен исчезнуть из админки WooCommerce.
- Если заказ не удалился, проверьте логи ошибок и nonce-параметры.
Частые ошибки и как их исправить
- Отсутствие cron-задачи: Убедитесь, что WordPress cron запущен и нет конфликтов с другими плагинами. Можно использовать реальные системные cron для точности.
- Письма не отправляются: Проверьте настройки SMTP и работоспособность функции
wp_mail(). Рекомендуется настроить SMTP через плагины типа WP Mail SMTP. - Nonce не проходит проверку: Убедитесь, что ссылка подтверждения не подвергается изменению при копировании и что nonce не истёк.
- Заказы не удаляются: Проверьте права пользователя, под которым выполняется скрипт, и убедитесь, что
wp_delete_postвызывается с параметромtrueдля полного удаления.
Практические советы по безопасности и производительности
- Используйте nonce и защищённые ссылки для подтверждения удаления, чтобы избежать случайного или злонамеренного удаления заказов.
- Регулярно проверяйте логи email и cron, чтобы своевременно выявлять неполадки.
- Для больших магазинов с высокой нагрузкой рекомендуем использовать системные cron вместо wp-cron, чтобы избежать задержек и пропусков задач.
- Не удаляйте заказы сразу, если они могут быть оплачены позже — подтверждение удаления снижает риск потерь.
- При необходимости можно интегрировать систему уведомлений с плагинами, например, Clearfy Pro для оптимизации работы сайта и управления задачами.
Сравнение вариантов реализации автоматического удаления
| Метод | Плюсы | Минусы | Рекомендуемые сценарии |
|---|---|---|---|
| Удаление без подтверждения (простой cron) | Простая реализация, не требует взаимодействия | Риск случайного удаления активных заказов | Магазины с малым количеством заказов, где задержки оплаты невозможны |
| Удаление с подтверждением по email (как в статье) | Максимальная безопасность, подтверждение действия администратором | Требует ручного подтверждения, возможна задержка удаления | Средние и крупные магазины с регулярными неоплаченными заказами |
| Использование плагинов автоматизации (например, WPShop решения) | Удобный интерфейс, расширенные функции | Зависимость от стороннего кода, возможные конфликты | Магазины без разработчиков, желающие быстрые решения |