Диагностика задачи: зачем отключать оплату для заказов с определённым статусом
В WooCommerce иногда возникает необходимость запретить оплату для заказов, которые находятся в конкретном статусе. Например, если заказ ожидает подтверждения, или находится в статусе "обработка" и оплата не требуется повторно. По умолчанию WooCommerce не ограничивает оплату по статусу, и пользователь может случайно или намеренно оплатить заказ повторно, что приводит к путанице и ошибкам в учёте.
Типичные случаи, когда нужно отключить оплату:
- Заказы, ожидающие подтверждения (pending, on-hold)
- Отменённые заказы (cancelled) — для исключения повторных попыток оплаты
- Возвраты и возвраты средств (refunded)
Пошаговое решение: отключаем оплату для заказов с выбранными статусами
1. Добавляем фильтр для управления доступностью методов оплаты
WooCommerce позволяет управлять доступностью методов оплаты через фильтр woocommerce_available_payment_gateways. Мы воспользуемся этим, чтобы отключить оплату при определённых статусах заказа.
2. Получаем текущий заказ и проверяем его статус
В коде важно получить объект текущего заказа. В зависимости от страницы можно использовать глобальные переменные или параметры запроса.
3. Пример кода для functions.php вашей темы или плагина
add_filter('woocommerce_available_payment_gateways', 'disable_payment_for_certain_order_statuses');
function disable_payment_for_certain_order_statuses($available_gateways) {
if (is_admin()) return $available_gateways; // не трогаем админку
// Получаем ID заказа из URL, если на странице оплаты
if (isset($_GET['pay_for_order']) && isset($_GET['key'])) {
$order_id = absint($_GET['pay_for_order']);
$order = wc_get_order($order_id);
if ($order) {
$status = $order->get_status();
// Статусы, для которых отключаем оплату
$blocked_statuses = array('cancelled', 'refunded', 'completed');
if (in_array($status, $blocked_statuses)) {
// Отключаем все методы оплаты
return array();
}
}
}
return $available_gateways;
}Проверка результата после внедрения
Чтобы убедиться, что код работает:
- Создайте тестовый заказ в WooCommerce и установите ему статус из массива
$blocked_statuses(например, cancelled или refunded). - Перейдите по ссылке оплаты для этого заказа (обычно
?pay_for_order=ID_заказа&key=ключ). - На странице оплаты убедитесь, что методы оплаты не отображаются (форма оплаты отсутствует).
- Для заказов с другими статусами методы оплаты должны работать как обычно.
Частые ошибки и как их исправить
- Отсутствие проверки is_admin(): без неё код может влиять на админ-панель, что нарушит работу менеджеров заказов.
- Неверный способ получения заказа: если код запускается не на странице оплаты, переменные
$_GETмогут быть пустыми, или заказ не получен. В таком случае можно расширить логику, например, для корзины или страницы оформления. - Статусы указаны без префикса "wc-": в WooCommerce
get_status()возвращает статус без "wc-" — важно использовать именно такие значения. - Необработанная ситуация с кешем: если на сайте активен кеш, может потребоваться исключить кеширование страницы оплаты.
Практические советы по безопасности и производительности
- Минимизируйте код в фильтрах — обрабатывайте заказы только на страницах оплаты, чтобы не снижать производительность на других страницах.
- Логируйте попытки оплаты для заблокированных заказов, чтобы отслеживать ошибки пользователей.
- Не удаляйте методы оплаты полностью, если нужно только скрыть их — возвращайте пустой массив, как в примере, чтобы избежать конфликтов.
Альтернативные подходы: плагин или кастомный код
| Подход | Плюсы | Минусы |
|---|---|---|
| Кастомный код (пример выше) | Полный контроль, нет дополнительных плагинов, меньше нагрузки | Требует знаний PHP, риск ошибок при неправильной реализации |
| Плагины для управления статусами и оплатой | Простота использования, готовые настройки | Могут перегружать сайт, не всегда гибко под задачу |