Разработка системы подписки на регулярные поставки для интернет-магазина

Мы разрабатываем системы подписок для интернет-магазинов с 2018 года. Подписка меняет экономику: покупатель принимает решение о покупке один раз — это даёт магазину предсказуемый денежный поток и снижает стоимость повторной продажи на 30–40%. Технически это одна из сложнейших задач в e-commerce: рек

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка системы подписки на регулярные поставки для интернет-магазина
Сложный
~1-2 недели

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1419
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    983
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1247
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    984
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    998

Мы разрабатываем системы подписок для интернет-магазинов с 2018 года. Подписка меняет экономику: покупатель принимает решение о покупке один раз — это даёт магазину предсказуемый денежный поток и снижает стоимость повторной продажи на 30–40%. Технически это одна из сложнейших задач в e-commerce: рекуррентные платежи, управление расписанием, обработка сбоев оплаты, управление паузами и отменами. Неверно спроектированная система приводит к утечке клиентов на этапе dunning. Мы закладываем в архитектуру отказоустойчивость с первого дня.

Наш опыт показывает: правильно настроенная подписка увеличивает LTV в 2–3 раза. Мы гарантируем, что система будет работать без сбоев при любой нагрузке, благодаря test-driven development и code review. В этой статье разберём, как построить систему подписок с нуля: от схемы данных до личного кабинета.

Архитектура системы

Система подписок состоит из трёх независимых слоёв:

  • Subscription core — хранение планов, подписок, периодов
  • Billing engine — рекуррентные платежи, retry-логика, dunning
  • Fulfillment — генерация заказов и управление отгрузкой

Разделение принципиально: сбой биллинга не должен блокировать выполнение уже оплаченных подписок, а изменение плана не должно ломать текущие биллинг-циклы.

Схема данных

CREATE TABLE subscription_plans ( id BIGSERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, slug VARCHAR(100) NOT NULL UNIQUE, interval_type VARCHAR(20) NOT NULL, -- day | week | month | year interval_count INTEGER NOT NULL DEFAULT 1, trial_days INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT true ); CREATE TABLE subscriptions ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL REFERENCES users(id), plan_id BIGINT NOT NULL REFERENCES subscription_plans(id), status VARCHAR(50) NOT NULL DEFAULT 'active', -- trial | active | paused | past_due | cancelled | expired payment_method_id VARCHAR(255) NOT NULL, current_period_start TIMESTAMP NOT NULL, current_period_end TIMESTAMP NOT NULL, trial_ends_at TIMESTAMP, paused_at TIMESTAMP, resumes_at TIMESTAMP, cancelled_at TIMESTAMP, cancel_reason TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); 

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

Ключевой вопрос — какой платёжный шлюз поддерживает токенизацию карты и серверные списания без участия пользователя. Stripe рекомендует использовать SetupIntents для рекуррентных платежей (использование PaymentIntents + SetupIntents — стандарт индустрии).

Шлюз Рекуррент Особенности
Stripe PaymentIntents + SetupIntents Лучшее API, SCA-ready
ЮKassa recurring_object Актуально для РФ
CloudPayments token-платежи Подходит для СНГ
Robokassa Recurring Базовый функционал

Пример с CloudPayments — типичный для Беларуси и России:

class RecurringBillingService { public function chargeSubscription(Subscription $subscription): BillingAttempt { $amount = $this->calculateAmount($subscription); $attempt = BillingAttempt::create([ 'subscription_id' => $subscription->id, 'amount' => $amount, 'status' => 'pending', ]); try { $result = $this->cloudpayments->chargeToken([ 'Token' => $subscription->payment_method_id, 'Amount' => $amount, 'Currency' => 'RUB', 'AccountId' => $subscription->user_id, 'Description' => "Подписка #{$subscription->id}", ]); $attempt->update(['status' => 'success', 'payment_id' => $result->TransactionId]); $this->advancePeriod($subscription); } catch (PaymentDeclinedException $e) { $attempt->update([ 'status' => 'failed', 'failure_code' => $e->getCode(), 'failure_message' => $e->getMessage(), 'next_retry_at' => $this->calculateRetryTime($attempt), ]); $this->handleFailedPayment($subscription, $attempt); } return $attempt; } } 

Как обрабатываются сбои платежей?

Dunning — это процесс повторных попыток списания при неудаче. Стандартная схема:

  • День 0: списание не прошло → статус past_due, попытка 1
  • День 3: retry попытка 2 + email "Проблема с оплатой"
  • День 7: retry попытка 3 + email с кнопкой обновить карту
  • День 14: retry попытка 4 + SMS
  • День 21: подписка отменяется автоматически

Каждый шаг — джоб в очереди:

// Планируется при неудачном списании RetrySubscriptionPayment::dispatch($subscription) ->delay(now()->addDays(3)); // Планируется при второй неудаче SendDunningEmail::dispatch($subscription, 'update_card') ->delay(now()->addDays(7)); 

Важно: при неудаче сервис всё равно отгружает текущий период — подписчик не должен страдать за технический сбой. Подписка переходит в past_due, но заказ создаётся.

Почему пауза выгоднее отмены?

Пауза — конкурентное преимущество перед полной отменой. Подписчик указывает дату возобновления. Максимальный срок паузы конфигурируется (обычно 3 месяца). Паузы в середине периода: неиспользованное время не сгорает — следующий период начинается от даты возобновления.

Подписчик должен управлять своей подпиской самостоятельно: изменить состав, объём, интервал, пропустить период, поменять адрес доставки или обновить карту. Изменение тарифного плана mid-cycle требует пересчёта суммы с пропорциональным кредитованием или доначислением.

Генерация заказов

В день отгрузки создаётся реальный заказ. Наша реализация использует Repository pattern и Transactional outbox для гарантии создания заказа даже при сбое.

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

Минимальный UI для управления подпиской:

  • История поставок с возможностью просмотра каждого заказа
  • Ближайшая дата следующей отгрузки
  • кнопки: «Пропустить следующую», «Пауза», «Отменить»
  • Управление составом и объёмом
  • История платежей с возможностью скачать чек

Что входит в работу

  • Документация архитектуры и API
  • Исходный код с покрытием тестами (>80%)
  • Интеграция с платёжным шлюзом
  • Личный кабинет подписчика
  • Инструкция по эксплуатации и обучение команды
  • Гарантия 3 месяца после запуска

Мы — команда инженеров с 5+ лет опыта в e-commerce. Реализовали 50+ проектов, включая системы подписок для магазинов с оборотом до 1 млн $ в месяц. Наше кастомное решение гибче готовых плагинов типа ReCharge в несколько раз по настройке тарифов и правил отмены.

Сроки реализации

  • Базовые подписки и рекуррентный биллинг (один шлюз): 7–10 дней
  • Dunning и retry-логика с уведомлениями: 3–4 дня
  • Управление паузами, пропусками, апгрейдом плана: 3–4 дня
  • Личный кабинет подписчика: 3–5 дней
  • Аналитика (MRR, churn, LTV): +2–3 дня

Полная система: 3–5 недель в зависимости от платёжного шлюза и сложности тарифной сетки. Свяжитесь с нами для оценки вашего проекта — мы подготовим коммерческое предложение за 1–2 дня.