qwelp.loyalty · Руководство по подключению

Документация

Подключите бонусы к своему магазину на 1С-Битрикс: от прогноза в карточке товара до списания и истории операций.

Начало

Выберите вкладку с нужным местом сайта. Здесь показано подключение к обычным компонентам Битрикс, без шаблона shop.light.

1. Включите программу

Откройте «Квэлп → Квэлп: Программа лояльности → Настройки», включите лояльность и задайте процент начисления, курс баллов и ограничения списания. В «Правилах» проверьте, что базовое правило начисления активно.

2. Выберите, что добавить на сайт

Хочу показатьОткройте вкладку
Сколько баллов даст покупка товараКарточка товара
Прогноз и списание в корзинеКорзина
Списание при оформлении заказаОформление заказа
Баланс, историю и условия программыБаланс и кабинет

Начисление после оплаты уже обрабатывает модуль. Вставки нужны, чтобы покупатель видел бонусы и мог их потратить.

3. Подготовьте доступ к шаблонам

Для вставки PHP понадобится доступ к файлам сайта. На стандартных страницах кабинета компоненты можно добавить визуальным редактором. У цены товара и внутри оформления нужно один раз изменить копию шаблона.

Примеры используют общий каталог /local/templates/.default/components/ и отдельные имена шаблонов loyalty_product, loyalty_basket и loyalty_checkout. Выберите нужную копию в параметрах компонента на своём сайте. Файлы ядра /bitrix/ используйте только как источник для копирования.

Не создавайте неполную папку /local/templates/ с именем действующего шаблона из /bitrix/templates/: она может скрыть его шапку и подвал. Если ваш полноценный шаблон уже находится в /local/templates/, копию компонента можно поместить в его components/. Для нескольких сайтов с разным оформлением используйте разные имена копий.

Если модуль ещё не установлен

Установите qwelp.loyalty через Marketplace / список решений. Нужны main, sale, catalog, iblock и currency, PHP от 8.2 в поддерживаемой платформой ветке и UTF-8. Для MySQL используется версия 8.0 или новее. Установщик добавляет пять компонентов и инфоблок условий программы; страницы, меню и чужие шаблоны он не переписывает.

Как вставлять код, чтобы его не испортил редактор

Примеры предназначены для уже работающей страницы Битрикс, между header.php и footer.php, либо для копии шаблона компонента. Каждый IncludeComponent размещайте в отдельном блоке <?php … ?>. Несколько вызовов в одном блоке визуальный редактор может сохранить как один.

Если PHP уже открыт, не вставляйте второй открывающий тег внутрь него. SITE_ID='' означает текущий сайт. Оставляйте простые значения в массиве параметров; вычисления цены выполняются внутри компонента. После правки сохраните параметры в редакторе без изменений и с изменением одного значения, затем проверьте страницу.

Куда устанавливаются файлы и как подключить второй сайт

Marketplace размещает модуль в /bitrix/modules/qwelp.loyalty/. Установщик добавляет пять компонентов в /bitrix/components/qwelp/ и расширения JS в /bitrix/js/qwelp/loyalty/. Административные страницы находятся в /bitrix/admin/qwelp_loyalty_*.php. Файлы ядра и чужих модулей не изменяются.

Установите модуль один раз на общую установку Битрикса. Для сайтов на разных доменах с общей символьной ссылкой /bitrix компоненты, скрипты и обновления доступны сразу на обоих сайтах. Ссылка /local для работы самого модуля не требуется. Общий /upload нужен стандартным данным Битрикса; /images зависит от устройства вашего сайта.

Добавьте нужные IncludeComponent на страницы каждого сайта. Оставьте SITE_ID пустым: карточка, корзина, баланс и списание определят текущий сайт. Балансы, история, заказы и купоны разделены по SITE_ID; общие настройки программы действуют на всю установку, а отдельное правило можно ограничить сайтом. Удаление модуля отключает его на всех сайтах общей установки.

В настройках «Композитный сайт» внесите оба домена. Установка модуля не включает Composite и не меняет настройки сайтов автоматически. Если для второго сайта нужны собственные тексты условий, создайте отдельный инфоблок и задайте IBLOCK_ID у loyalty.page; по умолчанию используется общий инфоблок условий.

Копии шаблонов в /local/templates/ остаются пользовательскими настройками. На раздельных корнях сайтов разместите свою копию на каждом нужном сайте либо используйте общий шаблон. Копии самих компонентов или JS в /local имеют приоритет над /bitrix и могут скрыть обновлённый модуль. Старую разработческую установку с файлами в /local сначала удалите с сохранением данных; затем установите пакет Marketplace. Не держите одновременно две копии qwelp.loyalty в /local/modules и /bitrix/modules.

Карточка товара

Результат: под ценой появится «Ориентировочно +… баллов». Ниже — пример для bitrix:catalog.element со стандартным шаблоном .default или bootstrap_v4.

1. Сделайте копию шаблона карточки

Для отдельного catalog.element скопируйте всю папку /bitrix/components/bitrix/catalog.element/templates/.default/ в /local/templates/.default/components/bitrix/catalog.element/loyalty_product/. В параметрах компонента выберите шаблон loyalty_product. Если сейчас выбран bootstrap_v4, копируйте именно его.

Если карточка находится внутри комплексного bitrix:catalog, раскройте пояснение ниже: путь будет другим.

2. Добавьте блок под ценой

В template.php вашей копии найдите div с классом product-item-detail-price-current и $itemIds['PRICE_ID']. Вставьте код сразу после закрывающего </div> этой цены, до следующего PHP-блока. Это основная цена в секции case 'price', а не цена в плавающей панели panel-price.

<?php
$APPLICATION->IncludeComponent(
    'qwelp:loyalty.earning',
    '',
    ['MODE' => 'PRODUCT', 'USE_PARENT' => 'Y', 'SITE_ID' => ''],
    $component
);
?>

$component передаёт текущий товар. Его нельзя убирать или заменять фиксированным ID. Цена, скидка и выбранное предложение читаются из результата catalog.element.

3. Проверьте товар

Откройте доступный товар с ценой. При базовом правиле 3% и цене 1000 ожидается +30 баллов. Если покупатель может менять количество, размер или цвет, выполните дополнительный шаг ниже.

Есть количество или торговые предложения — подключите обновление

В script.js той же копии найдите метод setPrice: function(). Вставьте этот фрагмент в самый конец тела метода, перед его закрывающей скобкой. Не вставляйте его за пределами метода: price и this относятся к текущей карточке.

var loyaltyApi = BX.Qwelp && BX.Qwelp.Loyalty && BX.Qwelp.Loyalty.Earning;
var loyaltyRoot = this.obProduct && this.obProduct.querySelector('[data-qwelp-loyalty-earning]');
if (loyaltyApi && loyaltyRoot) {
    loyaltyApi.updateProduct(
        loyaltyRoot,
        price ? Number(price.PRICE) : 0,
        this.obQuantity ? Number(this.obQuantity.value) : Number(this.stepQuantity || 1),
        this.canBuy === true || this.canBuy === 'Y'
    );
}

Если рядом есть script.min.js или script.map.js, пересоберите их из изменённого script.js либо удалите эти два сгенерированных файла только из вашей копии шаблона. Иначе Битрикс может продолжить отдавать старый минифицированный код. После этого сбросьте кеш компонента и объединённых JS-файлов штатной кнопкой «Сбросить кеш».

Штатный setPrice() вызывается после изменения количества, ценового диапазона и предложения. Используется PRICE за одну единицу × количество; RATIO_PRICE уже содержит коэффициент единицы измерения и здесь не нужен. Очистите кеш страницы и JS, смените SKU и количество, проверьте недоступное предложение. Для изменённого сторонним разработчиком script.js сначала сверьте наличие этих полей.

Карточка внутри комплексного bitrix:catalog

Если на странице установлен «Каталог», а отдельного catalog.element в списке компонентов страницы нет, копируйте активный шаблон комплексного каталога в /local/templates/.default/components/bitrix/catalog/loyalty_catalog/ и выберите эту копию в параметрах каталога.

Внутри копии найдите вложенный bitrix/catalog.element/ИМЯ_ВЛОЖЕННОГО_ШАБЛОНА/. Правьте его template.php и script.js. Если папки нет, посмотрите имя шаблона во вложенном вызове catalog.element в element.php: скопируйте соответствующий стандартный шаблон в эту вложенную папку. Пустое имя означает .default.

Не размещайте прогноз в element.php рядом с вызовом catalog.element: в этой точке нет результата самого товара. Вставка должна находиться в шаблоне карточки под ценой.

У меня другой шаблон или нужна карточка в списке каталога

В шаблоне bitrix:catalog.item используется такой же вызов с $component. Поддержаны ITEM, OFFERS/OFFERS_SELECTED, ITEM_PRICES/ITEM_PRICE_SELECTED/RATIO_PRICE и MIN_PRICE/DISCOUNT_VALUE. При другой структуре данных используйте параметры из вкладки «Параметры» и передавайте цену через updateProduct.

В свой обработчик цены передавайте DOM-корень именно изменённой карточки, цену числом за одну единицу, количество и boolean доступности. Этот прогноз показывает безусловный базовый бонус; персональные акции окончательно рассчитываются по заказу.

Корзина

Результат: под стандартной корзиной появятся прогноз начисления и возможность списать баллы. Компонент магазина — bitrix:sale.basket.basket; стандартный шаблон .default или bootstrap_v4.

1. Откройте страницу корзины

Найдите существующий вызов bitrix:sale.basket.basket в файле страницы корзины. Адрес может отличаться: используйте страницу вашего магазина, а не фиксированный путь из примера другого сайта.

2. Вставьте код после компонента корзины

Закончите PHP-блок существующего вызова и вставьте два отдельных блока ниже. Это самый простой способ: стандартный шаблон корзины менять не требуется.

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.earning', '', [
    'MODE' => 'BASKET', 'SITE_ID' => '',
]);
?>
<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.redeem', '', [
    'SITE_ID' => '', 'REFRESH_MODE' => 'RELOAD',
]);
?>

На странице достаточно одного блока списания. RELOAD после применения или отмены баллов обновляет всю страницу и итоги корзины.

3. Проверьте изменение корзины

Добавьте товар, измените количество и удалите позицию. Стандартное событие OnBasketChange обновляет виджеты. У гостя списание недоступно; для проверки войдите под тестовым покупателем с баллами. Пустая корзина не должна предлагать списание.

Нужно разместить рядом с итоговой суммой

Скопируйте активный шаблон корзины в /local/templates/.default/components/bitrix/sale.basket.basket/loyalty_basket/ и выберите loyalty_basket в параметрах. Разместите вызовы в его template.php в отдельном контейнере, который AJAX не пересоздаёт. Не вставляйте PHP в клиентский шаблон строки товара: он заполняется JavaScript.

Сначала проверьте простой вариант под корзиной. Он позволяет убедиться, что модуль работает, до изменения расположения.

Нестандартная AJAX-корзина

Если свой шаблон не отправляет OnBasketChange, после сохранения корзины и пересчёта её цен отправьте:

BX.onCustomEvent('QwelpLoyalty:onBasketRefresh');

Само событие обновляет только виджеты лояльности. Оно не сохраняет корзину и не пересчитывает магазин вместо его скрипта.

Оформление заказа

Результат: покупатель применяет баллы, а стандартный bitrix:sale.order.ajax пересчитывает итог без полной перезагрузки страницы. Поддерживается штатный JS шаблонов .default и bootstrap_v4.

1. Сделайте копию шаблона оформления

Скопируйте активную папку /bitrix/components/bitrix/sale.order.ajax/templates/.default/ в /local/templates/.default/components/bitrix/sale.order.ajax/loyalty_checkout/. Если выбран bootstrap_v4, копируйте его. В параметрах компонента оформления выберите loyalty_checkout.

2. Вставьте блок перед формой заказа

В template.php копии найдите <form с id="bx-soa-order-form". Сразу перед этим тегом, после существующего ?>, вставьте код ниже. В стандартном шаблоне это находится внутри ветки else обычного оформления — после проверок ORDER_ID и пустой корзины.

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.earning', '', [
    'MODE' => 'BASKET', 'SITE_ID' => '',
]);
?>
<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.redeem', '', [
    'SITE_ID' => '', 'REFRESH_MODE' => 'CHECKOUT',
]);
?>

Форма заказа остаётся сразу после этих блоков. Так списание не попадёт в confirm.php, не исчезнет при перерисовке итогов и не создаст вложенную форму. Не добавляйте одновременно второй блок списания на страницу оформления.

3. Проверьте применение баллов

Войдите под тестовым покупателем с баллами, заполните контакты, примените списание и отмените его. Сумма заказа должна меняться, а введённые поля — сохраняться. Enter в поле баллов не должен оформлять заказ. В штатном order_ajax.js ничего добавлять не требуется.

Что означает CHECKOUT и почему прогноз может измениться

CHECKOUT вызывает штатный BX.Sale.OrderAjaxComponent.sendRequest('refreshOrderAjax'). Не добавляйте второй обработчик того же пересчёта.

Прогноз берётся по сохранённым товарам корзины. Ещё не сохранённые условия доставки, оплаты и свойства заказа могут повлиять на окончательное начисление после оплаты. Максимум списания сервер проверяет повторно; доставка его не увеличивает.

У меня оформление другого разработчика

REFRESH_MODE=CHECKOUT подходит только при наличии штатного BX.Sale.OrderAjaxComponent. Для другого оформления выберите EVENT. В своём скрипте один раз подпишитесь на QwelpLoyalty:onChanged, выполните штатный пересчёт вашего заказа и после его завершения отправьте QwelpLoyalty:onBasketRefresh.

Событие onChanged передаёт siteId и action (redeem или cancelCurrentRedeem). Без обработчика пересчёта режим EVENT не завершает подключение. Не заменяйте собственную форму заказа копией шаблона shop.light.

Баланс и кабинет

Эти блоки можно разместить на обычных страницах Битрикс через визуальный редактор или PHP. У каждого — отдельная задача.

Краткий баланс

Для шапки или страницы личного кабинета:

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.summary', '', ['SITE_ID' => '']);
?>

Баланс и история операций

Создайте обычную страницу в личном кабинете, например personal/loyalty/ относительно корня вашего сайта. Разместите компонент и добавьте ссылку в меню:

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.account', '', [
    'SITE_ID' => '', 'HISTORY_LIMIT' => '20', 'ORDER_URL_TEMPLATE' => '',
]);
?>

Просмотр страницы не начисляет баллы и не создаёт участника. Покупатель видит только свои данные.

Условия программы

Создайте страницу для покупателей и вставьте:

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.page', '', [
    'IBLOCK_ID' => '0', 'LANGUAGE_ID' => '',
    'CACHE_TYPE' => 'A', 'CACHE_TIME' => '86400', 'TITLE_TAG' => 'h2',
]);
?>

Тексты редактируются в созданном модулем инфоблоке qwelp_loyalty_page. Проверьте ссылки кнопок и добавьте страницу в меню.

В стандартном шаблоне Битрикса заголовок H1 обычно выводит сама страница, поэтому в примере выбран TITLE_TAG=h2. Если заголовка страницы нет, выберите h1 в параметрах компонента.

Другие адреса заказов и настройка текстов

Пустой ORDER_URL_TEMPLATE использует personal/orders/#ID#/ от корня текущего сайта. Если у вас другие адреса, задайте свой локальный путь с #ID#.

IBLOCK_ID=0 выбирает инфоблок модуля, LANGUAGE_ID='' — текущий язык. У элементов контента BLOCK_TYPE задаёт блок, LANGUAGE — язык, EXTRA_VALUE — подпись, номер или локальный URL. Подстановки #EARN_PERCENT#, #POINT_RATE#, #PENDING_DAYS#, #EXPIRE_DAYS# и #MIN_REDEEM_POINTS# берут значения из настроек.

Отдельный универсальный компонент отчёта о баллах одного заказа не поставляется. Для такого отчёта разработчик может использовать OrderBonusViewService после проверки доступа к заказу.

Списание реализовано техническим купоном. Сам блок модуля показывает баллы, но стандартные шаблоны корзины и заказа могут также выводить код этого купона в своём списке скидок. Это штатное отображение Битрикса; скрытие таких кодов требует настройки вашей копии шаблона. Прогноз корзины учитывает рассчитанные товарные скидки; условия будущего заказа, зависящие от выбранной доставки, оплаты или свойств, окончательно проверяются после оплаты.

Параметры

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

Компонент / параметрПо умолчаниюКогда менять
earning, account, summary, redeem: SITE_IDпустоТолько для явного выбора другого активного сайта
earning: MODEBASKETPRODUCT для товара, BASKET для корзины/заказа
earning: USE_PARENTYN для своей структуры данных
earning: UNIT_PRICE / QUANTITY0 / 1Фиксированные числовые значения при USE_PARENT=N
earning: AVAILABLEYN скрывает прогноз при USE_PARENT=N
redeem: REFRESH_MODERELOADCHECKOUT для штатного заказа; EVENT для своего адаптера
account: HISTORY_LIMIT20Число операций от 1 до 100
account: ORDER_URL_TEMPLATEпуть текущего сайтаЛокальный путь к заказу с #ID#
page: IBLOCK_ID / LANGUAGE_ID0 / пустоДругой инфоблок условий или язык
page: TITLE_TAGh1h2, если шаблон сайта уже выводит H1 страницы
page: CACHE_TYPE / CACHE_TIMEA / 36000000Режим и срок кеширования содержимого в секундах

Курс баллов задаёт стоимость списания одного балла, а не процент начисления. Правила и сроки меняются в настройках программы, а не в PHP-вставках.

Проверочный пример без родительского товара

Для проверки на обычной странице можно задать цену вручную. Такой блок не узнает реальную цену товара сам:

<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.earning', '', [
    'MODE' => 'PRODUCT', 'USE_PARENT' => 'N',
    'UNIT_PRICE' => '1000', 'QUANTITY' => '1', 'AVAILABLE' => 'Y', 'SITE_ID' => '',
]);
?>

В настоящей карточке передавайте цену из её модели через updateProduct; не оставляйте тестовую цену 1000.

Доступ, несколько сайтов и удаление

Права D/R/W задаются через «Настройки → Настройки продукта → Настройки модулей → qwelp.loyalty → Доступ». Для чтения документации достаточно R.

Оставляйте SITE_ID пустым для текущего сайта; на дополнительном сайте проверьте его корзину, пути страниц и меню. Удаление модуля сначала проверяйте на стенде. Ручные вставки и ссылки удалите со страниц либо защитите загрузкой модуля:

<?php if (\Bitrix\Main\Loader::includeModule('qwelp.loyalty')): ?>
<?php
$APPLICATION->IncludeComponent('qwelp:loyalty.summary', '', ['SITE_ID' => '']);
?>
<?php endif; ?>

Проверка

Кеширование и свои шаблоны персональных блоков

Стандартные account, summary и redeem сначала выводят нейтральный HTML, затем получают значения текущего пользователя через AJAX. Не записывайте баланс или историю в общий кеш родительского компонента. Ответ getBalance запрещает кеширование и не принимает ID другого покупателя; historyLimit ограничен диапазоном 0–100, для краткого баланса используйте 0. При выходе из аккаунта или восстановлении страницы из истории браузера данные запрашиваются заново.

Если раньше копировали шаблоны этих компонентов, перенесите из текущей поставки нейтральную разметку и подключение JS-расширений. Один вызов setFrameMode(true) не защищает персональный HTML внутри общего кеша.

Пройдите этот короткий список после подключения на своём шаблоне.

  1. В товаре есть прогноз; после изменения количества или SKU он обновляется.
  2. В корзине прогноз и предел списания меняются после изменения товаров.
  3. Тестовый покупатель с баллами может применить и отменить списание; итог заказа пересчитывается.
  4. В оформлении контакты сохраняются, Enter в поле баллов не отправляет заказ.
  5. Гость не видит чужой баланс; на телефоне текст, поле и кнопки доступны.

Если что-то не работает

Что произошлоЧто проверить
Нет бонуса у товараПрограмма и базовое правило активны, товар доступен, цена положительная, передан $component
Прогноз не меняется вместе с SKUФрагмент добавлен в конец setPrice() копии script.js; очищен кеш JS
Нет поля списанияПокупатель вошёл, есть доступные баллы, сумма корзины и баланс выше минимума
Баллы применились, итог старыйCHECKOUT для стандартного sale.order.ajax; для EVENT выполнен адаптер пересчёта
После редактора пропал соседний блокКаждый IncludeComponent находится в отдельном PHP-блоке
Нет компонента в редактореУстановка завершилась, файлы есть в /bitrix/components/qwelp/; пользовательские копии в /local/components/qwelp/ могут иметь приоритет
Полная проверка перед запуском магазина

На тестовом заказе проверьте оплату, ожидание начисления, доступность баллов, отмену и повторную оплату без дублей. Испытания сгорания и сроков выполняйте на стенде, не меняя условия живым покупателям.

Проверьте сочетание с обычным промокодом, удаление/отложение товара и пустую корзину. Выключите программу на стенде: новые прогнозы и списание скрываются, существующее списание можно отменить.

Сохраните параметры компонента в визуальном редакторе без изменений, затем с изменением допустимого значения. Вложенный earning должен сохранить четвёртый аргумент $component. Проверьте обе локализации и дополнительный сайт.

На страницах с Композитом сделайте два анонимных запроса с одной сессией: второй должен вернуть X-Bitrix-Composite: Cache (200). Проверьте виджеты после загрузки динамических зон. Корзина и оформление могут работать без Композита.

Это проверка интеграции с вашим шаблоном. Подготовка самой поставки к Marketplace требует отдельной проверки установки, удаления и совместимости.

Почему не начислились баллы после оплаты

Посмотрите оплату заказа, активность и условия правил, сроки ожидания, журнал операций и работу агентов. Восстановление пропущенных начислений запускается раз в 5 минут; оно не начисляет автоматически бонусы за всю историю до установки модуля. Предварительный текст у товара не является записью о начислении.

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