WooCommerce: как запретить отмену заказа по ролям пользователей

Диагностика проблемы: почему нужно ограничить отмену заказов по ролям

В интернет-магазинах на WooCommerce иногда возникает необходимость ограничить отмену заказов для разных групп пользователей. Например, для оптовиков или VIP-клиентов отмена заказа может быть запрещена, чтобы избежать потери прибыли и упростить обработку заказов. По умолчанию WooCommerce не предоставляет гибких настроек для управления отменой заказов по ролям пользователей, поэтому требуется вмешательство через код.

Как работает отмена заказа в WooCommerce

Отмена заказа в WooCommerce — это изменение статуса заказа на "Отменён" (cancelled). Пользователь может отменить заказ через личный кабинет, если статус заказа позволяет это сделать, а также администратор может делать это вручную. Для реализации ограничения нам нужно перехватить попытку отмены и проверить роль пользователя.

Пошаговое решение: запрет отмены заказа для определённых ролей

1. Определяем роли, для которых запрещена отмена

В примере запретим отмену для пользователей с ролью wholesale_customer и vip_client.

2. Добавляем фильтр на изменение статуса заказа

Используем хук woocommerce_before_order_object_save для проверки попытки смены статуса на cancelled.

add_action('woocommerce_before_order_object_save', function($order) {
    if (!$order instanceof WC_Order) return;

    // Получаем текущего пользователя
    $user_id = get_current_user_id();
    if (!$user_id) return; // Неавторизованный пользователь

    $user = get_userdata($user_id);
    $forbidden_roles = ['wholesale_customer', 'vip_client'];

    // Проверяем, пытается ли изменить статус на отменён
    $new_status = $order->get_status();
    $old_status = $order->get_meta('_old_status');

    // Сохраняем старый статус для следующей проверки
    if (!$old_status) {
        $order->update_meta_data('_old_status', $new_status);
        return;
    }

    if ($new_status === 'cancelled' && in_array($old_status, ['processing', 'on-hold', 'pending'])) {
        // Проверяем роль пользователя
        foreach ($forbidden_roles as $role) {
            if (in_array($role, $user->roles)) {
                // Отменяем смену статуса
                $order->set_status($old_status);
                wc_add_notice('Отмена заказа запрещена для вашей роли пользователя.', 'error');
                // Прерываем дальнейшее сохранение
                remove_action('woocommerce_before_order_object_save', __FUNCTION__);
                wp_die('Отмена заказа запрещена для вашей роли пользователя.');
            }
        }
    }

    // Обновляем мета с текущим статусом
    $order->update_meta_data('_old_status', $new_status);
});

3. Обработка отмены заказа из личного кабинета

Пользователь может отменять заказ через AJAX или форму. Для UX лучше отключить кнопку отмены, если роль пользователя запрещает отмену. Добавим JS через хук wp_footer и проверим роль.

add_action('wp_footer', function() {
    if (!is_account_page()) return;
    $user = wp_get_current_user();
    $forbidden_roles = ['wholesale_customer', 'vip_client'];
    foreach ($forbidden_roles as $role) {
        if (in_array($role, $user->roles)) {
            ?>
            <script>
            document.addEventListener('DOMContentLoaded', function() {
                document.querySelectorAll('a.cancel-order').forEach(function(btn) {
                    btn.style.pointerEvents = 'none';
                    btn.style.opacity = '0.5';
                    btn.title = 'Отмена заказа запрещена для вашей роли';
                });
            });
            </script>
            <?php
            break;
        }
    }
});

Проверка результата после внедрения

  • Авторизуйтесь под пользователем с ролью wholesale_customer или vip_client.
  • Перейдите в Личный кабинет → Заказы.
  • Убедитесь, что кнопка отмены заказа либо неактивна, либо при попытке отмены появляется сообщение об ошибке.
  • Попробуйте отменить заказ из админки — ограничение не действует для администратора.

Частые ошибки и как их исправить

  • Ошибка: Смена статуса заказа не блокируется.
    Причина: Хук woocommerce_before_order_object_save не срабатывает, потому что код добавлен в неподходящем месте или кэш мешает.
    Решение: Убедитесь, что код добавлен в functions.php активной темы или в плагине, отключите кэширование и протестируйте.
  • Ошибка: Пользователь видит кнопку отмены, но при клике ничего не происходит.
    Причина: JS не подключился из-за неправильных условий или кэширования.
    Решение: Проверьте, что скрипт выводится на странице Личного кабинета, очистите кэш браузера.
  • Ошибка: При отмене заказа в админке не появляется сообщение об ошибке.
    Причина: wp_die() прерывает работу без вывода сообщения в UI.
    Решение: Для админки можно добавить уведомление через admin_notices или использовать другой способ отмены статуса.

Практические советы по безопасности и производительности

  • Проверяйте роли пользователей не через жёсткое сравнение, а через in_array() с массивом ролей — это предотвращает проблемы с кастомными ролями.
  • Не используйте wp_die() без явной необходимости — лучше возвращать ошибки через WooCommerce notices, чтобы не прерывать скрипт.
  • Кэшируйте данные пользователей и статусы заказов аккуратно, чтобы не потерять актуальность проверки.
  • Для улучшения UX отключайте кнопку отмены на фронтенде для запрещённых ролей, а не только блокируйте серверный запрос.
  • Тестируйте на разных ролях и сценариях, особенно если используете кастомные роли или плагин для управления ролями.

Сравнение способов реализации запрета отмены заказа

МетодПлюсыМинусы
Серверная проверка через woocommerce_before_order_object_saveНадёжно, блокирует отмену полностьюМенее дружелюбно в UX, требует правильного использования хуков
Отключение кнопки отмены через JSУлучшает UX, предотвращает попытки отменыМожно обойти, если отключен JS; требует серверной проверки
Полная замена шаблонов WooCommerceГибкий контроль интерфейсаСложнее в поддержке, зависит от обновлений WooCommerce
Как закрыть от индексации страницы поискового фильтра в WordPress
13.08.2026
Как закрыть дубли архивов авторов и дат в WordPress
20.08.2026
Как закрыть от индексации страницы поиска по сайту в WordPress
23.08.2026
Как отключить XML-RPC в WordPress без поломки приложений и плагинов
17.08.2026
×
Прокачай свой WordPress!

Скидка -20% на премиум темы и плагины

Воспользоваться сейчас ⋙