Настройка подписочных платежей на 1С-Битрикс
Подписочная монетизация — бизнес-логика поверх рекуррентных платежей. В Битрикс нет нативного модуля подписок, реализация всегда кастомная. Сложность не в самом списании (оно решается за 1–2 дня), а в управлении жизненным циклом: смена тарифа, триальный период, отмена с сохранением доступа до конца периода, retry при неудачном платеже.
Мы разрабатываем такие решения для клиентов уже более семи лет. За это время столкнулись с типичными проблемами: несовместимость API платежных шлюзов, дублирование платежей, потеря данных при сбоях cron, сложность обработки частичных возвратов. Наш опыт показывает, что без продуманной архитектуры подписочный бизнес теряет до 20% выручки из-за неудачных списаний и утечки клиентов. Например, при среднем чеке 10 000 руб./мес и 1000 активных подписчиков отток в 5% из-за ошибок биллинга обходится в 500 000 руб./мес. Правильная реализация спасает эти деньги.
Проблемы, которые решаем
Гибкое управление тарифами
Готовые модули часто не поддерживают сложные сценарии: триалы, фримиум, семейные планы. Мы создаём кастомную логику, адаптированную под ваш бизнес.
Надёжный биллинг
Планировщик с retry-механизмом минимизирует потери от неудачных платежей. Каждая попытка логируется, при исчерпании попыток подписка приостанавливается, а клиент получает уведомление.
Интеграция с эквайрингом
Требуется корректная настройка rebill_id через API Тинькофф, Сбера или ЮKassa. Мы обеспечиваем бесшовную передачу токенов и обработку холдов.
Как мы это делаем
Стек: PHP 8.1+, Битрикс (инфоблоки v2.0, ORM), MariaDB, cron, REST API. Для хранения тарифов и подписок используем отдельные таблицы (см. структуру ниже). Кэширование тегированное — кеш сбрасывается при изменении подписки. Все критические операции обёрнуты в транзакции.
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()
);
Статусы: trialing → active → past_due → paused / 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());
}
}
Как управлять жизненным циклом подписки?
После успешного списания обновляются даты периода и сбрасывается счётчик retry. При отказе в списании статус переводится в past_due, запускается цепочка повторных попыток. Если клиент отменяет подписку, мы сохраняем доступ до конца оплаченного периода (cancel_at_period_end = TRUE). Планировщик не будет создавать новый платёж по такой подписке.
Пример функции проверки активной подписки:
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()));
}
Почему кастомная реализация лучше готовых решений?
Готовые модули (например, из Маркетплейса) часто ограничены стандартными сценариями: они не позволяют гибко настроить retry, пропорциональное биллинг, или интеграцию с уникальной CRM. Кастомное решение даёт полный контроль над логикой — вы сами решаете, когда списывать, какие уведомления отправлять, как обрабатывать возвраты. Кроме того, мы можем интегрировать подписочную систему с любым эквайрингом: Тинькофф, Сбер, ЮKassa, АТОЛ.
| Характеристика | Готовый модуль | Кастомное решение |
|---|---|---|
| Гибкость тарифов | Ограничена | Полная свобода |
| Retry-логика | Базовая | Настраиваемая цепочка |
| Интеграция с CRM | Отсутствует | Любая CRM |
| Пропорциональный биллинг | Нет | Есть |
Кейс: SaaS-платформа, переход на подписки
Наш клиент — B2B-сервис автоматизации отчётности на Битрикс. До этого — единовременные лицензии. Задача: перевести клиентов на ежемесячную подписку с автоматическим продлением. Сделали: три тарифных плана, биллинг через Тинькофф с rebill_id, отдельный ЛК управления подпиской, email-уведомления за 3 дня до списания, retry через 1/3/7 дней. Интеграция с системой доступов — через проверку userHasSubscription() в каждом защищённом компоненте. Результат: отток клиентов снизился на 15%, регулярный доход вырос в 2 раза.
Что входит в работу
- Анализ бизнес-требований и проектирование архитектуры.
- Создание БД и модели данных.
- Разработка API для управления подписками (создание, смена, отмена).
- Интеграция с эквайрингом (Тинькофф, Сбер, ЮKassa).
- Настройка cron-планировщиков и retry-логики.
- Тестирование всех сценариев и нагрузочное тестирование.
- Документация по API и администрированию.
- Обучение ваших разработчиков.
- Гарантийная поддержка 3 месяца.
Процесс работы
- Аналитика — обсуждаем тарифную сетку, сценарии подписок, варианты оплаты.
- Проектирование — создаём схему БД, API, документацию.
- Разработка — пишем код на PHP, версионируем через Git.
- Тестирование — unit-тесты, интеграционные сценарии, проверка на боевых данных.
- Деплой — настройка cron, миграции, нагрузочное тестирование.
- Поддержка — мониторинг, доработки, 24/7 на связи.
Сроки ориентировочно
| Задача | Срок |
|---|---|
| Структура БД и бизнес-модели | 1–2 дня |
| Страница выбора плана и оформления | 2–3 дня |
| Биллинг-планировщик | 1–2 дня |
| ЛК управления подпиской | 1–2 дня |
| Уведомления и retry | 1 день |
Стоимость рассчитывается индивидуально — зависит от сложности интеграций и объёма кастомизации. Свяжитесь с нами для консультации по архитектуре подписок. Закажите разработку подписочного модуля под ваши задачи — мы подготовим коммерческое предложение с точными сроками.







