Диагностика проблемы с неподтверждёнными заказами и способами оплаты
В WooCommerce часто возникает ситуация, когда клиенты создают заказы, но не завершают оплату. При этом способы оплаты остаются активными, что может приводить к ошибкам в процессе оформления или повторным попыткам оплаты по одному и тому же заказу. В результате пользователь видит способы оплаты, которые должны быть временно заблокированы, чтобы избежать дублирования оплаты и путаницы.
Проверить наличие проблемы можно, просмотрев список заказов в админке WooCommerce и отфильтровав их по статусу on-hold или pending. Если таких заказов много и они долго не меняют статус, логично ограничить доступ к способам оплаты для заказчиков с такими заказами.
Пошаговое решение: как отключить способы оплаты при неподтверждённых заказах
1. Определение неподтверждённых заказов пользователя
Для начала нам нужно проверить, есть ли у текущего пользователя заказы в статусах pending или on-hold. Если есть — отключаем способы оплаты.
2. Фильтрация доступных способов оплаты через хук woocommerce_available_payment_gateways
Добавим в файл functions.php вашей дочерней темы или в собственный плагин следующий код:
add_filter('woocommerce_available_payment_gateways', 'disable_payment_methods_for_unconfirmed_orders');
function disable_payment_methods_for_unconfirmed_orders($available_gateways) {
if (!is_user_logged_in()) {
return $available_gateways; // не меняем для гостей
}
$user_id = get_current_user_id();
// Получаем заказы пользователя со статусом pending или on-hold
$args = array(
'customer_id' => $user_id,
'status' => array('pending', 'on-hold'),
'limit' => 1
);
$orders = wc_get_orders($args);
if (!empty($orders)) {
// Отключаем все способы оплаты
return array();
}
return $available_gateways;
}3. Дополнительная настройка: вывод сообщения пользователю
Чтобы пользователь видел, почему способы оплаты недоступны, выведите уведомление. Добавьте в functions.php следующий код:
add_action('woocommerce_before_checkout_form', 'show_payment_disabled_message');
function show_payment_disabled_message() {
if (!is_user_logged_in()) {
return;
}
$user_id = get_current_user_id();
$args = array(
'customer_id' => $user_id,
'status' => array('pending', 'on-hold'),
'limit' => 1
);
$orders = wc_get_orders($args);
if (!empty($orders)) {
wc_print_notice('У вас есть неподтверждённые заказы. Новые оплаты временно недоступны, пока предыдущие заказы не будут завершены.', 'error');
}
}Проверка результата после внедрения
- Залогиньтесь под пользователем, у которого есть неподтверждённые заказы (статус
pendingилиon-hold). - Перейдите на страницу оформления заказа (checkout).
- Убедитесь, что способы оплаты не отображаются, а выводится сообщение о блокировке оплаты.
- Залогиньтесь под пользователем без неподтверждённых заказов и проверьте, что способы оплаты доступны.
- Также проверьте гостевой режим — способы оплаты должны быть доступны, если не внедрена другая логика.
Частые ошибки и как исправить
- Способы оплаты не отключаются: проверьте, что функция
wc_get_ordersвозвращает заказы, используйте отладкуerror_log(print_r($orders, true));для диагностики. - Сообщение не выводится: убедитесь, что хук
woocommerce_before_checkout_formподключен и код находится в активном файле. - У гостя оплата отключена: проверьте условие
is_user_logged_in()в коде, чтобы исключить гостей. - Блокировка слишком жёсткая: можно добавить дополнительную проверку по дате заказа, например, отключать способы оплаты только если заказ старше 1 часа.
Практические советы по безопасности и производительности
- Используйте
limit => 1в запросах, чтобы снизить нагрузку на базу данных. - Не храните большие объёмы данных в сессии для проверки статуса заказов, используйте запросы по необходимости.
- Если сайт с большим количеством заказов, кешируйте результаты проверки статуса на 5-10 минут, чтобы избежать частых запросов к базе.
- Для сайтов с гостевой оплатой можно дополнительно расширить логику, например, по IP или сессии, чтобы ограничить повторные попытки оплаты.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы |
|---|---|---|
| Плагин сторонний | Быстрое решение, поддержка обновлений | Может влиять на производительность, лишний функционал |
| Код в functions.php | Полный контроль, минимальная нагрузка | Требует навыков, нужно поддерживать самостоятельно |
| Автоматическая очистка неподтверждённых заказов | Уменьшение нагрузки, автоматизация | Риск удаления нужных заказов, требует тестирования |