Диагностика проблемы с неподтверждёнными заказами и способами оплаты
В WooCommerce иногда возникает ситуация, когда способы оплаты остаются активными для пользователей, у которых есть неподтверждённые (например, ожидающие оплаты) заказы. Это может привести к путанице, повторным оплатам или конфликтам в логике оформления заказа. Чтобы избежать этого, необходимо автоматически отключать определённые способы оплаты, если у пользователя уже есть неподтверждённые заказы.
Проверить наличие проблемы можно следующим образом:
- Зайдите под учётной записью пользователя, сделайте заказ и оставьте его в статусе «Ожидание оплаты» или «В обработке» без подтверждения.
- Попробуйте снова оформить заказ — проверьте, доступны ли все способы оплаты.
- Если способы оплаты не должны быть доступны, а они видны, значит проблема актуальна.
Пошаговое решение: как отключить способы оплаты при неподтверждённых заказах
1. Определяем неподтверждённые заказы пользователя
Для начала создадим функцию, которая проверит наличие неподтверждённых заказов с определёнными статусами у текущего пользователя.
function has_unconfirmed_orders( $user_id ) {
if ( ! $user_id ) {
return false;
}
$args = array(
'customer_id' => $user_id,
'status' => array('pending', 'on-hold', 'failed'), // статусы неподтверждённых заказов
'limit' => 1,
'return' => 'ids',
);
$orders = wc_get_orders( $args );
return ! empty( $orders );
}
2. Отключаем способы оплаты через фильтр woocommerce_available_payment_gateways
Используем фильтр WooCommerce, чтобы при наличии неподтверждённых заказов пользователя убрать один или несколько способов оплаты из списка доступных:
add_filter( 'woocommerce_available_payment_gateways', 'disable_payment_gateways_for_unconfirmed_orders' );
function disable_payment_gateways_for_unconfirmed_orders( $available_gateways ) {
if ( ! is_user_logged_in() ) {
return $available_gateways;
}
$user_id = get_current_user_id();
if ( has_unconfirmed_orders( $user_id ) ) {
// Перечислите ID способов оплаты, которые нужно отключить
$disabled_gateways = array('cod', 'bacs'); // Пример: оплата при получении и банковский перевод
foreach ( $disabled_gateways as $gateway_id ) {
if ( isset( $available_gateways[ $gateway_id ] ) ) {
unset( $available_gateways[ $gateway_id ] );
}
}
}
return $available_gateways;
}
Как проверить, что решение работает
- Создайте тестового пользователя и войдите под ним.
- Оформите заказ, оставьте его в статусе «Ожидание оплаты» (pending) или «В обработке» (on-hold).
- Попробуйте оформить новый заказ — указанные способы оплаты должны отсутствовать.
- Измените статус заказа на «Завершён» или «Отменён» и проверьте, что способы оплаты вновь появились.
Частые ошибки и как их исправлять
- Неверный ID способов оплаты в массиве
$disabled_gateways. Проверьте ID в WooCommerce в разделе настроек платежей. Ошибка приведёт к тому, что способы оплаты не отключатся. - Проверка пользователя не срабатывает для гостей. В коде учтена проверка
is_user_logged_in(), для гостей отключение не работает. При необходимости реализуйте отдельную логику для гостей. - Статусы заказов не соответствуют бизнес-логике. Убедитесь, что в массиве статусов
array('pending', 'on-hold', 'failed')перечислены именно те, которые для вас означают неподтверждённые заказы. - Кэширование страниц мешает обновлению способов оплаты. Проверьте плагины кэширования и кеш браузера, отключите на время тестирования.
Практические советы по оптимизации и безопасности
- Используйте
wc_get_ordersс ограничением'limit' => 1, чтобы не нагружать базу лишними запросами. - Отключение способов оплаты лучше делать на уровне PHP, чтобы исключить возможность обхода через JS.
- Если используете кэширование, исключите страницы оформления заказа из кеша.
- Для более гибкой настройки можно добавлять в массив отключаемых способов оплаты условия по сумме заказа, роли пользователя и т.д.
Сравнение вариантов реализации отключения способов оплаты
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
Через фильтр woocommerce_available_payment_gateways | Прямое управление, быстрое выполнение, гибкость | Требует написания кода, требует понимания WooCommerce API | Пример в статье выше |
| Через плагины (например, Conditional Shipping and Payments) | Удобный интерфейс, без кода | Платные, могут влиять на производительность | Плагин WooCommerce Conditional Shipping and Payments |
| JS-скрипты для скрытия способов оплаты | Простая реализация | Ненадёжно, способы оплаты доступны в коде, легко обходится | Не рекомендуется |