Корзина, личный кабинет и оплата на сайте

Стандартные компоненты модуля sale выводят на сайте корзину, личный кабинет покупателя и страницу оплаты. Компоненты сами загружают данные текущего покупателя, проверяют доступ к заказу и передают результат в шаблон. Адреса страниц и состав данных задают параметры компонентов. Свой код нужен, когда шаблону не хватает данных.

Форма оформления заказа bitrix:sale.order.ajax описана в статье Оформление заказа и публичные сценарии. Как устроены компоненты, их параметры и шаблоны, описано в статье Компоненты.

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

  • /personal/cart/ — корзина,

  • /personal/order/make/ — оформление заказа,

  • /personal/ — личный кабинет,

  • /personal/order/payment/ — оплата заказа.

Выбрать компонент

Задача Компонент
Страница корзины с изменением количества, купонами и переходом к оформлению bitrix:sale.basket.basket
Число товаров и сумма корзины в шапке сайта, ссылки на корзину и личный кабинет bitrix:sale.basket.basket.line
Форма оформления заказа bitrix:sale.order.ajax, подробнее — в статье Оформление заказа и публичные сценарии
Личный кабинет — заказы, профили, внутренний счет, личные данные и подписки bitrix:sale.personal.section — комплексный компонент, внутри подключает компоненты отдельных страниц
Страница запуска платежной системы bitrix:sale.order.payment
Поле выбора местоположения в своей форме bitrix:sale.location.selector.search или bitrix:sale.location.selector.steps, подробнее — в разделе Выбрать местоположение в форме

Для личного кабинета используйте комплексный компонент bitrix:sale.personal.section. Комплексные компоненты bitrix:sale.personal.order и bitrix:sale.personal.profile выводят только заказы или только профили.

Компоненты bitrix:sale.personal.order.list, bitrix:sale.personal.order.detail, bitrix:sale.personal.order.cancel, bitrix:sale.personal.profile.list, bitrix:sale.personal.profile.detail, bitrix:sale.personal.account и bitrix:sale.account.pay подключайте отдельно, только если кабинет собран из собственных страниц.

Компоненты ссылаются друг на друга через параметры PATH_TO_*. Корзина ведет на оформление, кабинет — на корзину и оплату, оформление — на оплату. Значения по умолчанию у компонентов разные, поэтому передавайте адреса во все компоненты в параметрах вызова.

Параметр Компоненты Куда ведет ссылка Значение по умолчанию
PATH_TO_BASKET sale.basket.basket.line, sale.personal.section, sale.order.ajax Страница корзины /personal/cart/, у sale.basket.basket.line — personal/cart/ в папке сайта
PATH_TO_ORDER sale.basket.basket, sale.basket.basket.line Страница оформления заказа /personal/order/make/, у sale.basket.basket.line — personal/order/make/ в папке сайта
PATH_TO_PERSONAL sale.basket.basket.line Личный кабинет personal/ в папке сайта
PATH_TO_CATALOG sale.personal.section Каталог — ссылка из списка заказов /catalog/
PATH_TO_CONTACT sale.personal.section Страница контактов — плитка на главной кабинета /about/contacts/
PATH_TO_PAYMENT sale.personal.section, sale.order.ajax Страница с компонентом sale.order.payment /personal/order/payment/ у sale.personal.section, относительный payment.php у sale.order.ajax

У компонента sale.basket.basket.line адреса по умолчанию начинаются с папки текущего сайта. У sale.basket.basket и sale.personal.section адреса по умолчанию указаны от корня домена, а у sale.order.ajax адрес оплаты относительный. Для сайта в подпапке передайте полные адреса с папкой сайта.

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

Вывести корзину

Компонент bitrix:sale.basket.basket показывает корзину текущего посетителя. Корзина привязана к покупателю FUSER, поэтому работает и до авторизации. Как покупатель связан с посетителем и пользователем, описано в разделе Различить посетителя, пользователя и покупателя корзины.

Компонент не кеширует результат, потому что корзина меняется при каждом действии покупателя. Когда покупатель меняет количество, удаляет или откладывает товар, применяет купон, шаблон отправляет AJAX-запрос, а компонент пересчитывает корзину со скидками и возвращает обновленные данные.

Пример. Подключите корзину в файле /personal/cart/index.php.

<?php
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php';

$APPLICATION->SetTitle('Корзина');

$APPLICATION->IncludeComponent(
    'bitrix:sale.basket.basket',
    'bootstrap_v4',
    [
        'PATH_TO_ORDER' => '/personal/order/make/',
        'COLUMNS_LIST_EXT' => ['PREVIEW_PICTURE', 'DISCOUNT', 'PROPS', 'DELETE', 'DELAY', 'SUM'],
        'HIDE_COUPON' => 'N',
        'QUANTITY_FLOAT' => 'N',
        'EMPTY_BASKET_HINT_PATH' => '/catalog/',
        'SET_TITLE' => 'N',
    ]
);

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/footer.php';

Кнопка оформления заказа ведет на PATH_TO_ORDER. Кнопка неактивна, если в корзине нет товаров, доступных для покупки.

Настроить колонки и действия

Набор колонок определяет вид корзины и разрешенные действия. Без колонки DELETE компонент не удаляет товар, без колонки DELAY не откладывает его, даже если запрос пришел.

Параметр Тип Описание
COLUMNS_LIST_EXT array Колонки корзины — PREVIEW_PICTURE, DETAIL_PICTURE, PREVIEW_TEXT, DISCOUNT, WEIGHT, PROPS, DELETE, DELAY, TYPE, SUM и PROPERTY_<CODE> для свойств товара. Название, количество и цену компонент выводит всегда. По умолчанию PREVIEW_PICTURE, DISCOUNT, DELETE, DELAY, TYPE, SUM
HIDE_COUPON Y или N Скрыть поле ввода купона. При Y компонент не принимает купоны. По умолчанию N. Купоны создают для правил работы с корзиной, подробнее — в разделе Работать с купонами
QUANTITY_FLOAT Y или N Разрешить дробное количество. По умолчанию Y
PRICE_VAT_SHOW_VALUE Y или N Показывать сумму НДС. По умолчанию Y
SHOW_RESTORE Y или N Разрешить вернуть удаленный товар. По умолчанию Y
OFFERS_PROPS array Свойства торговых предложений, по которым покупатель меняет предложение прямо в корзине. Если в настройках модуля Информационные блоки включено использование параметров свойств в компонентах, компонент берет свойства из настроек торгового каталога и параметр не учитывает. Настройка модуля включена по умолчанию
USE_GIFTS Y или N Показывать блок подарков. По умолчанию Y
SET_TITLE Y или N Установить заголовок страницы «Моя корзина». По умолчанию N

Параметр COLUMNS_LIST — прежнее имя набора колонок. Компонент учитывает его, только если COLUMNS_LIST_EXT не передан.

Параметры DISPLAY_MODE, TOTAL_BLOCK_DISPLAY, TEMPLATE_THEME, метки и процент скидки задают оформление. Они относятся к шаблону и перечислены в настройках компонента в визуальном редакторе.

Показать пустую корзину

Если в корзине нет товаров, шаблон показывает сообщение о пустой корзине и ссылку для продолжения покупок. Адрес ссылки задает параметр шаблона EMPTY_BASKET_HINT_PATH, по умолчанию /. Пустое значение скрывает ссылку.

Показать корзину в шапке сайта

Компонент bitrix:sale.basket.basket.line выводит число товаров и сумму корзины, ссылки на корзину, личный кабинет и авторизацию. Обычно его подключают в шаблоне сайта, поэтому компонент выводит блок на каждой странице.

Пример. Выведите ссылку на корзину с числом товаров и суммой в header.php шаблона сайта.

$APPLICATION->IncludeComponent(
    'bitrix:sale.basket.basket.line',
    'bootstrap_v4',
    [
        'PATH_TO_BASKET' => SITE_DIR . 'personal/cart/',
        'PATH_TO_ORDER' => SITE_DIR . 'personal/order/make/',
        'PATH_TO_PERSONAL' => SITE_DIR . 'personal/',
        'SHOW_NUM_PRODUCTS' => 'Y',
        'SHOW_TOTAL_PRICE' => 'Y',
        'SHOW_PERSONAL_LINK' => 'Y',
        'SHOW_AUTHOR' => 'Y',
        'SHOW_PRODUCTS' => 'N',
    ]
);

Константа SITE_DIR содержит папку текущего сайта. Число товаров — это количество позиций корзины, доступных для покупки, а не сумма их количества.

Параметр Тип Описание
SHOW_NUM_PRODUCTS, SHOW_TOTAL_PRICE Y или N Показывать число товаров и сумму. По умолчанию Y
SHOW_PERSONAL_LINK Y или N Показывать ссылку на PATH_TO_PERSONAL. По умолчанию N
SHOW_AUTHOR Y или N Показывать ссылки входа и регистрации или имя пользователя. По умолчанию N
PATH_TO_REGISTER, PATH_TO_PROFILE string Страница регистрации и профиля пользователя. Регистрация по умолчанию ведет на страницу из настроек главного модуля, а если она не задана — на login/ в папке сайта. Профиль по умолчанию — personal/ в папке сайта
PATH_TO_AUTHORIZE string Страница входа для ссылки, которую выводит SHOW_AUTHOR. По умолчанию совпадает с PATH_TO_REGISTER
SHOW_PRODUCTS Y или N Показывать список товаров во всплывающем блоке. По умолчанию N
SHOW_DELAY, SHOW_NOTAVAIL Y или N Показывать в списке отложенные товары и товары, недоступные для покупки. По умолчанию Y
HIDE_ON_BASKET_PAGES Y или N Не показывать корзину на страницах, адрес которых начинается с PATH_TO_BASKET или PATH_TO_ORDER. По умолчанию Y
POSITION_FIXED Y или N Закрепить блок поверх страницы. По умолчанию N. Положение задают POSITION_VERTICAL — top, bottom или vcenter, по умолчанию top, и POSITION_HORIZONTAL — right, left или hcenter, по умолчанию right

Если SHOW_PRODUCTS = Y, компонент заново рассчитывает корзину со скидками при каждом открытии страницы. Для шапки, которая выводится на всех страницах, оставьте N, если список товаров не нужен.

При HIDE_ON_BASKET_PAGES = Y на страницах корзины и оформления компонент скрывает число товаров, сумму и список товаров. Если включен SHOW_AUTHOR, на этих страницах компонент скрывает и ссылку на кабинет. Если выключены SHOW_AUTHOR и SHOW_PERSONAL_LINK, компонент на этих страницах ничего не выводит.

Обновить счетчик после изменения корзины

Шаблоны компонента подписаны на JS-событие OnBasketChange. Получив событие, компонент запрашивает новые данные с сервера и перерисовывает блок. Корзина sale.basket.basket и карточка товара catalog.item вызывают это событие сами.

Если собственный код добавляет товар в корзину без перезагрузки страницы, вызовите событие после успешного ответа сервера. Как работают JS-события ядра, описано в разделе Работать с событиями.

Пример. Обновите блок корзины в шапке после добавления товара собственным AJAX-запросом.

BX.onCustomEvent('OnBasketChange');

Собрать личный кабинет

Комплексный компонент bitrix:sale.personal.section собирает кабинет покупателя из нескольких страниц. Каждую страницу выводит отдельный компонент, а комплексный компонент передает ему адреса соседних страниц и общие настройки.

Подключить кабинет с ЧПУ

Чтобы адреса страниц кабинета были вида /personal/orders/15/, используйте режим ЧПУ — человекопонятных адресов. Режим включен по умолчанию — параметр SEF_MODE со значением Y. Папку кабинета передайте в SEF_FOLDER, шаблоны адресов — в SEF_URL_TEMPLATES. Ключи массива задают страницы кабинета, #ID# — номер заказа или идентификатор профиля.

Пример. Подключите кабинет в файле /personal/index.php.

<?php
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php';

$APPLICATION->SetTitle('Личный кабинет');

$APPLICATION->IncludeComponent(
    'bitrix:sale.personal.section',
    'bootstrap_v4',
    [
        'SEF_MODE' => 'Y',
        'SEF_FOLDER' => '/personal/',
        'SEF_URL_TEMPLATES' => [
            'index' => 'index.php',
            'orders' => 'orders/',
            'order_detail' => 'orders/#ID#',
            'order_cancel' => 'cancel/#ID#',
            'account' => 'account/',
            'profile' => 'profiles/',
            'profile_detail' => 'profiles/#ID#',
            'private' => 'private/',
            'subscribe' => 'subscribe/',
        ],
        'PATH_TO_BASKET' => '/personal/cart/',
        'PATH_TO_PAYMENT' => '/personal/order/payment/',
        'PATH_TO_CATALOG' => '/catalog/',
        'ORDER_HISTORIC_STATUSES' => ['F'],
        'ORDERS_PER_PAGE' => 20,
        'ACCOUNT_PAYMENT_PERSON_TYPE' => $personTypeId,
        'SET_TITLE' => 'Y',
        'CACHE_TYPE' => 'A',
        'CACHE_TIME' => 3600,
    ]
);

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/footer.php';

Переменная $personTypeId содержит ID типа плательщика. С этим типом форма пополнения внутреннего счета создает заказ, подробнее — в разделе Настроить пополнение внутреннего счета. Типы плательщиков описаны в разделе Создать тип плательщика.

Передайте все шаблоны адресов, которые использует кабинет. Если в SEF_URL_TEMPLATES нет ключа order_cancel, компонент строит адрес отмены по шаблону orders/order_cancel.php?ID=#ID#, а визуальный редактор показывает cancel/#ID#.

Чтобы запросы /personal/... попадали на файл /personal/index.php, нужно правило обработки адресов. Визуальный редактор добавляет его при сохранении страницы. Если страница создана в коде, добавьте правило методом Bitrix\Main\UrlRewriter::add(), например в скрипте установки решения. Первый аргумент — код сайта, второй — массив правила с ключами:

  • CONDITION — регулярное выражение адреса,

  • ID — имя компонента,

  • PATH — файл, который обрабатывает адрес,

  • RULE — правило подстановки, для комплексного компонента пустая строка.

Если правило с таким же условием уже есть, метод ничего не меняет. Правила urlrewrite.php описаны в разделе Миграция с устаревшего urlrewrite.php.

Пример. Добавьте правило для личного кабинета.

\Bitrix\Main\UrlRewriter::add(SITE_ID, [
    'CONDITION' => '#^/personal/#',
    'RULE' => '',
    'ID' => 'bitrix:sale.personal.section',
    'PATH' => '/personal/index.php',
]);

Страницы корзины /personal/cart/ и оформления /personal/order/make/ — отдельные файлы. Правило не перехватывает адреса существующих файлов, поэтому эти страницы продолжают работать внутри папки кабинета.

В режиме без ЧПУ страницу выбирает параметр адреса SECTION с ключом страницы — orders, profile, private, account или subscribe, например ?SECTION=orders для списка заказов. Без SECTION кабинет показывает главную страницу. Заказ, отмену и профиль открывают адреса с ID:

  • ?SECTION=orders&ID=<номер> — заказ,

  • ?SECTION=orders&ID=<номер>&CANCEL=Y — отмена заказа,

  • ?SECTION=profile&ID=<идентификатор> — профиль покупателя.

Выбрать страницы кабинета

Главная страница кабинета показывает плитки-ссылки на включенные страницы. Каждую страницу включает параметр SHOW_<СТРАНИЦА>_PAGE, по умолчанию все страницы включены. Если страница выключена, переход на ее адрес перенаправляет покупателя на главную страницу кабинета.

Ключ SEF_URL_TEMPLATES Параметр Компонент страницы Что видит покупатель
orders SHOW_ORDER_PAGE sale.personal.order.list Текущие заказы, историю и отмененные заказы
order_detail SHOW_ORDER_PAGE sale.personal.order.detail Состав, оплаты, отгрузки и свойства одного заказа
order_cancel SHOW_ORDER_PAGE sale.personal.order.cancel Форму отмены заказа с причиной
profile, profile_detail SHOW_PROFILE_PAGE sale.personal.profile.list, sale.personal.profile.detail Сохраненные профили покупателя, редактирование и удаление
account SHOW_ACCOUNT_PAGE sale.personal.account, sale.account.pay Баланс внутреннего счета и форму пополнения
private SHOW_PRIVATE_PAGE main.profile Личные данные пользователя и смену пароля
subscribe SHOW_SUBSCRIBE_PAGE catalog.product.subscribe.list Подписки на поступление товаров

Параметры SHOW_BASKET_PAGE и SHOW_CONTACT_PAGE включают на главной странице кабинета ссылки на корзину и контакты. Адреса компонент берет из PATH_TO_BASKET и PATH_TO_CONTACT.

Ссылки на собственные страницы добавляет параметр CUSTOM_PAGES. Он принимает строку с JS-массивом, каждый элемент которого содержит адрес страницы, название и класс иконки Font Awesome. Иконку можно не указывать — передайте пустую строку.

Пример. Добавьте на главную страницу кабинета ссылку на раздел документов.

'CUSTOM_PAGES' => '[["/personal/documents/", "Документы", "fa-file-text-o"]]',

Страница по адресу из CUSTOM_PAGES в кабинет не встраивается. Создайте ее отдельным файлом.

Страница внутреннего счета работает только в редакциях с внутренними счетами покупателей. В остальных редакциях компонент выключает ее сам, как и страницу подписок, если на сайте нет компонента catalog.product.subscribe.list. Как устроен внутренний счет, описано в разделе Работать с внутренним счетом.

Страницы кабинета, кроме главной, доступны только авторизованному пользователю. По умолчанию каждая страница сама показывает форму авторизации. Чтобы вместо этого перенаправлять покупателя на страницу входа кабинета, передайте USE_PRIVATE_PAGE_TO_AUTH со значением Y. В этом режиме кабинет использует еще три ключа SEF_URL_TEMPLATES — login, password_change и password_restore, по умолчанию login/, password/change/ и password/restore/.

Настроить список заказов

Список показывает заказы текущего пользователя на текущем сайте. Список делится на три вкладки:

  • текущие заказы — не отмененные, со статусом не из ORDER_HISTORIC_STATUSES,

  • история — заказы со статусами из ORDER_HISTORIC_STATUSES,

  • отмененные заказы.

Комплексный компонент получает параметры списка с префиксом ORDER_, кроме ORDERS_PER_PAGE, ALLOW_INNER и ONLY_INNER_FULL.

Параметр Тип Описание
ORDER_HISTORIC_STATUSES array Статусы заказов, которые попадают во вкладку истории. Если параметр не передан или пуст, история содержит заказы в статусе F
ORDERS_PER_PAGE int Количество заказов на странице. По умолчанию 20
ORDER_DEFAULT_SORT string Начальная сортировка списка. По умолчанию STATUS — по порядку статусов
ORDER_DISALLOW_CANCEL Y или N Запретить покупателю отменять заказы. По умолчанию N
ORDER_RESTRICT_CHANGE_PAYSYSTEM array Статусы заказов, в которых покупатель не может сменить платежную систему
ORDER_REFRESH_PRICES Y или N Пересчитать цены заказа при смене платежной системы. По умолчанию N
ALLOW_INNER, ONLY_INNER_FULL Y или N Разрешить оплату с внутреннего счета и только на полную сумму оплаты. По умолчанию N

Комплексный компонент не читает параметр PER_PAGE из прежних примеров. Для числа заказов на странице передавайте ORDERS_PER_PAGE.

У неоплаченного заказа список показывает кнопку оплаты и смены платежной системы. Смену выполняет компонент sale.order.payment.change внутри AJAX-запроса списка или детальной страницы. Отдельно на странице его не подключают.

Ссылка «Повторить заказ» добавляет в корзину товары заказа, которые сейчас доступны для покупки, и переводит покупателя на PATH_TO_BASKET. Если товар с теми же свойствами уже лежит в корзине, компонент суммирует количество.

Ограничить данные на странице заказа

Детальная страница заказа показывает состав заказа, оплаты, отгрузки, свойства заказа и данные пользователя. Часть данных скрывают параметры комплексного компонента. Параметр ORDER_HIDE_USER_INFO передайте с префиксом, а PROP_<ID> и CUSTOM_SELECT_PROPS — без него.

Параметр Тип Описание
ORDER_HIDE_USER_INFO array Данные пользователя, которые страница не показывает — LOGIN, EMAIL, PERSON_TYPE_NAME. Комплексный компонент передает его во вложенный компонент как HIDE_USER_INFO
PROP_<ID> array Идентификаторы свойств заказа, которые страница не показывает для типа плательщика с идентификатором <ID>, например PROP_1
CUSTOM_SELECT_PROPS array Дополнительные свойства товаров из инфоблока в формате PROPERTY_<CODE> или PROPERTY_<ID>. Компонент добавляет значения к строкам состава заказа в ключах PROPERTY_<CODE>_VALUE. Стандартные шаблоны эти значения не выводят, выведите их в копии шаблона

Разрешить отмену заказа

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

  • не отменен,

  • не оплачен,

  • находится не в статусе F — финальном статусе заказа.

Список статусов заказа описан в статье Статусы и события. Статус F скрывает кнопку независимо от ORDER_HISTORIC_STATUSES. При ORDER_DISALLOW_CANCEL = Y кнопка скрыта, а страница отмены кабинета перенаправляет на список заказов.

Перед отменой компонент sale.personal.order.cancel проверяет, что заказ принадлежит текущему пользователю, не оплачен и не отгружен. Статус заказа и запрет отмены компонент не проверяет. Если подключаете его отдельно от кабинета, проверьте их на странице до вызова компонента.

Причину отмены покупатель вводит в форме, компонент сохраняет ее в поле REASON_CANCELED заказа. После отмены компонент перенаправляет покупателя на список заказов.

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

Настроить пополнение внутреннего счета

На странице счета кабинет показывает баланс и форму пополнения sale.account.pay. Компонент sale.account.pay создает заказ на выбранную сумму и показывает форму выбранной платежной системы. Если платежная система открывается в новом окне, форма открывает страницу PATH_TO_PAYMENT. Форма доступна только авторизованному пользователю.

Комплексный компонент получает параметры формы с префиксом ACCOUNT_PAYMENT_. Показ формы включает параметр SHOW_ACCOUNT_PAY_COMPONENT без префикса.

Параметр Тип Описание
SHOW_ACCOUNT_PAY_COMPONENT Y или N Показывать форму пополнения на странице счета. По умолчанию Y
ACCOUNT_PAYMENT_PERSON_TYPE int Идентификатор типа плательщика для заказа пополнения. Если параметр не передан, кабинет передает форме пустое значение и форма создает заказ пополнения без типа плательщика
ACCOUNT_PAYMENT_SELL_TOTAL array Суммы, которые покупатель выбирает кнопками. По умолчанию 100, 200, 500, 1000, 5000
ACCOUNT_PAYMENT_SELL_SHOW_FIXED_VALUES Y или N Показывать кнопки сумм. По умолчанию Y
ACCOUNT_PAYMENT_SELL_USER_INPUT Y или N Разрешить ввести свою сумму. По умолчанию Y
ACCOUNT_PAYMENT_SELL_CURRENCY string Валюта пополнения. Если параметр пуст, форма использует валюту сайта
ACCOUNT_PAYMENT_ELIMINATED_PAY_SYSTEMS array Идентификаторы платежных систем, которые форма не предлагает. Оплату с внутреннего счета форма не предлагает всегда

Всегда передавайте в ACCOUNT_PAYMENT_PERSON_TYPE тип плательщика, который существует на сайте. Свойства заказа пополнения форма заполняет из первого профиля покупателя для этого типа плательщика.

Открыть заказ по ссылке без авторизации

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

Гостевой просмотр выключен по умолчанию. Включите его в настройках модуля Интернет-магазин — параметр «Разрешить просмотр заказа по ключу без авторизации». В тех же настройках выберите статусы заказа, в которых просмотр разрешен, и шаблон адреса детальной страницы для каждого сайта с меткой #order_id#, например personal/orders/#order_id#.

Метод Bitrix\Sale\Helpers\Order::getPublicLink() возвращает ссылку на заказ с ключом доступа. Метод не проверяет, включен ли гостевой просмотр и разрешен ли он для статуса заказа, — это проверяет детальная страница при открытии ссылки. Чтобы не отправлять ссылку, которая не откроется, сначала вызовите метод Bitrix\Sale\Helpers\Order::isAllowGuestView(). Он возвращает true, если просмотр включен и статус заказа входит в выбранные.

Пример. Подготовьте ссылку на заказ для письма покупателю. Модуль sale подключен, переменная $order содержит загруженный объект Bitrix\Sale\Order, массив $mailFields — поля почтового события.

use Bitrix\Sale\Helpers\Order as OrderHelper;

$mailFields['ORDER_PUBLIC_URL'] = '';

if (OrderHelper::isAllowGuestView($order))
{
    $mailFields['ORDER_PUBLIC_URL'] = OrderHelper::getPublicLink($order);
}

Поле ORDER_PUBLIC_URL остается пустым, если просмотр запрещен для статуса заказа или для сайта не задан шаблон адреса с меткой #order_id#. Метку не ставьте в начало шаблона — с таким шаблоном метод тоже возвращает пустую строку. Как добавить поле в письмо по заказу, описано в разделе Изменить поля перед штатной отправкой.

В гостевом режиме страница заказа не показывает кнопки отмены, повтора заказа и смены платежной системы.

Если в кабинете включен USE_PRIVATE_PAGE_TO_AUTH = Y, кабинет перенаправляет неавторизованного посетителя на вход раньше, чем детальная страница проверит ключ. Для гостевых ссылок оставьте N.

Подключить страницу оплаты

Компонент bitrix:sale.order.payment запускает обработчик платежной системы для оплаты заказа. На эту страницу ведут ссылки «Оплатить» из подтверждения заказа и из личного кабинета, если платежная система открывается в новом окне.

Компонент сбрасывает уже выведенный HTML и выводит только ответ платежной системы. Подключите на странице prolog_before.php вместо header.php — он загружает ядро без вывода шаблона сайта. Варианты подключения описаны в разделе Подготовить контекст.

Пример. Создайте страницу оплаты /personal/order/payment/index.php.

<?php
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

$APPLICATION->IncludeComponent(
    'bitrix:sale.order.payment',
    '',
    []
);

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php';

У компонента нет параметров. Заказ и оплату он получает из адреса страницы:

  • ORDER_ID — номер заказа ACCOUNT_NUMBER или его ID,

  • PAYMENT_ID — идентификатор или номер оплаты,

  • HASH — ключ гостевого доступа к заказу,

  • RETURN_URL — адрес, на который платежная система вернет покупателя после оплаты.

Подтверждение заказа в sale.order.ajax строит ссылку вида /personal/order/payment/?ORDER_ID=<номер заказа>&PAYMENT_ID=<номер оплаты>. По такому же образцу формируйте ссылку на оплату в своем шаблоне или письме.

Компонент находит заказ текущего сайта, если выполнено одно из условий:

  • заказ принадлежит текущему пользователю,

  • номер заказа сохранен в сессии покупателя после оформления без авторизации,

  • HASH совпадает с ключом заказа, а гостевой просмотр разрешен для статуса заказа.

Если номера заказов задает шаблон нумерации, компонент сначала ищет заказ по номеру, затем по ID. Без шаблона нумерации компонент ищет заказ по ID. Оплату он берет из PAYMENT_ID. Если параметр не передан или такой оплаты в заказе нет, компонент берет первую неоплаченную оплату, кроме оплаты с внутреннего счета. Компонент не проверяет статус оплаты из PAYMENT_ID и запускает обработчик, даже если она уже оплачена.

Если оплату запустить нельзя, результат зависит от причины:

  • заказ не найден — сообщение «Заказ не найден»,

  • статус заказа не разрешает оплату или ключ не подошел — перенаправление на корень домена / без сообщения об ошибке,

  • подходящей оплаты нет или у оплаты не найдена платежная система — пустая страница,

  • платежная система вернула ошибку при запуске — текст ошибки без оформления.

Статус, начиная с которого разрешена оплата, задают в настройках модуля, подробнее — в разделе Разрешить оплату после проверки менеджером. Запуск обработчика из своего кода описан в разделе Запустить оплату.

Страница оплаты не принимает уведомления платежной системы о результате оплаты. Для них есть стандартная точка входа модуля, а для обработчика на классическом API — компонент bitrix:sale.order.payment.receive на отдельной странице. Подробнее — в разделе Обработать результат платежной системы.

Доработать шаблон компонента

Скопируйте шаблон компонента в папку /local/templates/<шаблон_сайта>/components/bitrix/<имя_компонента>/<имя_копии>/ и передайте имя копии вторым аргументом IncludeComponent(). Файлы в /bitrix/components/bitrix/ не изменяйте — обновление продукта перезапишет их. Шаблоны вложенных компонентов кабинета копируйте в папку шаблона комплексного компонента. Порядок поиска шаблонов описан в разделе Шаблоны компонента.

Данные, которых компонент не выбрал, добавьте в файле result_modifier.php копии шаблона. Как работает файл, описано в разделе Файл result_modifier.php.

Файл mutator.php шаблона корзины формирует строки и итоги после AJAX-пересчета. Компонент подключает его при каждом запросе, в том числе при пересчете. Данные строк корзины, которые должны обновляться после изменения количества, добавляйте в mutator.php копии шаблона.

Шаблон корзины bootstrap_v4 отправляет AJAX-запросы с подписанными параметрами и именем шаблона. Сохраните в template.php копии шаблона код, который передает эти параметры. Без подписи сервер отклоняет запрос пересчета.

Шаблоны sale.basket.basket.line выводят блок корзины в динамической области композитного сайта через $this->createFrame(). Сохраните этот вызов в копии шаблона. Без динамической области в кеш композитного сайта попадут число товаров и сумма корзины другого посетителя. Как работают динамические области, описано в статье Композитный сайт.

Проверить результат

Перед публикацией проверьте на тестовом сайте сценарии ниже.

  1. Добавьте товар в корзину из каталога и проверьте, что блок корзины в шапке обновил число товаров без перезагрузки страницы.

  2. Измените количество, удалите и отложите товар в корзине. Если действие не выполняется, проверьте колонки DELETE и DELAY в COLUMNS_LIST_EXT.

  3. Перейдите из корзины к оформлению и оформите заказ. Проверьте, что ссылка оплаты из подтверждения и из списка заказов ведет на одну страницу.

  4. Откройте личный кабинет, заказ и его отмену по адресам из SEF_URL_TEMPLATES. Проверьте, что адрес отмены открывает форму отмены, а не список заказов.

  5. Отмените неоплаченный заказ и проверьте, что он появился во вкладке отмененных заказов.

  6. Нажмите «Оплатить» у неоплаченного заказа в кабинете и проверьте, что открылась платежная система. Если вместо оплаты открылся корень сайта /, проверьте статус заказа и статус, с которого разрешена оплата.

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