Диагностика задачи: почему нужно ограничивать возвраты по ролям
В WooCommerce возвраты товаров обычно доступны всем покупателям, что не всегда подходит для бизнес-моделей с разными уровнями клиентов (оптовики, розница, партнеры). Например, оптовым клиентам можно разрешить возвраты только в течение 7 дней, а розничным — 14 дней, или полностью запретить возвраты для определенных ролей. Чистого функционала для этого в WooCommerce нет, поэтому нужно добавить кастомную логику.
Пошаговое решение: ограничение возвратов по ролям пользователей
1. Создаем пользовательские роли (если нужно)
Если у вас еще нет нужных ролей, добавим их через код в functions.php или плагин-сниппет:
function add_custom_roles() {
add_role('optovik', 'Оптовик', array(
'read' => true,
'level_0' => true,
));
}
add_action('init', 'add_custom_roles');2. Добавляем проверку роли на странице возврата (например, в WooCommerce My Account)
Допустим, возвраты обрабатываются через страницу с формой. Нужно добавить фильтр или проверку, чтобы блокировать или разрешать возврат по ролям.
Пример фильтра для запрета возврата товара, если роль пользователя не соответствует:
add_filter('woocommerce_is_return_allowed', 'restrict_return_by_user_role', 10, 2);
function restrict_return_by_user_role($allowed, $order) {
$user = wp_get_current_user();
if (in_array('optovik', (array) $user->roles)) {
// Для оптовиков разрешаем возврат
return true;
} elseif (in_array('roznitsa', (array) $user->roles)) {
// Для розницы запрещаем возврат
return false;
}
return $allowed;
}Обратите внимание, что хук woocommerce_is_return_allowed — условный пример. Реального такого хука в WooCommerce нет. Для реализации обычно нужно работать с плагинами возвратов или создавать кастомные функции, например, фильтровать доступность кнопки возврата или обработку формы возврата.
3. Пример ограничения возврата на уровне кнопки в My Account
Если возврат реализован через кастомную кнопку, можно скрыть или показать ее по роли:
add_action('woocommerce_account_orders_actions', 'hide_return_button_by_role', 10, 2);
function hide_return_button_by_role($actions, $order) {
$user = wp_get_current_user();
if (!in_array('optovik', (array) $user->roles)) {
if (isset($actions['return'])) {
unset($actions['return']);
}
}
return $actions;
}Проверка результата после внедрения
- Залогиньтесь под разными пользователями с разными ролями.
- Проверьте, доступна ли кнопка или форма возврата в разделе заказов.
- Попробуйте отправить запрос на возврат и убедитесь, что ограничения работают.
Частые ошибки и как исправить
- Неправильное определение роли пользователя: используйте
wp_get_current_user()и проверяйте роли черезin_array, чтобы избежать ошибок. - Использование несуществующих хуков WooCommerce: WooCommerce по умолчанию не имеет встроенной системы возвратов, поэтому нужно либо использовать плагины возвратов с документированными API, либо реализовывать кастомные решения.
- Кэширование страниц аккаунта: кэш может показывать устаревший интерфейс без изменений по ролям. Отключите кэширование для страниц аккаунта или настройте исключения.
- Отсутствие проверки на фронтенде и бекенде: скрытие кнопок — только визуальный метод, обязательно проверяйте права и на сервере при обработке запросов, чтобы избежать обхода.
Практические советы по безопасности и производительности
- Не полагайтесь только на фронтенд-ограничения — обязательно проверяйте права на сервере, чтобы исключить несанкционированный возврат.
- Используйте nonce и проверку текущего пользователя для форм возврата.
- Учитывайте производительность при добавлении проверок — кешируйте результаты ролей, если проверок много.
Сравнение вариантов реализации ограничения возвратов
| Метод | Плюсы | Минусы | Рекомендации |
|---|---|---|---|
| Кастомный код в functions.php | Полный контроль, бесплатно | Требует знаний, нужно тестировать все сценарии | Используйте для уникальных требований |
| Плагины возвратов с поддержкой ролей | Готовое решение, часто с UI | Платные, могут быть избыточными | Подходит для стандартных процессов возврата |
| Комбинация кода и плагинов | Гибкость и удобство | Сложнее в поддержке | Оптимально при нестандартных требованиях |