Диагностика задачи: зачем менять стоимость товара при регистрации пользователя
В типовом WooCommerce цена товара статична и не зависит от пользователя. Однако в реальных проектах часто нужно предоставить скидку новым клиентам сразу после регистрации, либо применить специальную цену для определенной группы пользователей, сформированной автоматически. Например, после регистрации пользователя можно сделать первые товары дешевле, чтобы стимулировать покупки.
Как отследить регистрацию и изменить цену товара
Для автоматического изменения цены товара при регистрации необходимо:
- Отследить событие регистрации пользователя;
- Установить специальный мета ключ или роль, сигнализирующую о новом пользователе;
- Изменить цену товара на фронтенде и в корзине для таких пользователей.
Рассмотрим практическую реализацию с использованием стандартных хуков WooCommerce и WordPress.
1. Отслеживание регистрации и установка мета данных
Добавим мета ключ new_customer_discount для вновь зарегистрированных пользователей:
add_action('user_register', 'wpinfo_set_new_customer_flag');
function wpinfo_set_new_customer_flag($user_id) {
update_user_meta($user_id, 'new_customer_discount', 1);
}2. Изменение цены товара для пользователей с флагом
Используем фильтр woocommerce_get_price, чтобы динамически изменить цену на странице товара и в каталоге:
add_filter('woocommerce_get_price', 'wpinfo_apply_new_customer_discount', 10, 2);
function wpinfo_apply_new_customer_discount($price, $product) {
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$has_discount = get_user_meta($user_id, 'new_customer_discount', true);
if ($has_discount) {
// Например, скидка 20%
$price = $price * 0.8;
}
}
return $price;
}3. Обновление цены в корзине и на странице оформления заказа
Чтобы применить скидку в корзине и при оформлении заказа, добавим следующий хук:
add_action('woocommerce_before_calculate_totals', 'wpinfo_apply_discount_cart');
function wpinfo_apply_discount_cart($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
if (!is_user_logged_in()) {
return;
}
$user_id = get_current_user_id();
$has_discount = get_user_meta($user_id, 'new_customer_discount', true);
if (!$has_discount) {
return;
}
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.8; // 20% скидка
$cart_item['data']->set_price($discounted_price);
}
}Проверка результата после внедрения
- Зарегистрируйте нового пользователя через форму регистрации;
- Войдите под этим пользователем;
- Откройте страницу товара и убедитесь, что цена уменьшена на 20%;
- Добавьте товар в корзину и проверьте, что в корзине и на оформлении заказа цена тоже снижена;
- Залогиньтесь под пользователем без мета ключа
new_customer_discount(например, администратор) — цена должна отображаться без изменений.
Частые ошибки и как их исправить
- Цена не меняется на странице товара: убедитесь, что фильтр
woocommerce_get_priceне конфликтует с другими плагинами, и что код подключён в functions.php или в плагине. - Скидка не применяется в корзине: проверьте, что хук
woocommerce_before_calculate_totalsне отключён и что в функции не возвращается преждевременно. - Цена меняется для всех пользователей: убедитесь, что проверка
get_user_metaкорректна и возвращает значение только для новых пользователей. - Проблемы с кешем: отключите кеширование страниц для авторизованных пользователей или сбрасывайте кеш после регистрации.
Практические советы по безопасности и производительности
- Не используйте постоянные пользовательские роли для временных скидок — лучше мета ключи, которые можно удалить после использования.
- Для массовых сайтов с большим количеством пользователей и заказов лучше реализовать скидку через пользовательские цены в базе данных, чтобы не влиять на производительность.
- Убедитесь, что функции быстро выполняются и не вызывают избыточных запросов к базе данных (например, кэшируйте результат
get_user_metaвнутри запроса). - При использовании кеша страниц (например, Varnish, Cloudflare) отключайте кеширование для авторизованных пользователей.
Сравнение вариантов реализации
| Вариант | Плюсы | Минусы | Применение |
|---|---|---|---|
| Динамическая смена цены через хуки (как в статье) | Легко внедрить, гибко, не требует изменений в базе | Может конфликтовать с кешем, нагрузка на обработку | Маленькие и средние сайты с низкой нагрузкой |
| Создание отдельной роли и изменение цены через пользовательские поля | Чёткая сегментация пользователей | Требует доп. управления ролями, возможны конфликты с плагинами | Сайты с разными группами клиентов |
| Использование плагинов скидок и программ лояльности | Готовые решения, поддержка, удобный интерфейс | Платные, могут быть избыточны для простых задач | Большие проекты с комплексными скидками |