Разработка веб-сервиса по подписке
Веб-сервис по подписке — это любой продукт, где пользователь платит регулярно (ежемесячно, ежегодно) за доступ к функциям, контенту или данным. Технически это означает: управление жизненным циклом подписки (trial → active → past_due → cancelled), обработку неудачных платежей, анти-churn механизмы и корректный доступ к функциям в зависимости от статуса.
Жизненный цикл подписки
trialing (14 дней)
↓ автоматический платёж
active
↓ неудачный платёж
past_due → retry 3–4 раза → cancelled
↓ ручная отмена
cancelled → grace period (до конца периода)
↓
expired
Каждый переход генерирует webhook от платёжного провайдера. Приложение слушает эти события и обновляет статус подписки в базе.
Stripe webhook events:
-
invoice.payment_succeeded→ активируем/продлеваем -
invoice.payment_failed→ устанавливаемpast_due, отправляем email -
customer.subscription.deleted→ деактивируем доступ
Dunning-управление
Dunning — процесс работы с неудачными платежами. Stripe Billing имеет встроенный Smart Retries (ML-алгоритм выбирает оптимальное время retry). Настраивается в настройках биллинга: 3–4 попытки в течение 7–14 дней.
Параллельно отправляются email-уведомления с ссылкой на обновление карты. Stripe Billing предоставляет hosted customer portal — страницу, где клиент может обновить платёжный метод без написания кода.
Бесплатный пробный период
Два подхода:
- Trial without card — пользователь не вводит карту, после окончания trial нужно добавить оплату. Меньше трения при регистрации, но ниже конверсия в платящих.
- Trial with card — карта добавляется при регистрации, списание происходит автоматически после trial. Выше конверсия, но меньше регистраций.
Для B2B-SaaS рекомендуется trial with card. Для B2C и viral-продуктов — без карты.
Upgrade / Downgrade
Смена плана должна быть мгновенной и учитывать уже оплаченный период. Stripe обрабатывает это через proration:
await stripe.subscriptions.update(subscriptionId, {
items: [{ id: itemId, price: 'price_premium_monthly' }],
proration_behavior: 'create_prorations',
});
При апгрейде — списывается разница за оставшиеся дни периода. При даунгрейде — разница засчитывается как кредит.
Анти-churn: retention механики
- Cancellation flow: вместо кнопки «Отменить» — диалог с clarifying questions («Почему вы уходите?»), предложение паузы (подписка на 1–3 месяца) или скидки
-
Email-кампании: серия писем при
past_due, при окончании trial без конверсии, через 30/60/90 дней после отмены - Win-back offers: специальное предложение для cancelled пользователей
Доступ к функциям
Проверка доступа должна быть централизованной, не разбросанной по всему коду:
// Gate в Laravel
Gate::define('use-advanced-feature', function (User $user) {
return $user->subscription?->active()
&& $user->subscription->plan->hasFeature('advanced');
});
// Использование
$this->authorize('use-advanced-feature');
Сроки
Веб-сервис с подпиской через Stripe (регистрация, trial, upgrade/downgrade, portal, базовые webhook'и): 2–3 месяца. С расширенной тарификацией, командами, dunning и analytics: 3–5 месяцев.







