Автоматические списания по подпискам делают доход от подписок стабильным. Но до 30% рекуррентных платежей отклоняются: карты просрочены, не хватает средств, банк блокирует операцию. Без автоматической обработки отказов вы теряете до 15% выручки от подписок. При ежемесячном обороте это ощутимые потери. Интеграция рекуррентных платежей с токенизацией и dunning стратегией возвращает до 80% неудачных списаний. Мы реализовали такие системы для Stripe и CloudPayments в проектах с тысячами подписчиков. Опыт — 10+ лет в обработке платежей и более 50 проектов с подписками. Получите консультацию по интеграции уже сегодня.
Как реализовать интеграцию рекуррентных платежей с помощью токенизации?
Токенизация — сохранение платёжных данных в виде токена у шлюза. Первый платёж проходит с участием пользователя, последующие инициирует сервер. Stripe использует SetupIntent для безопасного сбора карты, затем PaymentIntent с параметром off_session: true для списания без 3DS. Это стандартный подход в документации Stripe.
Сервер — сохранение метода оплаты
\Stripe\Stripe::setApiKey(config('services.stripe.secret')); $stripeCustomer = \Stripe\Customer::create([ 'email' => $user->email, 'metadata' => ['user_id' => $user->id], ]); $user->update(['stripe_customer_id' => $stripeCustomer->id]); $setupIntent = \Stripe\SetupIntent::create([ 'customer' => $user->stripe_customer_id, 'usage' => 'off_session', 'automatic_payment_methods' => ['enabled' => true], ]); return response()->json(['clientSecret' => $setupIntent->client_secret]); Сервер — последующее списание без участия пользователя
public function chargeRecurring(User $user, int $amountCents): void { \Stripe\Stripe::setApiKey(config('services.stripe.secret')); $paymentMethod = $user->default_payment_method_id; try { $paymentIntent = \Stripe\PaymentIntent::create([ 'amount' => $amountCents, 'currency' => 'usd', 'customer' => $user->stripe_customer_id, 'payment_method' => $paymentMethod, 'confirm' => true, 'off_session' => true, 'description' => "Subscription - {$user->id}", ]); if ($paymentIntent->status === 'succeeded') { $this->recordSuccessfulCharge($user, $paymentIntent); } } catch (\Stripe\Exception\CardException $e) { $this->handleFailedCharge($user, $e->getError()->decline_code); } catch (\Stripe\Exception\InvalidRequestException $e) { if ($e->getStripeCode() === 'authentication_required') { $this->sendAuthenticationEmail($user, $e->getError()->payment_intent->id); } } } Почему до 30% платежей отклоняются?
Основные причины: истекший срок действия карты, недостаток средств, банковский фрод-мониторинг, технические сбои. При ручной обработке каждый отказ — потерянный доход. Автоматическая стратегия повторов (dunning) позволяет вернуть большую часть этих платежей. Например, у нас на проектах с облачным сервисом после внедрения dunning отказ снизился с 25% до 8%.
Обработка неудачных списаний
Неудачи — норма для рекуррентных платежей. Применяем dunning с экспоненциальной задержкой: первая попытка через 1 день, вторая через 3 дня, третья через 7 дней. Если после трёх попыток списание не проходит, подписка переводится в статус past_due, клиент получает письмо с просьбой обновить карту. Дополнительно запускается dunning-процесс — серия из 3-5 напоминаний. Вот пример класса для обработки:
class RecurringChargeJob implements ShouldQueue { public int $tries = 3; public function backoff(): array { return [86400, 259200, 604800]; } public function handle(): void { $subscription = Subscription::find($this->subscriptionId); if ($subscription->failed_attempts >= 3) { $subscription->update(['status' => 'past_due']); Mail::to($subscription->user)->send(new PaymentFailedMail($subscription)); return; } try { app(RecurringPaymentService::class)->charge($subscription); $subscription->update([ 'failed_attempts' => 0, 'status' => 'active', 'next_charge_at' => now()->addMonth(), ]); } catch (PaymentFailedException $e) { $subscription->increment('failed_attempts'); throw $e; } } } Stripe Billing — готовое решение
Если управлять расписанием самостоятельно не хочется, Stripe Billing делает это за вас. Просто создайте продукт и цену, затем подписку. Webhook обработает все события: успешные платежи, сбои, продления. Stripe Billing реализуется в 2 раза быстрее, чем собственная токенизация, и снижает нагрузку на сервер.
\Stripe\Stripe::setApiKey(config('services.stripe.secret')); $product = \Stripe\Product::create(['name' => 'Pro Plan']); $price = \Stripe\Price::create([ 'unit_amount' => 2900, 'currency' => 'usd', 'recurring' => ['interval' => 'month'], 'product' => $product->id, ]); $subscription = \Stripe\Subscription::create([ 'customer' => $user->stripe_customer_id, 'items' => [['price' => $price->id]], 'payment_behavior' => 'default_incomplete', 'expand' => ['latest_invoice.payment_intent'], ]); Webhook-обработчик должен слушать события invoice.payment_succeeded, invoice.payment_failed, customer.subscription.updated. Каждое событие обновляет статус подписки в локальной БД. Важно идемпотентно обрабатывать повторные уведомления — проверять по Stripe Event ID. Для тестирования используйте Stripe CLI с командой stripe listen --forward-to localhost/webhook.
Какой подход выбрать: токенизация или Subscription API?
Выбор между токенизацией и Subscription API определяет уровень контроля и скорость разработки. Токенизация даёт полный контроль над расписанием и данными, но требует больше кода и тестирования. Subscription API упрощает управление подписками за счёт шлюза, но привязывает к нему и ограничивает гибкость.
Сравнение токенизации и Subscription API
| Критерий | Токенизация | Subscription API |
|---|---|---|
| Контроль | полный | частичный |
| Надёжность | ниже (выше нагрузка) | выше (шлюз управляет) |
| Привязка к шлюзу | слабая (можно мигрировать) | жёсткая |
| Сложность реализации | средняя | низкая |
| Время разработки | 3-6 недель | 1-3 недели |
Получите консультацию по выбору подхода для вашего бизнеса.
Что входит в работу
- Документация: API-спецификация интеграции, описание webhook-событий, схема базы данных подписок.
- Доступы: настройка окружений (dev/staging/prod), создание аккаунтов шлюзов, настройка webhook-секретов.
- Обучение: передача знаний команде, демонстрация админ-панели управления подписками.
- Поддержка: гарантийное обслуживание 1 месяц после сдачи, исправление багов по hotfix.
Процесс работы
- Аналитика — изучаем вашу бизнес-логику, частоту списаний, требования к dunning.
- Проектирование — выбираем стек (Stripe, CloudPayments), модель токенизации или Subscription API.
- Реализация — интеграция платёжного шлюза, создание таблицы подписок, webhook-обработчики, джобы.
- Тестирование — проверка оплаты, отказов, grace-периодов, повторных попыток.
- Деплой и мониторинг — настройка алертов, логирование ошибок, обновление документации.
Свяжитесь с нами для обсуждения деталей вашего проекта.
Сроки и стоимость
| Вариант | Срок разработки |
|---|---|
| Токенизация | 3–6 недель |
| Stripe Billing | 1–3 недели |
Базовая интеграция с одним шлюзом — от 3 до 6 недель. Если нужны сложные биллинг-циклы, несколько шлюзов или нестандартные стратегии повторов — срок увеличивается до 8–10 недель. Стоимость рассчитывается индивидуально.
Закажите интеграцию рекуррентных платежей под ключ — мы гарантируем надёжность и прозрачность на всех этапах.







