Настройка налоговых ставок по регионам 1С-Битрикс
Магазин работает на Беларусь и Россию с разными ставками НДС. Или продаёт цифровые товары в ЕС, где НДС зависит от страны покупателя. Стандартная одна ставка на весь каталог здесь не работает — нужна региональная логика.
Группы налогоплательщиков
Битрикс реализует региональные ставки через механизм групп налогоплательщиков (tax groups). Таблица b_sale_tax хранит налоговые группы, b_sale_tax_rate — ставки внутри групп с привязкой к региону.
Структура b_sale_tax_rate: TAX_ID (ссылка на группу), COUNTRY_ID, REGION, CITY, RATE, IS_PERCENT (Y/N), IS_IN_PRICE (Y/N — аналог VAT_INCLUDED), ACTIVE.
Создание налоговой группы с региональными ставками:
// Создать группу
$taxResult = \Bitrix\Sale\Tax::add([
'NAME' => 'НДС',
'ACTIVE' => 'Y',
'LID' => 's1',
]);
$taxId = $taxResult->getId();
// Ставка для Беларуси
\Bitrix\Sale\TaxRate::add([
'TAX_ID' => $taxId,
'COUNTRY_ID' => 'BY',
'RATE' => 20,
'IS_PERCENT' => 'Y',
'IS_IN_PRICE' => 'Y',
'ACTIVE' => 'Y',
]);
// Ставка для России
\Bitrix\Sale\TaxRate::add([
'TAX_ID' => $taxId,
'COUNTRY_ID' => 'RU',
'RATE' => 20,
'IS_PERCENT' => 'Y',
'IS_IN_PRICE' => 'Y',
'ACTIVE' => 'Y',
]);
Привязка налогов к свойствам заказа
Определение применяемой ставки происходит в момент расчёта корзины. Битрикс читает адрес покупателя из свойств заказа (b_sale_order_props_value) — ищет свойство с типом LOCATION или TEXT с кодом страны/региона.
Привязка налоговой группы к магазину — настройка в /bitrix/admin/sale_tax.php. Каждая группа может быть активна для конкретного сайта (LID). При расчёте корзины модуль sale вызывает \Bitrix\Sale\Tax::getList() с фильтром по LID и применяет первую подходящую ставку по стране/региону из адреса.
Определение региона покупателя
Проблема механизма: покупатель не всегда заполняет адрес до расчёта корзины. Для автоматического определения региона по IP используется модуль seo — класс \Bitrix\Seo\Ip2Location. Он опрашивает сервис геолокации и возвращает страну/регион.
Обработчик для автоподстановки страны в корзину:
AddEventHandler('sale', 'OnSaleBasketBeforeSaved', function($basket) {
$order = $basket->getOrder();
if (!$order) return;
$ip = $_SERVER['REMOTE_ADDR'];
$location = \Bitrix\Seo\Ip2Location::getLocationByIp($ip);
if ($location && $location['COUNTRY_CODE']) {
// установить свойство заказа с кодом страны
$propertyCollection = $order->getPropertyCollection();
$prop = $propertyCollection->getItemByOrderPropertyCode('COUNTRY');
if ($prop) {
$prop->setValue($location['COUNTRY_CODE']);
}
}
});
Налоги и цены: отображение
Если в каталоге цены с НДС (VAT_INCLUDED = Y), а региональная ставка ниже (например, 0% для экспорта), корзина должна пересчитать цены. Битрикс это делает автоматически через механизм налогов модуля sale, но только если IS_IN_PRICE = Y в b_sale_tax_rate и VAT_INCLUDED = Y в b_catalog_product согласованы.
Расхождение этих полей — главный источник неверного НДС при региональных ставках. Проверочный запрос для поиска несогласованных товаров:
SELECT cp.IBLOCK_ELEMENT_ID, cp.VAT_INCLUDED, cv.RATE
FROM b_catalog_product cp
LEFT JOIN b_catalog_vat cv ON cp.VAT_ID = cv.ID
WHERE cp.VAT_ID IS NOT NULL
AND cp.VAT_INCLUDED != 'Y';
Все найденные позиции нужно привести к единому правилу перед настройкой региональных ставок.







