Интеграция Stripe Billing для SaaS-подписок

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция Stripe Billing для SaaS-подписок
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

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

Этапы разработки

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

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

Интеграция Stripe Billing для SaaS-подписок

Stripe Billing — наиболее полная готовая реализация биллинга для SaaS на рынке. Покрывает подписки, пробные периоды, апгрейды/даунгрейды, prorated billing, метерированное потребление, автоматический retry при неудаче. Реализация с нуля заняла бы месяцы — Stripe Billing сокращает это до 1–2 недель.

Ключевые сущности

ProductPriceSubscriptionInvoicePaymentIntent. Продукт — это план (Basic, Pro, Enterprise). К продукту привязываются несколько Price — ежемесячная и ежегодная. Подписка привязывает customer к Price. Invoice выставляется автоматически в начале каждого периода.

Создание продуктов и цен

// Создать продукт (один раз при настройке)
$product = \Stripe\Product::create([
    'name'     => 'Pro Plan',
    'metadata' => ['plan_id' => 'pro'],
]);

// Ежемесячная цена
$monthlyPrice = \Stripe\Price::create([
    'product'       => $product->id,
    'unit_amount'   => 2900,  // $29.00
    'currency'      => 'usd',
    'recurring'     => ['interval' => 'month'],
    'lookup_key'    => 'pro_monthly', // для поиска без хранения ID
]);

// Ежегодная (со скидкой)
$yearlyPrice = \Stripe\Price::create([
    'product'       => $product->id,
    'unit_amount'   => 27900, // $279.00
    'currency'      => 'usd',
    'recurring'     => ['interval' => 'year'],
    'lookup_key'    => 'pro_yearly',
]);

Регистрация пользователя и создание подписки

// При регистрации — создать Stripe Customer
$stripeCustomer = \Stripe\Customer::create([
    'email'    => $user->email,
    'name'     => $user->name,
    'metadata' => ['user_id' => $user->id],
]);
$user->update(['stripe_customer_id' => $stripeCustomer->id]);

// Создать подписку с trial
$subscription = \Stripe\Subscription::create([
    'customer'          => $user->stripe_customer_id,
    'items'             => [['price' => 'pro_monthly']],
    'trial_period_days' => 14,
    'payment_behavior'  => 'default_incomplete',
    'payment_settings'  => ['save_default_payment_method' => 'on_subscription'],
    'expand'            => ['latest_invoice.payment_intent'],
]);

// Вернуть client_secret для подтверждения карты на фронтенде
$clientSecret = $subscription->latest_invoice->payment_intent->client_secret;

payment_behavior: default_incomplete означает, что подписка создаётся, но активируется только после успешного первого платежа. Это важно для бесплатных trial: карта привязывается, но не списывается.

Апгрейд/даунгрейд

public function changePlan(User $user, string $newPriceLookupKey): void
{
    $prices = \Stripe\Price::all(['lookup_keys' => [$newPriceLookupKey]]);
    $newPrice = $prices->data[0];

    $subscription = \Stripe\Subscription::retrieve($user->stripe_subscription_id);

    \Stripe\Subscription::update($subscription->id, [
        'items'              => [[
            'id'    => $subscription->items->data[0]->id,
            'price' => $newPrice->id,
        ]],
        'proration_behavior' => 'create_prorations', // или 'none' для годовых
        'billing_cycle_anchor'=> 'unchanged',
    ]);
}

При апгрейде с proration Stripe автоматически кредитует неиспользованное время текущего плана и выставляет invoice на разницу.

Webhook: синхронизация статусов

Вся бизнес-логика должна строиться на webhook-ах, не на синхронных ответах API. События для обработки:

protected array $handlers = [
    'customer.subscription.created'       => 'onSubscriptionCreated',
    'customer.subscription.updated'       => 'onSubscriptionUpdated',
    'customer.subscription.deleted'       => 'onSubscriptionCancelled',
    'invoice.payment_succeeded'           => 'onInvoicePaid',
    'invoice.payment_failed'              => 'onInvoicePaymentFailed',
    'customer.subscription.trial_will_end'=> 'onTrialEndingSoon',
];

public function onInvoicePaymentFailed(array $event): void
{
    $subscription = $event['data']['object']['subscription'];
    $user = User::where('stripe_subscription_id', $subscription)->firstOrFail();

    // Не блокировать сразу — Stripe делает retry
    // next_payment_attempt есть в invoice
    $nextRetry = $event['data']['object']['next_payment_attempt'];
    Notification::send($user, new PaymentFailedNotification($nextRetry));
}

Customer Portal

Stripe Customer Portal — готовый UI для управления подпиской (смена карты, отмена, история инвойсов). Не нужно писать с нуля:

$session = \Stripe\BillingPortal\Session::create([
    'customer'   => $user->stripe_customer_id,
    'return_url' => route('dashboard'),
]);
return redirect($session->url);

Конфигурируется в Stripe Dashboard: разрешить/запретить смену плана, отмену, скачивание инвойсов.

Metered billing

Для SaaS с оплатой по потреблению (API вызовы, хранилище, пользователи):

// Price с metered billing
$price = \Stripe\Price::create([
    'product'   => $product->id,
    'currency'  => 'usd',
    'recurring' => [
        'interval'       => 'month',
        'usage_type'     => 'metered',
        'aggregate_usage'=> 'sum',
    ],
    'billing_scheme' => 'per_unit',
    'unit_amount'    => 1, // $0.01 за единицу
]);

// Репортить потребление (раз в час или в конце периода)
\Stripe\SubscriptionItem::createUsageRecord(
    $subscriptionItemId,
    ['quantity' => $apiCallsThisPeriod, 'action' => 'set']
);

action: set устанавливает абсолютное значение, increment — добавляет к текущему. set безопаснее при retry.