Разработка системы подписок (subscription) на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка системы подписок (subscription) на 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка системы подписок (subscription) на 1С-Битрикс

Система подписок — это модель, при которой клиент платит регулярно (ежемесячно, ежеквартально, ежегодно) и получает доступ к сервису или товарам. 1С-Битрикс не имеет встроенного механизма подписок с рекуррентными платежами — его нужно строить на базе модулей sale, catalog и кастомного кода.

Типы подписок в контексте Битрикс

Прежде чем проектировать, важно понять бизнес-модель:

Тип подписки Описание Техническая реализация
Доступ к контенту Платный раздел, закрытые материалы Группы пользователей + ограничение доступа
Товарная подписка Регулярная доставка товаров Автоматическое создание заказов
Сервисная подписка SaaS, лицензия, техподдержка Статус аккаунта + автопродление

Все три типа имеют общее: периодическое списание денег и управление статусом доступа.

Архитектура хранения данных

Ядро системы — таблица подписок. Создаётся через ORM Битрикс (наследование от \Bitrix\Main\ORM\Data\DataManager):

class SubscriptionTable extends DataManager
{
    public static function getTableName(): string
    {
        return 'b_local_subscription';
    }

    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new IntegerField('USER_ID', ['required' => true]),
            new IntegerField('PLAN_ID', ['required' => true]),
            new EnumField('STATUS', ['values' => ['TRIAL', 'ACTIVE', 'PAST_DUE', 'CANCELLED', 'EXPIRED']]),
            new DatetimeField('CURRENT_PERIOD_START'),
            new DatetimeField('CURRENT_PERIOD_END'),
            new DatetimeField('TRIAL_END'),
            new StringField('PAYMENT_TOKEN'),    // Токен рекуррентной оплаты
            new IntegerField('PAY_SYSTEM_ID'),
            new StringField('CANCEL_REASON'),
            new DatetimeField('CANCELLED_AT'),
            new DatetimeField('CREATED_AT'),
        ];
    }
}

Таблица планов подписки:

class SubscriptionPlanTable extends DataManager
{
    // ID, NAME, PRICE, CURRENCY, PERIOD_DAYS, TRIAL_DAYS,
    // IBLOCK_SECTION_IDS (доступные разделы), FEATURES (JSON)
}

Управление доступом по подписке

Для подписок типа «контент» доступ реализуется через группы пользователей Битрикс. Каждому плану соответствует группа (b_group). При активации подписки — добавить пользователя в группу:

CUser::SetUserGroup($userId, array_merge(
    CUser::GetUserGroup($userId),
    [$plan->getGroupId()]
));

При истечении или отмене — убрать из группы. Доступ к разделам ограничивается правами доступа инфоблоков или компонентов.

Рекуррентные платежи

Это самая сложная часть. Рекуррент требует от платёжной системы хранения метода оплаты (карты) и автоматического списания по запросу. Поддерживают: ЮKassa (Яндекс.Касса), CloudPayments, Robokassa (рекуррент), Stripe (если работаете с международными клиентами).

Схема работы:

  1. Первый платёж: обычная оплата через API платёжной системы. В ответе — payment_method_id или токен сохранённого метода.
  2. Сохранить токен: записать в SubscriptionTable.PAYMENT_TOKEN.
  3. Автосписание: при наступлении CURRENT_PERIOD_END — вызвать API платёжной системы с токеном:
// Пример для ЮKassa
$payment = new \YooKassa\Client();
$payment->setAuth($shopId, $secretKey);
$response = $payment->createPayment([
    'amount' => ['value' => $plan->getPrice(), 'currency' => 'RUB'],
    'payment_method_id' => $subscription->getPaymentToken(),
    'capture' => true,
    'description' => 'Подписка ' . $plan->getName() . ' #' . $subscription->getId(),
]);
  1. Обработка результата: успех → обновить CURRENT_PERIOD_START, CURRENT_PERIOD_END, сохранить новый статус ACTIVE. Неуспех → статус PAST_DUE, уведомить клиента, повторить через 24/48 часов.

Триальный период

При создании подписки с триалом:

$trialEnd = (new DateTime())->modify('+' . $plan->getTrialDays() . ' days');
SubscriptionTable::add([
    'USER_ID' => $userId,
    'PLAN_ID' => $planId,
    'STATUS' => 'TRIAL',
    'TRIAL_END' => $trialEnd,
    'CURRENT_PERIOD_END' => $trialEnd,
]);

Агент за 1 день до окончания трайла — уведомить пользователя. В день окончания — попытка первого списания. Если карта не привязана — перевести в статус EXPIRED.

Агент обработки подписок

Ежедневный cron-скрипт:

// Найти подписки, требующие продления
$expiring = SubscriptionTable::getList([
    'filter' => [
        'STATUS' => ['ACTIVE', 'PAST_DUE'],
        '<=CURRENT_PERIOD_END' => new DateTime(),
    ]
])->fetchAll();

foreach ($expiring as $sub) {
    try {
        $result = chargeSubscription($sub);
        if ($result->isSuccess()) {
            SubscriptionTable::update($sub['ID'], [
                'STATUS' => 'ACTIVE',
                'CURRENT_PERIOD_START' => new DateTime(),
                'CURRENT_PERIOD_END' => (new DateTime())->modify('+' . $planPeriodDays . ' days'),
            ]);
        } else {
            handlePaymentFailure($sub);
        }
    } catch (\Exception $e) {
        logError($e, $sub);
    }
}

Личный кабинет подписчика

Минимальный функционал страницы /personal/subscription/:

  • Текущий план и статус.
  • Дата следующего списания и сумма.
  • История платежей.
  • Кнопка «Отменить» (с опциональным вопросом о причине).
  • Смена плана (апгрейд/даунгрейд).
  • Обновление платёжных данных.

При отмене: STATUS = 'CANCELLED', CANCELLED_AT = now(). Доступ сохраняется до CURRENT_PERIOD_END — клиент оплатил период, он использует то, за что заплатил.

Уведомления

Обязательные почтовые события:

  • SUBSCRIPTION_CREATED — подтверждение подписки.
  • SUBSCRIPTION_PAYMENT_SUCCESS — успешное списание, квитанция.
  • SUBSCRIPTION_PAYMENT_FAILED — ошибка списания, обновить карту.
  • SUBSCRIPTION_TRIAL_ENDING — за 1-3 дня до конца трайла.
  • SUBSCRIPTION_CANCELLED — подтверждение отмены.
  • SUBSCRIPTION_EXPIRED — доступ закрыт.

Сроки разработки

Вариант Состав Срок
Без рекуррента Подписка с ручной оплатой, управление доступом 5-7 дней
С рекуррентными платежами Автосписание через ЮKassa или CloudPayments 10-14 дней
Полная платформа Несколько планов, трайл, ЛК, аналитика 15-20 дней