Диагностика задачи: зачем менять способы оплаты по ролям
В интернет-магазинах на WooCommerce иногда требуется ограничить или открыть определённые способы оплаты для разных групп пользователей. Например, оплата при получении доступна только для оптовиков, а для розничных покупателей — только онлайн-платежи. Такое поведение не реализуется стандартными настройками и требует кастомизации.
Пошаговое решение: фильтрация доступных методов оплаты по ролям
Для реализации этой функциональности используем хук woocommerce_available_payment_gateways. Он позволяет динамически менять список платежных методов, доступных для текущего пользователя.
1. Определяем роль пользователя
function get_user_role() {
if (!is_user_logged_in()) {
return 'guest';
}
$user = wp_get_current_user();
$roles = (array) $user->roles;
return $roles ? $roles[0] : 'guest';
}
2. Фильтруем методы оплаты
add_filter('woocommerce_available_payment_gateways', 'filter_payment_gateways_by_user_role');
function filter_payment_gateways_by_user_role($available_gateways) {
$role = get_user_role();
// Пример настроек:
// оплата при получении (cod) только для оптовиков
// онлайн-оплата (paypal, stripe) для всех, кроме гостей
if ($role === 'guest') {
// для гостей разрешаем только PayPal
foreach ($available_gateways as $gateway_id => $gateway) {
if ($gateway_id !== 'paypal') {
unset($available_gateways[$gateway_id]);
}
}
} elseif ($role === 'wholesale_customer') {
// для оптовиков разрешаем оплату при получении и PayPal
foreach ($available_gateways as $gateway_id => $gateway) {
if (!in_array($gateway_id, ['cod', 'paypal'])) {
unset($available_gateways[$gateway_id]);
}
}
} else {
// для остальных пользователей запрещаем оплату при получении
if (isset($available_gateways['cod'])) {
unset($available_gateways['cod']);
}
}
return $available_gateways;
}
3. Добавляем роль в WooCommerce (если нужно)
Если роль wholesale_customer отсутствует, создайте её через плагин User Role Editor или программно:
add_action('init', function() {
add_role('wholesale_customer', 'Оптовый покупатель', [
'read' => true,
'level_0' => true
]);
});
Проверка результата после внедрения
- Авторизуйтесь под разными ролями (гость, wholesale_customer, обычный пользователь).
- Перейдите на страницу оформления заказа в WooCommerce.
- Убедитесь, что способы оплаты соответствуют правилам, заданным в фильтре:
- Гость видит только PayPal.
- Оптовик видит «Оплата при получении» и PayPal.
- Обычный пользователь видит все, кроме «Оплаты при получении».
Частые ошибки и как их исправить
- Методы оплаты не меняются: проверьте, что в WooCommerce активированы нужные платежные шлюзы и их ID совпадают с теми, что используются в фильтре.
- Роль не определяется корректно: используйте отладку, например,
error_log('User role: '.$role);чтобы убедиться, что функцияget_user_role()возвращает ожидаемое значение. - Пользователь всегда считается гостем: убедитесь, что пользователь авторизован и роли корректно установлены.
- Нельзя оплатить заказ нужным способом: проверьте приоритет и корректность других плагинов, которые могут влиять на платежи.
Практические советы по безопасности и производительности
- Не используйте
current_user_can()для определения роли пользователя, если нужны точные проверки — роли могут пересекаться. - Кешируйте результат определения роли, если фильтр вызывается часто.
- Не отключайте методы оплаты напрямую — лучше использовать фильтры WooCommerce, чтобы не ломать совместимость.
- Тестируйте на разных версиях WooCommerce и PHP.
Сравнение способов реализации
| Метод | Плюсы | Минусы | Примечания |
|---|---|---|---|
Фильтр woocommerce_available_payment_gateways | Гибкость, не требует плагинов, можно тонко настроить | Требует знаний PHP, может конфликтовать с другими плагинами | Рекомендуется для разработчиков |
| Плагины ограничения оплат по ролям | Быстрая настройка, интерфейс без кода | Могут нагружать сайт, ограничены в кастомизации | Хорошо для простых случаев |
| Использование пользовательских условий в шаблонах | Простота для базовых случаев | Не всегда надёжно, сложно поддерживать | Редко рекомендуется |