Розробка функціоналу підписки на товари 1С-Bitrix
Інтернет-магазин продає розхідники: кофе, корм для тварин, фільтри, побутову хімію. Клієнт купує одне й те саме раз у два-чотири тижні. Без підписки він щоразу проходить повний цикл замовлення — або йде до конкурента, у якого є автоповтор. В 1С-Bitrix готового модуля підписки на товари немає. Його потрібно будувати на базі 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. Агенти Bitrix (\CAgent) зручні, але виконуються в контексті хіту користувача (якщо не налаштований cron_events). Для підписки це неприйнятно: створення замовлення — важка операція. Рекомендується окремий PHP-скрипт, викликаємий із crontab:
*/30 * * * * /usr/bin/php /home/bitrix/www/local/cron/subscription_process.php
Скрипт підключає пролог (/bitrix/modules/main/include/prolog_before.php), потім обробляє підписки пакетами по 50.
Управління підпискою в особистому кабінеті
Користувач повинен бачити свої активні підписки, змінювати періодичність, склад, ставити на паузу. Це реалізується через кастомний компонент у розділі /personal/subscriptions/. Компонент використовує ORM-клас підписки й рендерить форму з полями:
- Список товарів із можливістю видалити позицію або змінити кількість.
- Вибір періоду: 7 / 14 / 21 / 30 днів.
- Кнопки «Приостановити» й «Скасувати».
- Дата наступної доставки з можливістю зсуву.
При змінюванні складу кошика перераховується BASKET_DATA. При паузі STATUS переключається на PAUSED, агент пропускає запис.
Рекурентні платежі
Підписка без автоматичного списання — піврозв'язання. Клієнт отримує замовлення зі статусом «Чекає оплати» й повинен оплатити вручну. Повноцінна підписка потребує рекурентних платежів.
Рекурентні платежі підтримують не всі платіжні системи. З поширених: ЮKassa (метод createPayment з параметром payment_method_id збереженого методу), CloudPayments (recurrent через API post-запити). У Bitrix рекурент реалізується через кастомний обробник платіжної системи, який успадковує \Bitrix\Sale\PaySystem\BaseServiceHandler.
Логіка: при першій оплаті зберігаємо токен платіжного методу в b_subscription_order.PAY_TOKEN. При автостворенні замовлення — ініціюємо списання через API платіжної системи. Якщо списання не пройшло — помічаємо замовлення як неоплачене й відправляємо листа клієнту.
Строки впровадження
| Масштаб | Склад | Строк |
|---|---|---|
| Базовий | Підписка без автоплатежу, управління в ЛК, агент | 5-7 днів |
| Повний | Рекурентні платежі, сповіщення, аналітика підписок | 8-12 днів |
Сповіщення
Мінімальний набір поштових подій:
- SUBSCRIPTION_CREATED — підтвердження створення підписки.
- SUBSCRIPTION_ORDER_CREATED — сповіщення про нове замовлення по підписці.
- SUBSCRIPTION_ITEM_OUT_OF_STOCK — товар із підписки закінчився.
- SUBSCRIPTION_PAYMENT_FAILED — помилка автоматичного списання.
- SUBSCRIPTION_REMINDER — нагадування за 1-2 дні до наступного замовлення (дає можливість змінити склад).
Поштові шаблони створюються в Налаштування → Поштові события з типом события, привязаним до сайту.







