Валюты и курсы - несколько валют в магазине и пересчёт цен
Заводим вторую валюту, настраиваем курс и разбираемся, в какой валюте в итоге считается заказ.
Решение
Смотрим заведённые валюты и базовую:
use Bitrix\Main\Loader;
Loader::includeModule('currency');$res = CCurrency::GetList(); // список валют магазина с их настройкамиwhile ($currency = $res->Fetch()) { printf("%-5s база=%s формат=%s\n", $currency['CURRENCY'], $currency['BASE'], $currency['FORMAT_STRING']);}Базовая валюта в магазине одна, и через неё идут все пересчёты. Цена в долларах превращается в рубли не напрямую, а через базовую, и точность результата зависит от обоих курсов.
Задаём курс на дату:
CCurrencyRates::Add([ 'CURRENCY' => 'USD', 'DATE_RATE' => '01.09.2026', // курс привязан к дате 'RATE_CNT' => 1, 'RATE' => 92.5,]);// пересчёт всегда идёт через базовую валюту, а не напрямую между двумяКурс хранится историей значений на каждую отдельную дату. Пересчёт берёт курс на дату операции, и старые заказы не меняются от сегодняшнего курса - это и есть смысл истории.
Смотрим, в какой валюте посчитан заказ:
$order = \Bitrix\Sale\Order::load($orderId);printf("валюта=%s сумма=%.2f\n", $order->getCurrency(), $order->getPrice());// валюта фиксируется при оформлении и потом не меняетсяЗаказ запоминает свою валюту в момент создания документа. Смена базовой валюты магазина потом не пересчитывает старые заказы: они остаются в той валюте, в которой были оформлены.
Настраиваем формат вывода:
CCurrency::Update('RUB', [ 'FORMAT_STRING' => '# руб.', // где стоит символ валюты 'DEC_POINT' => ',', 'THOUSANDS_SEP' => ' ', 'DECIMALS' => 0, // копейки в рознице обычно не показывают]);Формат живёт у валюты и действует на весь сайт сразу. Разные форматы на витрине и в письмах означают, что где-то цена собирается своим кодом мимо штатного форматирования.
Курсы валют в магазине не обновляются сами по себе. Их либо заводят руками, либо забирают из внешнего источника своим агентом; забытый курс месячной давности - обычная причина расхождения цен с ожиданиями.
Пересчёт через базовую валюту стоит держать в голове при любой работе с ценами. Цена в долларах, переведённая в евро, проходит два пересчёта и два округления, и расхождение в пару копеек здесь не ошибка, а свойство схемы.
Мультивалютность стоит заводить только при действительно реальной необходимости. Магазину с рублёвыми ценами вторая валюта добавляет пересчёты и округления, не давая взамен ровным счётом ничего.
Типичные проблемы
Цена на витрине отличается от заданной в админке.
Цена задана в другой валюте и пересчитывается по текущему курсу. Пересчёт при этом идёт через базовую валюту магазина.
Суммы старых заказов изменились.
Так быть не должно: заказ хранит собственную валюту и сумму. Изменение сумм означает, что их переписал чей-то свой код.
Цены разъехались на копейки.
Округление возникает после двойного пересчёта через базовую валюту. Число знаков после запятой задают у валюты явно.
Курс устарел на месяц.
Курсы валют не обновляются автоматически сами. Их заводят руками либо забирают агентом из внешнего источника.
В письме цена в другом формате.
Цена собрана своим кодом мимо штатного форматирования. Формат живёт у валюты и применяется штатной функцией вывода.
Частые вопросы
Нужна ли вторая валюта интернет-магазину?
Только если покупатели действительно платят в разных валютах. Показ цен в валюте при оплате в рублях чаще делают простым пересчётом на витрине.
Откуда брать курсы автоматически?
Своим агентом, забирающим их у центрального банка или у поставщика данных. Штатного источника курсов в поставке нет.
Можно ли менять базовую валюту?
Технически да, но все цены и курсы после этого пересчитываются относительно новой базы. На работающем магазине это дорогая операция.
Как показать цену в валюте, не меняя валюту заказа?
Пересчётом на витрине при выводе: заказ при этом остаётся в валюте магазина. Так делают справочный показ цен для иностранных покупателей.
Смежное
- Цены и скидки - оглавление подтемы
- Цена в другой валюте неверная: разбор причин - когда пересчёт даёт не те числа
- Типы цен: розница и опт, права групп, цена по количеству - в какой цене хранится валюта
- Валюты - устройство модуля валют
- Многоязычный каталог: второй сайт, переводы товаров и корзина - формат валюты для второго языка
- Каталог и продажи - устройство магазина целиком