Интернет-магазин продаёт расходники: кофе, корм для животных, фильтры, бытовую химию. Клиент покупает одно и то же раз в две-четыре недели. Без подписки он каждый раз проходит полный цикл заказа — или уходит к конкуренту, у которого есть автоповтор. В 1С-Битрикс готового модуля подписки на товары нет. Его нужно строить на базе sale, catalog и собственного модуля, связывающего периодичность с автоматическим созданием заказов. Мы разрабатываем такой функционал под ключ — с гарантией стабильной работы и полной документацией. Оценим ваш проект за один день.
Архитектура решения
Подписка — это не просто «повторить заказ». Это отдельная сущность со своим жизненным циклом: создание, активная фаза, пауза, отмена, возобновление. Хранить её удобно в отдельной таблице, например b_subscription_order:
| Поле | Тип | Назначение |
|---|---|---|
| ID | int | Первичный ключ |
| USER_ID | int | Привязка к пользователю |
| BASKET_DATA | text | Сериализованный состав корзины |
| PERIOD_DAYS | int | Интервал повтора в днях |
| NEXT_DATE | datetime | Дата следующего заказа |
| STATUS | enum | ACTIVE, PAUSED, CANCELLED |
| PAY_SYSTEM_ID | int | Платёжная система |
| DELIVERY_ID | int | Служба доставки |
| PERSON_TYPE_ID | int | Тип плательщика |
| DISCOUNT_PERCENT | decimal | Скидка подписчика |
Для работы с таблицей создаём ORM-класс, наследуясь от \Bitrix\Main\ORM\Data\DataManager. Это даёт стандартные методы getList(), add(), update(), delete() и возможность использовать фильтры D7.
Как реализовать автоматическое создание заказов?
Ядро функционала — агент или cron-задача, которая запускается раз в сутки (или чаще) и проверяет записи с STATUS = ACTIVE и NEXT_DATE <= NOW().
Алгоритм обработки одной подписки:
- Десериализовать
BASKET_DATA, проверить наличие каждого товара через\Bitrix\Catalog\ProductTable::getList(). - Проверить остатки:
\CCatalogStoreProduct::GetList()или\Bitrix\Catalog\StoreProductTable. Если товара нет на складе — пропустить позицию и уведомить клиента. - Создать корзину:
\Bitrix\Sale\Basket::create(), добавитьBasketItemдля каждой позиции. - Применить скидку подписчика через кастомное правило корзины или прямое изменение цены в
BasketItem::setField('CUSTOM_PRICE', 'Y')+BasketItem::setField('PRICE', $discountedPrice). - Создать заказ:
\Bitrix\Sale\Order::create(), привязать корзину, установитьPERSON_TYPE_ID, заполнить свойства заказа из сохранённого профиля. - Привязать доставку и оплату:
\Bitrix\Sale\Shipment::create(),\Bitrix\Sale\Payment::create(). - Сохранить заказ:
$order->save(). - Обновить
NEXT_DATEнаNEXT_DATE + PERIOD_DAYS.
Критически важно оборачивать каждую подписку в try/catch и логировать ошибки. Один сбой не должен останавливать обработку остальных.
Выбор между агентом и cron. Агенты Битрикс удобны, но выполняются в контексте хита пользователя (если не настроен cron_events). Для подписки это неприемлемо: создание заказа — тяжёлая операция. Рекомендуется отдельный PHP-скрипт, вызываемый из crontab:
*/30 * * * * /usr/bin/php /home/bitrix/www/local/cron/subscription_process.php Скрипт подключает пролог (/bitrix/modules/main/include/prolog_before.php), затем обрабатывает подписки пакетами по 50.
Почему рекуррентные платежи критичны для подписки?
Подписка без автоматического списания — полумера. Клиент получает заказ со статусом «Ожидает оплаты» и должен оплатить вручную. Полноценная подписка требует рекуррентных платежей. По нашим данным, LTV клиента с автоплатежом вырастает на 30% по сравнению с ручным повторением.
Рекуррентные платежи поддерживают не все платёжные системы. Из распространённых: ЮKassa (метод createPayment с параметром payment_method_id сохранённого метода), CloudPayments (recurrent через post-запросы к API). В Битрикс рекуррент реализуется через кастомный обработчик платёжной системы, наследующий \Bitrix\Sale\PaySystem\BaseServiceHandler.
Логика: при первой оплате сохраняем токен платёжного метода в b_subscription_order.PAY_TOKEN. При автосоздании заказа — инициируем списание через API платёжной системы. Если списание не прошло — помечаем заказ как неоплаченный и отправляем письмо клиенту.
Управление подпиской в личном кабинете
Пользователь должен видеть свои активные подписки, менять периодичность, состав, ставить на паузу. Это реализуется через кастомный компонент в разделе /personal/subscriptions/. Компонент использует ORM-класс подписки и рендерит форму с полями:
- Список товаров с возможностью удалить позицию или изменить количество.
- Выбор периода: 7 / 14 / 21 / 30 дней.
- Кнопки «Приостановить» и «Отменить».
- Дата следующей доставки с возможностью сдвига.
При изменении состава корзины пересчитывается BASKET_DATA. При паузе STATUS переключается на PAUSED, агент пропускает запись.
Сроки внедрения
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Подписка без автоплатежа, управление в ЛК, агент | 5-7 дней |
| Полный | Рекуррентные платежи, уведомления, аналитика подписок | 8-12 дней |
Уведомления
Минимальный набор почтовых событий:
-
SUBSCRIPTION_CREATED— подтверждение создания подписки. -
SUBSCRIPTION_ORDER_CREATED— уведомление о новом заказе по подписке. -
SUBSCRIPTION_ITEM_OUT_OF_STOCK— товар из подписки закончился. -
SUBSCRIPTION_PAYMENT_FAILED— ошибка автоматического списания. -
SUBSCRIPTION_REMINDER— напоминание за 1-2 дня до следующего заказа (даёт возможность изменить состав).
Почтовые шаблоны создаются в административном разделе Настройки → Почтовые события с типом события, привязанным к сайту.
Что входит в работу
- Полная документация по архитектуре и API модуля.
- Исходный код с комментариями, покрытие ключевых кейсов.
- Настройка прав доступа для администраторов и менеджеров.
- Обучение вашей команды работе с модулем (2 часа онлайн).
- Постпроектная поддержка в течение 30 дней (исправление ошибок, консультации).
- При необходимости — доработка платёжных систем под ваш агрегатор.
Мы гарантируем стабильную работу подписки под любой нагрузкой. Сертифицированные специалисты Битрикс с опытом более 7 лет. Свяжитесь с нами — оценим ваш проект за 1 рабочий день и предложим оптимальное решение.







