Настройка подписочных платежей на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка подписочных платежей на 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1175
  • 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

Настройка подписочных платежей на 1С-Битрикс

Подписочная монетизация — бизнес-логика поверх рекуррентных платежей. В Битрикс нет нативного модуля подписок, реализация всегда кастомная. Сложность не в самом списании (оно решается за 1–2 дня), а в управлении жизненным циклом: смена тарифа, триальный период, отмена с сохранением доступа до конца периода, retry при неудачном платеже.

Компоненты системы

Слой Что делает
Тарифные планы Хранит условия: цена, период, возможности
Подписки пользователей user → plan, даты периода, статус
Токены карт rebill_id от эквайера
Биллинг-планировщик Cron для создания платежей по расписанию
Управление доступом Проверка активной подписки при запросе
Уведомления Email при успехе, ошибке, окончании

Структура данных

CREATE TABLE b_subscription_plans (
    id           SERIAL PRIMARY KEY,
    code         VARCHAR(32)   UNIQUE NOT NULL,
    name         VARCHAR(128),
    price        DECIMAL(10,2),
    currency     CHAR(3)       DEFAULT 'RUB',
    period_days  INT           NOT NULL,
    trial_days   INT           DEFAULT 0,
    is_active    BOOLEAN       DEFAULT TRUE
);

CREATE TABLE b_user_subscriptions (
    id                   SERIAL PRIMARY KEY,
    user_id              INT           NOT NULL,
    plan_id              INT           REFERENCES b_subscription_plans(id),
    rebill_id            VARCHAR(128),
    status               VARCHAR(16)   DEFAULT 'trialing',
    trial_ends_at        TIMESTAMP,
    period_start         TIMESTAMP,
    period_end           TIMESTAMP,
    cancel_at_period_end BOOLEAN       DEFAULT FALSE,
    retry_count          INT           DEFAULT 0,
    last_payment_at      TIMESTAMP,
    created_at           TIMESTAMP     DEFAULT NOW()
);

Статусы: trialingactivepast_duepaused / cancelled / expired.

Биллинг-планировщик

// /local/cron/subscription_billing.php
// Cron: 0 9 * * * php /var/www/shop/local/cron/subscription_billing.php

define('NO_KEEP_STATISTIC', true);
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

$db = Bitrix\Main\Application::getConnection();

$due = $db->query("
    SELECT s.id, s.user_id, s.rebill_id, p.price, p.currency, p.period_days, u.EMAIL
    FROM b_user_subscriptions s
    JOIN b_subscription_plans p ON p.id = s.plan_id
    JOIN b_users u ON u.ID = s.user_id
    WHERE s.status = 'active'
      AND s.cancel_at_period_end = FALSE
      AND DATE(s.period_end) = CURRENT_DATE
");

while ($row = $due->fetch()) {
    try {
        $success = chargeRebill($row['rebill_id'], $row['price'], $row['currency']);

        if ($success) {
            $db->query("UPDATE b_user_subscriptions SET
                period_start    = period_end,
                period_end      = period_end + INTERVAL '" . (int)$row['period_days'] . " days',
                retry_count     = 0,
                last_payment_at = NOW()
                WHERE id = " . (int)$row['id']);

            createBitrixOrderForSubscription($row);
        } else {
            $db->query("UPDATE b_user_subscriptions
                SET status = 'past_due', retry_count = retry_count + 1
                WHERE id = " . (int)$row['id']);
            sendPaymentFailedNotification($row['EMAIL']);
        }
    } catch (\Exception $e) {
        logError('billing', $row['id'], $e->getMessage());
    }
}

Проверка активной подписки в компонентах

function userHasSubscription(int $userId, string $planCode = null): bool
{
    $db = Bitrix\Main\Application::getConnection();

    $sql = "SELECT COUNT(1) FROM b_user_subscriptions s
            JOIN b_subscription_plans p ON p.id = s.plan_id
            WHERE s.user_id = " . (int)$userId . "
              AND s.status IN ('active', 'trialing')
              AND s.period_end > NOW()";

    if ($planCode) {
        $sql .= " AND p.code = '" . $db->getSqlHelper()->forSql($planCode) . "'";
    }

    return (int)$db->queryScalar($sql) > 0;
}

// В шаблоне закрытого раздела
if (!userHasSubscription($USER->GetID(), 'premium')) {
    LocalRedirect('/subscribe/?redirect=' . urlencode($APPLICATION->GetCurPage()));
}

Кейс: SaaS-платформа, переход на подписки

Клиент — B2B-сервис автоматизации отчётности на Битрикс. До этого — единовременные лицензии. Задача: перевести клиентов на ежемесячную подписку с автоматическим продлением.

Сделали: три тарифных плана, биллинг через Тинькофф с rebill_id, отдельный ЛК управления подпиской, email-уведомления за 3 дня до списания, retry через 1/3/7 дней. Интеграция с системой доступов — через проверку userHasSubscription() в каждом защищённом компоненте.

Сроки

Задача Срок
Структура БД и бизнес-модели 1–2 дня
Страница выбора плана и оформления 2–3 дня
Биллинг-планировщик 1–2 дня
ЛК управления подпиской 1–2 дня
Уведомления и retry 1 день