Разработка функционала предзаказа на 1С-Битрикс
Товар ещё не поступил на склад, но карточка уже есть в каталоге. Стандартное поведение Битрикс — кнопка «Нет в наличии» и уведомление о поступлении. Это теряет горячего клиента: он хочет купить сейчас, а не получить письмо через неделю. Предзаказ решает задачу: клиент оформляет заказ на отсутствующий товар, фиксирует цену и место в очереди, а магазин получает прогнозируемый спрос.
Чем предзаказ отличается от «Уведомить о поступлении»
Модуль catalog.subscribe в Битрикс — это подписка на наличие. Пользователь оставляет email, при изменении CATALOG_AVAILABLE = Y получает письмо. Никакого заказа, никакой фиксации цены, никакой очереди.
Предзаказ — это полноценный заказ со специальным статусом. Товар резервируется за клиентом, оплата может быть полной, частичной (задаток) или отложенной. Когда товар поступает — заказ переводится в обработку.
Механика на уровне каталога
Управление предзаказом начинается со свойства товара. Создаём свойство инфоблока PREORDER_AVAILABLE (тип: список, значения: Y/N). Оно определяет, доступен ли товар для предзаказа, когда CATALOG_AVAILABLE = N.
В шаблоне catalog.element логика кнопки меняется:
- Если
CATALOG_AVAILABLE = Y— стандартная «Купить». - Если
CATALOG_AVAILABLE = NиPREORDER_AVAILABLE = Y— кнопка «Предзаказ». - Если оба
N— «Нет в наличии» + подписка.
Кнопка «Предзаказ» добавляет товар в корзину с пометкой. Пометку храним в свойстве элемента корзины: \Bitrix\Sale\BasketItem::setField('PROPS', ...) — добавляем свойство IS_PREORDER = Y.
Обход проверки наличия
Главная техническая проблема: Битрикс не позволяет добавить в корзину товар с нулевым остатком. Метод \Bitrix\Catalog\Product\Basket::addProduct() проверяет CATALOG_AVAILABLE и возвращает ошибку.
Два подхода:
1. Виртуальный склад предзаказов. Создаём отдельный склад в Магазин → Склады с названием «Предзаказ». Когда товар помечен как доступный для предзаказа — устанавливаем на этом складе количество, равное лимиту предзаказов (например, 100). Товар становится CATALOG_AVAILABLE = Y, но реальный склад пуст. При обработке заказа менеджер видит, что товар зарезервирован на складе «Предзаказ», и понимает ситуацию.
Преимущество: не нужно модифицировать ядро. Работает со стандартным оформлением заказа. Недостаток: искажает остатки в отчётах, требует дисциплины при обмене с 1С.
2. Обработчик события. Подписываемся на OnBeforeBasketAdd или OnSaleBasketItemBeforeSaved и перехватываем проверку наличия. Если товар помечен PREORDER_AVAILABLE = Y — пропускаем валидацию остатков. Этот способ чище, но требует тестирования с каждым обновлением Битрикс, так как механизм проверки наличия менялся между версиями модуля sale.
Статусы заказа
Для предзаказов создаём дополнительные статусы в Магазин → Статусы заказов:
| Код | Название | Описание |
|---|---|---|
| PP | Предзаказ принят | Заказ создан, товар отсутствует |
| PW | Ожидание поставки | Товар заказан у поставщика |
| PR | Товар поступил | Можно переводить в сборку |
Автоматизация перехода PP → PR реализуется через обработчик OnStoreProductUpdate. При изменении остатка на основном складе проверяем, есть ли заказы в статусе PP с этим товаром. Если остаток достаточен — меняем статус на PR и отправляем уведомление клиенту.
Оплата предзаказа
Три стратегии:
Полная предоплата. Клиент платит сразу. Простая схема, но рискованная для покупателя — если поставка сорвётся, нужен возврат.
Задаток. При оформлении предзаказа создаётся оплата на фиксированную сумму (например, 10-20% от стоимости). Реализуется через кастомное правило корзины или через создание двух Payment в заказе: первый — задаток (активный), второй — остаток (отложенный). Метод \Bitrix\Sale\Payment::setField('SUM', $depositAmount).
Оплата при поступлении. Заказ создаётся без оплаты. Когда товар приходит — менеджер активирует платёж, клиент получает ссылку на оплату. Для онлайн-оплаты используется метод \Bitrix\Sale\PaySystem\Service::initiatePay(), генерирующий платёжную форму.
Лимиты и очередь
Без лимитов предзаказ превращается в проблему: 500 клиентов оформили предзаказ, а поставка — 50 единиц. Лимит задаётся через свойство товара PREORDER_LIMIT и проверяется при добавлении в корзину. Текущее количество предзаказов считается запросом к b_sale_basket с фильтром по свойству IS_PREORDER = Y и связью с незавершёнными заказами.
Очередь формируется по дате создания заказа. При поступлении товара приоритет отдаётся ранним заказам. Это реализуется сортировкой ORDER BY DATE_INSERT ASC при выборке предзаказов для перевода в статус PR.
Сроки
| Масштаб | Что входит | Срок |
|---|---|---|
| Базовый | Кнопка предзаказа, виртуальный склад, статусы | 4-5 дней |
| Полный | Задаток, автосмена статусов, лимиты, уведомления, интеграция с 1С | 8-12 дней |







