Диагностика проблемы: зачем менять способы оплаты по ролям
В WooCommerce по умолчанию все пользователи видят одинаковые методы оплаты. Однако в некоторых проектах нужно ограничить или расширить способы оплаты в зависимости от роли пользователя — например, чтобы оплата при получении была доступна только для оптовиков, а розничным покупателям показывать онлайн-оплату.
Если вы столкнулись с задачей изменить доступные способы оплаты по ролям, то стандартных настроек WooCommerce недостаточно. Решение потребует кастомного кода.
Как получить роль пользователя в WooCommerce
Чтобы фильтровать методы оплаты, сначала нужно определить роль текущего пользователя в момент оформления заказа. В WordPress роли можно получить через объект WP_User:
function get_current_user_role() {
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
if ( !empty( $user->roles ) ) {
return $user->roles[0];
}
}
return 'guest'; // для неавторизованных
}Пошаговое решение: фильтрация способов оплаты по ролям
Основной хук для изменения доступных методов оплаты — woocommerce_available_payment_gateways. Он позволяет программно отфильтровать массив платежных шлюзов.
Пример кода, который отключит метод «Оплата при получении» для всех, кроме роли «оптовик» (оптовик — роль user role wholesale_customer):
add_filter( 'woocommerce_available_payment_gateways', 'filter_payment_gateways_by_user_role' );
function filter_payment_gateways_by_user_role( $available_gateways ) {
$role = get_current_user_role();
// Проверяем роль
if ( $role !== 'wholesale_customer' ) {
// Убираем оплату при получении
if ( isset( $available_gateways['cod'] ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}Как добавить исключения для нескольких ролей
Если нужно разрешить метод оплаты нескольким ролям, используйте массив:
add_filter( 'woocommerce_available_payment_gateways', 'filter_payment_gateways_by_user_roles' );
function filter_payment_gateways_by_user_roles( $available_gateways ) {
$role = get_current_user_role();
$allowed_roles = array('wholesale_customer', 'shop_manager');
if ( ! in_array( $role, $allowed_roles ) ) {
if ( isset( $available_gateways['cod'] ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}Проверка результата после внедрения
- Войдите на сайт под разными ролями (например, как гость, как розничный покупатель, как оптовик).
- Перейдите в корзину и начните оформление заказа.
- Обратите внимание на список доступных методов оплаты — убедитесь, что «Оплата при получении» доступна только нужным ролям.
- Если у вас есть кэширование, очистите его перед проверкой.
Частые ошибки и способы их исправления
- Код не работает для гостей: функция возвращает
guest, но в фильтре код не обрабатывает этот случай. Решение — явно прописывать поведение для гостей. - Методы оплаты не меняются: возможно, подключение кода происходит в неправильном месте. Добавляйте фильтр в файл
functions.phpили в плагин, активный на сайте. - Конфликты с кешированием: если на сайте есть кеш (например, WP Rocket или серверный кеш), временно отключайте кеш при тестах.
- Проблемы с названиями ролей: убедитесь, что роль пользователя написана правильно и существует в базе.
Практические советы по безопасности и производительности
- Избегайте тяжелых операций в фильтре — просто читайте роль из объекта пользователя, не делайте запросов к базе.
- Код лучше размещать в дочерней теме или собственном плагине, чтобы не потерять при обновлении.
- Не забывайте проверять работу на мобильных устройствах и в разных браузерах.
- Для улучшения UX можно добавить кастомное уведомление на фронтенде, если метод оплаты скрыт для текущего пользователя.
Сравнение вариантов реализации фильтрации способов оплаты
| Метод | Плюсы | Минусы |
|---|---|---|
| Фильтр в functions.php | Простота, контроль над кодом | Риск потери при смене темы |
| Плагин для ролей и платежей | Готовые настройки, меньше кода | Может быть тяжелее, меньше гибкости |
| Кастомный плагин | Максимальная гибкость и безопасность | Требует навыков разработки |