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

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка системи підписок (subscription) на 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка системи підписок (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 днів