Диагностика задачи: зачем нужен переключатель валют в WooCommerce
Многие магазины на WooCommerce работают с международной аудиторией и хотят показывать цены в разных валютах. Обычно для этого используют плагины, но они могут конфликтовать с другими расширениями, замедлять сайт или быть платными. В таких случаях практично реализовать переключатель валют собственными силами через код.
Основные шаги для реализации переключателя валют без плагинов
1. Добавление поддержки нескольких валют
WooCommerce по умолчанию не поддерживает несколько валют, поэтому нужно вручную менять валюту и цены на лету. Для этого можно использовать сессии и фильтры WooCommerce.
2. Создание переключателя валют в шапке сайта
Добавим простой селектор валют, который будет сохранять выбор пользователя в сессии.
add_action('init', function() {
if (!session_id()) {
session_start();
}
if (isset($_GET['currency'])) {
$allowed_currencies = ['USD', 'EUR', 'RUB'];
$currency = strtoupper(sanitize_text_field($_GET['currency']));
if (in_array($currency, $allowed_currencies)) {
$_SESSION['my_currency'] = $currency;
}
}
});
function render_currency_switcher() {
$currencies = ['USD' => '$', 'EUR' => '€', 'RUB' => '₽'];
$current = $_SESSION['my_currency'] ?? 'USD';
echo '<form method="get" id="currency-switcher">';
echo '<select name="currency" onchange="this.form.submit()">';
foreach ($currencies as $code => $symbol) {
$selected = ($current === $code) ? 'selected' : '';
echo "<option value=\"$code\" $selected>$code ($symbol)</option>";
}
echo '</select>';
echo '</form>';
}
add_action('wp_footer', 'render_currency_switcher');3. Изменение отображаемой валюты и цен
Используем фильтры WooCommerce woocommerce_currency и woocommerce_get_price для подмены валюты и пересчёта цен.
add_filter('woocommerce_currency', function($currency) {
if (!session_id()) {
session_start();
}
if (!empty($_SESSION['my_currency'])) {
return $_SESSION['my_currency'];
}
return $currency;
});
// Пример курсов валют относительно USD
function convert_price_by_currency($price, $currency) {
$rates = [
'USD' => 1,
'EUR' => 0.92,
'RUB' => 75
];
if (isset($rates[$currency])) {
return $price * $rates[$currency];
}
return $price;
}
add_filter('woocommerce_product_get_price', function($price, $product) {
if (!session_id()) {
session_start();
}
$currency = $_SESSION['my_currency'] ?? 'USD';
return convert_price_by_currency((float)$price, $currency);
}, 10, 2);
add_filter('woocommerce_product_get_regular_price', function($price, $product) {
if (!session_id()) {
session_start();
}
$currency = $_SESSION['my_currency'] ?? 'USD';
return convert_price_by_currency((float)$price, $currency);
}, 10, 2);
add_filter('woocommerce_product_get_sale_price', function($price, $product) {
if (!session_id()) {
session_start();
}
$currency = $_SESSION['my_currency'] ?? 'USD';
return convert_price_by_currency((float)$price, $currency);
}, 10, 2);Проверка результата после внедрения
- Перейдите на страницу магазина, внизу (или там, где вы подключили селектор) появится выпадающий список валют.
- Выберите другую валюту — страница перезагрузится, цены должны отобразиться в выбранной валюте.
- Убедитесь, что цены в карточках товаров, на странице товара и в корзине отображаются правильно.
- Проверьте, что сессия сохраняет выбор при переходе по страницам.
Частые ошибки и их исправление
- Сессия не стартует: Если вы получаете ошибку «Headers already sent» или сессия не сохраняется, убедитесь, что вызов
session_start()происходит до вывода любых данных. Лучше подключать этот код вinitс приоритетом 0. - Цены не меняются: Проверьте, что фильтры применяются именно к
woocommerce_product_get_price, а не к другим хукам. Иногда требуется также фильтроватьwoocommerce_get_price_htmlдля корректного отображения. - Неверные курсы валют: Обновляйте курсы вручную или интегрируйте API для актуализации. Не забывайте кэшировать результаты для производительности.
- Переключатель не отображается: Убедитесь, что функция вывода селектора подключена в нужное место темы (например, в футере или в шапке).
Практические советы по безопасности и производительности
- Очистка и фильтрация данных: Всегда фильтруйте входящие данные через
sanitize_text_field(), чтобы избежать XSS-уязвимостей. - Используйте кеширование курсов валют: Если интегрируете API для курсов (например, Open Exchange Rates), кешируйте ответ минимум на час, чтобы не перегружать внешний сервис и не замедлять сайт.
- Минимизируйте сессии: Используйте WordPress Transients или куки, если сессии вызывают проблемы на хостинге.
- Тестируйте на staging-сервере: Перед внедрением на боевой сайт проверьте корректность отображения и пересчёта цен.
Сравнение решений для переключателя валют в WooCommerce
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Плагины (Currency Switcher) | Простая установка, поддержка, автоматические курсы | Зависимость от стороннего кода, нагрузка, цена | Для крупных магазинов с мультивалютой и частым обновлением курсов |
| Ручной код (как в статье) | Легковесно, полная кастомизация | Нужно обновлять курсы вручную, ограниченный функционал | Маленькие магазины или проекты с ограниченным бюджетом и функционалом |
| Внешние сервисы с API | Автоматизация курсов, точность | Сложность интеграции, зависимость от API | Если нужна автоматизация и точность курсов |