Диагностика проблемы: почему нужна многовалютность в WooCommerce
Многие магазины WooCommerce работают с клиентами из разных стран, что требует отображения цен в нескольких валютах. Стандартно WooCommerce не поддерживает многовалютность без сторонних плагинов, что создает ограничения для пользователей и владельцев магазинов. Часто владельцы магазинов сталкиваются с проблемой, когда цены и платежи принимаются только в одной валюте, что снижает удобство и конверсию.
Как реализовать простую поддержку нескольких валют без плагинов
Если вам нужна базовая функциональность, например, отображение цен в зависимости от выбора пользователя и конвертация при оформлении заказа, это можно реализовать через пользовательский код с использованием хуков WooCommerce и фильтрации цен.
Шаг 1. Добавление выбора валюты на фронтенде
Добавим простой селектор валюты в верхнюю часть сайта. Для хранения выбранной валюты используем сессию PHP.
add_action('init', function() {
if (isset($_GET['currency'])) {
$currency = sanitize_text_field($_GET['currency']);
$allowed_currencies = ['USD', 'EUR', 'RUB'];
if (in_array($currency, $allowed_currencies)) {
WC()->session->set('chosen_currency', $currency);
}
}
});
add_action('wp_footer', function() {
$currencies = ['USD', 'EUR', 'RUB'];
$current = WC()->session->get('chosen_currency') ?: 'USD';
echo '<form method="get" id="currency-switcher" style="margin:10px;">';
echo '<select name="currency" onchange="this.form.submit()">';
foreach ($currencies as $cur) {
$selected = ($cur === $current) ? 'selected' : '';
echo "<option value=\"{$cur}\" {$selected}>{$cur}</option>";
}
echo '</select>';
echo '</form>';
});Шаг 2. Изменение отображения цен в зависимости от выбранной валюты
Воспользуемся фильтром woocommerce_get_price_html для корректного отображения цены, а также фильтром woocommerce_product_get_price для изменения цены товара.
add_filter('woocommerce_product_get_price', 'convert_price_by_currency', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'convert_price_by_currency', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'convert_price_by_currency', 10, 2);
add_filter('woocommerce_get_price_html', 'display_price_with_currency', 10, 2);
function convert_price_by_currency($price, $product) {
$currency = WC()->session->get('chosen_currency') ?: 'USD';
$rates = ['USD' => 1, 'EUR' => 0.9, 'RUB' => 75]; // Пример курсов
$base_currency = 'USD'; // Валюта магазина
if ($currency === $base_currency) {
return $price;
}
if (!isset($rates[$currency])) {
return $price;
}
return round($price * $rates[$currency], 2);
}
function display_price_with_currency($price_html, $product) {
$currency = WC()->session->get('chosen_currency') ?: 'USD';
return $price_html . ' ' . $currency;
}Шаг 3. Обработка валюты при оформлении заказа
Для корректной работы платежных шлюзов нужно передать валюту, выбранную пользователем. Для этого добавим в заказ мета-данные и изменим валюту в процессе оплаты.
add_action('woocommerce_checkout_create_order', function($order, $data) {
$currency = WC()->session->get('chosen_currency') ?: 'USD';
$order->set_currency($currency);
$order->update_meta_data('_selected_currency', $currency);
}, 10, 2);Проверка результата после внедрения
- Зайдите на сайт и переключите валюту с помощью селектора.
- Проверьте, что цены на страницах товаров изменились и отображают выбранную валюту с корректным символом или кодом.
- Добавьте товар в корзину, перейдите к оформлению заказа и убедитесь, что валюта заказа соответствует выбранной валюте.
- После оформления заказа проверьте в админке WooCommerce, что валюта заказа сохранена и отображается правильно.
Частые ошибки и способы их исправления
- Сессия не сохраняется: Убедитесь, что
WC()->sessionинициализирована, и сессии работают (например, сессии PHP не отключены). - Цены не обновляются: Проверьте, что фильтры применяются к нужным хукам и приоритеты не конфликтуют с другими плагинами.
- Платежный шлюз не принимает валюту: Некоторые шлюзы поддерживают ограниченный набор валют. Используйте совместимые валюты или доработайте интеграцию.
- Ошибки округления: Используйте функцию
round()для корректного округления цены после конвертации.
Практические советы по безопасности и производительности
- Сохраняйте курсы валют в transient или кеш, чтобы не делать лишних расчетов при каждом запросе.
- Обновляйте курсы валют регулярно, например, через wp_cron, используя API надежных сервисов.
- Валидация и санитизация пользовательских данных обязательны (как в примере с
sanitize_text_field()). - Не храните курсы валют в базе без необходимости — лучше использовать внешний API с кешированием.
Сравнение подходов: плагин vs код
| Критерий | Реализация через код | Использование плагина | Компромисс |
|---|---|---|---|
| Гибкость | Максимальная, можно подстроить под любые задачи | Ограничена функционалом плагина | Требуется больше времени на разработку |
| Поддержка | Зависит от разработчика | Обновления и поддержка от автора | Не всегда актуально |
| Производительность | Меньшее количество лишних запросов | Может добавлять нагрузку | Плюс к удобству |
| Стоимость | Свободная, без платы | Часто платные расширения | Экономия или инвестиции |