Диагностика проблемы: почему WooCommerce создает заказ сразу при оформлении
По умолчанию WooCommerce создает запись заказа в базе данных сразу после перехода пользователя на страницу оформления заказа (checkout). Это делается для сохранения состояния корзины и упрощения процесса оплаты. Однако в некоторых случаях такое поведение нежелательно — например, если вы хотите избежать появления большого количества «пустых» заказов, которые так и не были оплачены или завершены. Такое бывает при интеграции с внешними системами или при необходимости более точного контроля над процессом заказа.
Проверить, что проблема именно в этом, можно так:
- Добавьте товар в корзину и перейдите на страницу оформления заказа.
- В базе данных (таблица
wp_postsс типомshop_order) появится новый заказ со статусомpendingилиfailed, даже если пользователь не завершил оплату.
Причина: автоматическое создание заказа в WooCommerce
Функция wc_create_order() вызывается в момент загрузки страницы оформления. WooCommerce фиксирует заказ для последующего обновления статусов и обработки платежей. Это стандартное поведение, изменить которое можно через фильтры и хуки.
Пошаговое решение: отключаем автоматическое создание заказа
1. Отключаем автоматическое создание заказа через фильтр
В WooCommerce с версии 3.0+ можно использовать фильтр woocommerce_checkout_create_order, чтобы предотвратить создание заказа на этапе загрузки страницы.
Добавьте следующий код в файл functions.php вашей темы или в отдельный плагин:
add_filter('woocommerce_checkout_create_order', function( $order, $data ) {
// Возвращаем false, чтобы отменить создание заказа на этапе загрузки
return false;
}, 10, 2);Однако данный фильтр не всегда адекватно работает, и WooCommerce может создавать заказ в других местах.
2. Используем более надежный способ — удаляем заказ из базы, если он «пустой»
Создадим функцию, которая при загрузке страницы оформления будет удалять заказы со статусом pending, которые старше 1 часа и не содержат оплату.
add_action('woocommerce_before_checkout_form', function() {
global $wpdb;
$time_limit = date('Y-m-d H:i:s', strtotime('-1 hour'));
// Получаем ID заказов со статусом pending старше часа
$orders = $wpdb->get_col($wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_status = 'wc-pending' AND post_date < %s",
$time_limit
));
foreach ($orders as $order_id) {
$order = wc_get_order($order_id);
if ($order && $order->get_total() == 0) {
wp_delete_post($order_id, true); // Полное удаление заказа
}
}
});3. Отключаем сохранение заказа в сессии до подтверждения
Можно попробовать отключить создание заказа в сессии, переопределив поведение класса WC_Checkout. Для этого напишем фильтр, который отменит создание заказа до момента подтверждения.
add_filter('woocommerce_create_order', '__return_null');Но этот способ нестабилен и может вызывать ошибки с оплатой и обработкой корзины. Рекомендуется тестировать отдельно.
Проверка результата после внедрения
- Добавьте товар в корзину и перейдите на страницу оформления.
- Проверьте таблицу
wp_postsна наличие заказов со статусомpending— новых заказов не должно создаваться сразу. - Завершите оформление заказа — заказ должен появиться с корректным статусом.
Частые ошибки и как исправить
Ошибка 1. Заказы не создаются вообще
Причина: слишком агрессивное отключение создания заказа (например, фильтр woocommerce_create_order возвращает null). Это нарушает логику оформления.
Как исправить: удалите или отключите этот фильтр, используйте мягкие методы очистки старых заказов.
Ошибка 2. Появляются «зависшие» заказы
Причина: удаление заказов происходит не вовремя или не для всех статусов.
Как исправить: расширьте логику удаления, например, учитывайте статусы failed, cancelled, а также увеличьте период проверки. Используйте WP-CLI для массового удаления.
Ошибка 3. Нарушение совместимости с платежными шлюзами
Причина: отключение создания заказа мешает работе плагинов оплаты, которые ожидают заказа в базе.
Как исправить: тестируйте изменения с конкретными шлюзами, либо делайте исключения для них по условию в коде.
Практические советы по производительности и безопасности
- Не удаляйте заказы сразу после создания, используйте отложенную очистку через WP-Cron или внешние cron-задачи.
- Всегда делайте резервные копии базы перед массовыми операциями удаления заказов.
- Логируйте удаление заказов для последующего анализа.
- При работе с заказами используйте стандартные API WooCommerce, а не прямые SQL-запросы, чтобы избежать ошибок и нарушений целостности данных.
Сравнение способов отключения автоматического создания заказа
| Метод | Плюсы | Минусы | Использование |
|---|---|---|---|
Фильтр woocommerce_checkout_create_order | Простой код | Не всегда срабатывает | Для легкой отмены создания заказа |
| Удаление «пустых» заказов через хук | Надежно очищает базу | Ресурсоемко при большом количестве заказов | Для поддержания базы в порядке |
Отключение через woocommerce_create_order | Полный запрет создания | Может сломать оплату | Экспериментальный, осторожно |