Веб

Настройка типа цены в 1С Битрикс по оплате

Автоматическое изменение типа цены в 1С и Битрикс в зависимости от способа оплаты. Настройка наличной и безналичной цены, выгрузка цен.

Как настроить автоматическое изменение типа цены в зависимости от способа оплаты в 1С и Битрикс?

В нашем интернет-магазине требуется реализовать два варианта цен:

  • Цена при оплате наличными
  • Цена при безналичной оплате картой

Проблема заключается в том, что в 1С расчеты ведутся иначе, чем в Битрикс. Простое добавление наценки 6% с последующим округлением не решает задачу корректно.

Пример:

  • Наличная цена: 2499 руб.
  • Безналичная цена: 2699 руб. (хотя по расчетам должна быть 2649 руб.), с округлением до сотни и вычитанием 1 рубля.

Основной вопрос: Как настроить систему так, чтобы при выборе способа оплаты безналичным расчетом, цена автоматически бралась из соответствующего типа цен?

Дополнительная информация: В стандартном функционале Битрикс типы цен можно привязать только к группам пользователей, а в нашем случае требуется единая настройка для всех клиентов.

Чтобы система автоматически подставляла безналичную цену, создайте в 1С и в Битрикс два типа цен с одинаковыми внешними кодами (например, CASH и CARD), реализуйте в 1С точную формулу расчёта безналичной цены (учтите порядок операций: округление ↔ наценка), экспортируйте обе цены в Битрикс и переключайте применяемый тип цены на этапе корзины/чекаута — через событие OnGetOptimalPrice или клиентский переключатель. Главное — вычислять и выгружать в 1С ту версию безналичной цены, которая соответствует вашим бизнес‑правилам, чтобы избежать расхождений (например, 2649 vs 2699 руб.).

Содержание

Настройка типа цены в 1С и Битрикс

  1. Определите бизнес‑правило расчёта. Выясните точно, в каком порядке должны применяться операции: округление до сотни — перед наценкой или после неё; где вычитается 1 рубль. Пример ошибки в вашем кейсе: если наценка применяется до округления, то 2499 * 1.06 = 2648.94 → округление до сотни → 2700 → −1 = 2699; если округлять до сотни сначала: 2500 * 1.06 = 2650 → −1 = 2649.

  2. Создайте типы цен в 1С:

    • Названия: «Наличная», «Безналичная».
    • Установите одинаковые внешние коды (XML_ID) — например CASH и CARD. Эти коды потом используются при выгрузке в Bitrix.
  3. Создайте соответствующие типы цен в Битрикс:

    • Админка → Каталог → Типы цен (или /bitrix/admin/cat_group_admin.php).
    • Добавьте «Наличная» и «Безналичную» и укажите XML_ID, совпадающие с 1С (CASH, CARD).
  4. Решите, где хранится окончательная цена:

    • Рекомендуется вычислять и сохранять итоговую безналичную цену в 1С и выгружать её в отдельный тип цены. Тогда в Битрикс вы будете точно отображать и считать ту цену, которую заложил бухгалтер/менеджмент.
    • Если по каким‑то причинам нельзя вычислять в 1С (лицензия, ограничения), тогда реализуйте ту же формулу в Битрикс — но это риск рассинхронизации.

Рассчет безналичной цены в 1С (порядок операций и формулы)

Почему у вас получилось 2699 вместо 2649 — из‑за порядка операций. Приведу две варианта формул и объяснение, как добиться ожидаемого результата.

Входные: base = 2499, маржа = 6% (×1.06), финальное правило: округление до сотни и вычитание 1 рубля (точный порядок нужно согласовать с бизнесом).

Вариант A — округление до сотни ДО наценки (получает 2649):

  • base100 = RoundToHundred(base) → 2500
  • temp = base100 * 1.06 → 2650.0
  • final = RoundToRuble(temp) − 1 → 2649

Вариант B — наценка, затем округление до сотни (получает 2699):

  • temp = base * 1.06 → 2648.94
  • temp100 = RoundToHundred(temp) → 2700
  • final = temp100 − 1 → 2699

Как реализовать в 1С (алгоритм, псевдокод):

text
Функция RoundToHundred(value, mode)
    Если mode = "up" Тогда
        Возврат ОкруглитьВВерх(value/100)*100
    ИначеЕсли mode = "down" Тогда
        Возврат ОкруглитьВниз(value/100)*100
    Иначе
        Возврат Окр(value/100)*100  // ближайшее
    КонецЕсли
КонецФункции

// Вариант A (рекомендуемый, если вы хотите 2649):
base = ТекущаяНаличнаяЦена;
base100 = RoundToHundred(base, "nearest");
cardPrice = Окр(base100 * 1.06, 0) - 1;

Примечания:

  • В 1С используйте функции округления вашей конфигурации (Окр, Округлить, Цел/Остаток в зависимости от версии). Если не уверены, попросите программиста 1С реализовать RoundToHundred через целочисленные операции (целая часть / ceil / floor).
  • Внесите финальную цену в отдельный тип цен «CARD» и сохраните в регистре цен перед выгрузкой.

Выгрузка цен из 1С и сопоставление типов цен Битрикс

  • Экспортируйте оба типа цен (CASH и CARD) из 1С в каталог интернет‑магазина. Для корректной привязки используйте внешний код/XML_ID — этот момент описан в справке по обмену; пример: настройка внешнего кода в 1С и соответствие в Битрикс Как настроить одновременный вывод двух цен?.
  • В УТ/Управление торговлей обратите внимание на соглашения и режим выгрузки: в некоторых изданных 1С (например, «Малый бизнес») выгружается только один вид цен; для нескольких типов цен может потребоваться «Бизнес‑»лицензия. Практические примеры настройки описаны в статье про выгрузку цен для УТ11: Настройка выгрузки цен из 1С в интернет‑магазин.
  • После обмена проверьте в Битрикс таблицу цен (b_catalog_price) — должны появиться записи с разными CATALOG_GROUP_ID для ваших типов.

Если выгрузка нескольких типов невозможна по лицензии, варианты:

  • Реализовать расчет вторичной цены на стороне Битрикс — но убедитесь, что формула и функции округления совпадают.
  • Хранить вторую цену в торговом предложении как свойство и выводить её вручную.

Автоматическое применение типа цены в Битрикс по способу оплаты

Есть два рабочих подхода:

  1. Серверный (автоматическая подстановка цены при пересчёте корзины)
  • Идея: при расчёте цены для позиции перехватить выбор типа цены и вернуть цену нужного типа через событие OnGetOptimalPrice.
  • Механизм:
    • При выборе способа оплаты на фронтенде сохраняйте код способа оплаты в сессии (например, $_SESSION['SELECTED_PAYMENT_METHOD']='CARD').
    • В init.php или в модуле зарегистрируйте обработчик:
      • AddEventHandler("catalog", "OnGetOptimalPrice", "MyOnGetOptimalPriceHandler");
    • В обработчике: если в сессии выбран CARD, прочитайте цену из priceType CARD и верните структуру, ожидаемую модулем каталога (см. пример в блоке “Примеры кода”).
  • Плюсы: цены на этапе оформления/корзины всегда берутся из того типа, который вы выгрузили; скидки и промоакции корректно применяются.
  • Минусы: на страницах каталога/карточке товара статически показывается базовая цена — нужно дополнительно обновлять видимую цену через AJAX при смене метода оплаты.
  1. Клиентский (показываем оба значения и переключаем отображение)
  • Измените шаблон компонента каталога/детальной страницы: извлекайте обе цены (CASH и CARD) и выводите рядом или как переключатель.
  • При выборе способа оплаты в чеке через JS изменяйте отображаемую цену и отправляйте запрос на пересчёт корзины.
  • Плюсы: визуально сразу видно, какая будет цена при выборе того или иного способа оплаты.
  • Минусы: если логика расчёта сложная (налоги, курсы валют, индивидуальные скидки), клиентская подстановка должна учитывать эти факторы или требовать пересчёта на сервере.

Кеширование:

  • Учитывайте кеш компонент — если компонент кеширует вывод без учёта сессии, клиент не увидит актуальную цену. Включите динамическую область или обновляйте цену через AJAX.

Практическая заметка: подробнее о механизмах подстановки цен и провайдеров цен — см. примеры и разбор в статье о персональных ценах и событиях: Персональные цены и скидки в 1С‑Битрикс.

Тестирование, отладка и типичные ошибки

План тестов:

  1. Создайте тестовый товар с ценой 2499.
  2. В 1С вручную рассчитаете безналичную цену двумя способами (вариант A и B) и сравните.
  3. Пропустите выгрузку, проверьте в XML/экспорте, что значения для CASH и CARD совпадают с ожидаемыми.
  4. Выполните обмен — в Битрикс проверьте записи в b_catalog_price.
  5. На фронтенде: выберите способ оплаты «наличными» и «карта», убедитесь, что корзина и итог пересчитываются и берут правильную цену.

Частые ошибки:

  • Несовпадение внешних кодов (XML_ID) — цены не сопоставляются.
  • Неправильный порядок округления — как в вашем примере.
  • Лицензионные ограничения 1С — экспортируется только один тип цен.
  • Кеширование шаблона каталога мешает увидеть актуальную цену.
  • Не пересчитывается корзина при смене способа оплаты (нужно AJAX/перезагрузку или серверную обработку).

Примеры кода (1С и Bitrix)

  1. Псевдо‑алгоритм расчёта в 1С (логика округления до сотни перед наценкой — даёт 2649):
text
// Псевдокод (в 1С реализовать через встроенные функции округления)
base = Товар.ЦенаНаличными;              // 2499
base100 = RoundToHundred(base, "nearest"); // 2500
temp = base100 * 1.06;                  // 2650
cardPrice = Round(temp, 0) - 1;        // 2649
Товар.ЦенаБезнал = cardPrice;

Функцию RoundToHundred реализуйте через целочисленные операции (ceil/floor/round).

  1. Обработчик OnGetOptimalPrice — пример для Bitrix (поместите в init.php или модуль):
php
AddEventHandler("catalog", "OnGetOptimalPrice", "UA_OnGetOptimalPriceHandler");

function UA_OnGetOptimalPriceHandler($productID, $quantity, $userGroups, $renew = "N", $siteID = SITE_ID)
{
    if (!isset($_SESSION)) { @session_start(); }
    $pay = $_SESSION['SELECTED_PAYMENT_METHOD'] ?? null;
    if ($pay !== 'CARD') {
        return false; // Использовать стандартный механизм
    }

    // получить ID типа цены по XML_ID = 'CARD'
    $rsGroup = CCatalogGroup::GetList([], ['XML_ID' => 'CARD']);
    if (!($arGroup = $rsGroup->Fetch())) return false;
    $priceTypeId = intval($arGroup['ID']);
    if (!$priceTypeId) return false;

    $dbPrice = CPrice::GetList([], ['PRODUCT_ID' => $productID, 'CATALOG_GROUP_ID' => $priceTypeId]);
    if ($arPrice = $dbPrice->Fetch()) {
        $price = floatval($arPrice['PRICE']);
        return [
            "PRICE" => $arPrice,
            "RESULT_PRICE" => [
                "BASE_PRICE" => ["PRICE" => $price, "CURRENCY" => $arPrice['CURRENCY']],
                "DISCOUNT_PRICE" => 0,
                "MIN_PRICE" => ["PRICE" => $price, "CURRENCY" => $arPrice['CURRENCY']]
            ],
            "DISCOUNT_LIST" => []
        ];
    }
    return false;
}
  1. Простой AJAX‑скрипт на фронтенде (при выборе способа оплаты сохранить в сессии и перезагрузить корзину):
javascript
// Пример: при смене radio с data-code
document.querySelectorAll('input[name="PAY_SYSTEM_ID"]').forEach(function(el){
  el.addEventListener('change', function(){
    var pay = this.dataset.code || this.value;
    BX.ajax({
      url: '/local/ajax/set_payment.php',
      method: 'POST',
      dataType: 'json',
      data: {'pay': pay},
      onsuccess: function(){ location.reload(); } // либо обновлять только блок корзины через AJAX
    });
  });
});

/local/ajax/set_payment.php:

php
<?php
session_start();
$pay = $_POST['pay'] ?? '';
// валидация $pay: только разрешённые значения
$_SESSION['SELECTED_PAYMENT_METHOD'] = $pay;
echo json_encode(['status' => 'ok']);

Источники

Заключение

Коротко: для корректной работы настройка типа цены 1С Битрикс должна включать два синхронизированных типа цен (CASH и CARD), точную реализацию формулы расчёта безналичной цены в 1С (с правильным порядком округления и наценки) и логику подстановки нужного типа цены в Битрикс на этапе корзины/чекаута (OnGetOptimalPrice или клиентский переключатель). Начните с уточнения бизнес‑правила округления (до сотни до наценки или после), реализуйте это в 1С и протестируйте полную цепочку: расчёт → выгрузка → отображение → перерасчёт корзины.

Авторы
Проверено модерацией
Модерация
Настройка типа цены в 1С Битрикс по оплате