Перейти к содержимому
DedicatedPHP Контакт

Восстанавливаемые состояния подписки для SaaS

Проектируйте восстанавливаемые состояния подписки, чтобы разделить платежи, договор и доступ, а также исправлять поздние и дублирующиеся платежные события.

Редакционная схема SaaS-потока, разделяющего договор, платежный цикл и возможности доступа

Платежный провайдер может с задержкой подтвердить списание, отправить одно и то же событие несколько раз или обработать операцию лишь частично. Поэтому «оплачено» и «есть доступ» не равнозначны. Если разрешение для аккаунта напрямую зависит от последнего ответа, полученного из платежного API, временный сбой может заблокировать клиента, который действительно заплатил, или предоставить доступ другому, чей платеж в итоге завершился ошибкой.

В состояниях подписки в SaaS PHP цель состоит не в хранении единственной метки в таблице. Нужно построить восстанавливаемый процесс: у каждого решения должны быть доказательство, ответственный, допустимый переход и способ сверки при поступлении новых данных.

Определите правила продукта до технической модели

Определите правила продукта до технической модели — guía visual de DedicatedPHP

Модель данных не устраняет коммерческие неоднозначности. Прежде чем проектировать сущности или webhooks, команды продукта, финансов и операций должны договориться о том, что происходит в каждой значимой ситуации.

  • Подключение: предоставляется ли доступ до подтверждения первого платежа, после авторизации или только после расчета?
  • Продление: когда начинается льготный период и какие возможности сохраняются в его течение?
  • Неуплата: предусмотрены ли автоматические повторные попытки, уведомления, частичные ограничения или полная приостановка?
  • Отмена: прекращается ли доступ немедленно или в конце уже оплаченного периода?
  • Возврат или спор: требует ли это немедленной блокировки, ручной проверки или отзыва после подтверждения результата?
  • Повторная активация: восстанавливает ли она в точности прежний тариф, создает новый коммерческий цикл или требует операционной проверки?

Также полезно различать отмену, запрошенную клиентом, и фактическую отмену. Первая выражает намерение; вторая изменяет будущее право доступа. Их смешение приводит к запутанным интерфейсам и автоматизациям, которые трудно исправить.

Разделяйте договор, платеж и фактический доступ

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

Такое разделение не позволяет превратить платежного провайдера в единственный источник истины для всего SaaS. Цикл может ожидать обработки, пока договор остается действующим в течение льготного периода. Одновременно аккаунт может сохранять доступ на чтение, но не иметь возможности создавать новые ресурсы. Возможности позволяют выразить это решение, не сводя его к ложной бинарности между активным и неактивным состояниями.

В PHP приложение может предоставлять сервис авторизации, который обращается к локальной проекции возможностей, например canCreateProject или canExportData. Эта проекция обновляется при изменении коммерческих фактов или фактов оплаты; ей не нужно вызывать провайдера при каждом запросе. Так уменьшаются задержка, внешняя зависимость и разброс условной логики по контроллерам, очередям и запланированным задачам.

Моделируйте переходы, ответственных и доказательства

Избегайте единственного поля status со значениями, добавляемыми по мере возникновения инцидентов. Лучше объявить состояния для каждого агрегата и разрешенные переходы. Например, платежный цикл может перейти из open в payment_pending, paid, failed, refunded или disputed. Не каждый переход обратим и не любой участник может его выполнить.

При каждом изменении нужно сохранять дату, источник, внешний идентификатор при его наличии и доказательство. Источником может быть внутренняя команда, проверенный webhook, запрос сверки или авторизованное ручное действие. Исправление службой поддержки не должно молча перезаписывать историю: его следует зарегистрировать как отдельное решение с причиной и ответственным оператором.

Приоритет при противоречивой информации

Определите, какое доказательство имеет приоритет. Экран перенаправления после оплаты не должен подтверждать цикл: он служит для информирования пользователя, а не является окончательным доказательством. Подписанный и проверенный webhook обычно дает более надежный сигнал, но может прийти поздно. Аутентифицированный запрос к провайдеру во время сверки может прояснить отсутствующие события. Если два источника расходятся, система должна перейти к проверке или в определенное состояние ожидания, а не произвольно выбирать самые последние данные.

Обрабатывайте поздние, дублирующиеся и неполные события

Получение события должно быть идемпотентным. Сохраняйте стабильный идентификатор внешнего события и хеш или ссылку на релевантную полезную нагрузку. При повторном получении отвечайте без повторного выполнения бизнес-эффекта. Это особенно важно, если платежное событие запускает выпуск документа, продление периода или уведомление.

Обработка должна разделять получение и применение. Сначала проверьте подпись, схему и происхождение; затем надежно сохраните полученное событие; наконец, обработайте задачу, которая пытается применить переход. Если процесс завершится сбоем после сохранения события, очередь или процесс восстановления сможет его продолжить. Если сбой произойдет до сохранения, сверка должна будет обнаружить расхождение, сравнив внутренние циклы с внешним источником.

событие получено → валидация → надежное сохранение → идемпотентное применение
                                      ↓
                              повторная попытка или сверка

Не предполагайте порядок доставки. Возврат может поступить раньше позднего подтверждения исходного платежа. Правила должны оценивать текущее состояние, ссылки на операции и известную последовательность, оставляя невозможные или неоднозначные случаи в очереди на проверку. Слепое применение «последнего полученного события» — частая причина ошибочных разрешений.

Сверка и разрешения как контролируемая проекция

Периодическая сверка — не заплатка, а часть проектирования. Она должна находить циклы, остающиеся открытыми слишком долго, платежи, подтвержденные вне системы, зарегистрированные, но необработанные события, дублирующиеся внешние ссылки и возможности, не соответствующие действующему договору. Обнаружив расхождение, зарегистрируйте находку и примените отслеживаемый переход вместо прямого обновления полей.

У проекции возможностей должны быть явные правила. Например, действующий договор с просроченным циклом, но в пределах льготного периода, может сохранять ключевые функции; по окончании льготного периода он может отключить операции записи. Когда поздний платеж подтверждается, система повторно активирует предусмотренные тарифом возможности и сохраняет историю предыдущего ограничения.

Кэш разрешений может быть полезен, но ему нужна инвалидация при изменении проекции и ограничение срока действия. Критическая авторизация также не должна основываться только на данных, хранящихся в браузере. Сервер должен принимать решение на основе текущей возможности и правильной области действия аккаунта, пользователя и ресурса.

Backoffice, аудит и тесты восстановления

Команде поддержки необходимо видеть, не редактируя записи базы данных, договор, циклы, внешние события, примененные переходы, текущие возможности и ручные действия. Она должна иметь возможность запросить сверку, повторить безопасное событие и открыть проверку. Исправления, меняющие доступ или баланс, требуют разграниченных прав, обязательного указания причины и аудиторской записи.

Тестируйте поток как последовательность сбоев, а не только как корректный платеж. Включите подтвержденное продление, неопределенный платеж, дубликаты, события вне порядка, возврат, отмену в конце периода и повторную активацию. Проверяйте как конечный результат, так и то, что ни одна повторная попытка не создает два периода, два документа или двойное расширение разрешений.

Гипотетический случай: цикл истекает, платеж остается в ожидании, и аккаунт входит в льготный период с ограниченными возможностями. Webhook подтверждения не обрабатывается из-за временного сбоя, но событие остается зарегистрированным. Идемпотентная повторная попытка подтверждает цикл, продлевает договор и восстанавливает возможности. Если бы событие не пришло, сверка нашла бы подтвержденную внешнюю операцию и создала тот же переход со своим собственным доказательством.

Предупреждающие сигналы и контрольный список

Предупреждающие сигналы и контрольный список — guía visual de DedicatedPHP

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

  • Являются ли договор, платежный цикл и возможности отдельными сущностями?
  • Есть ли у каждого перехода участник, доказательство, дата и причина?
  • Идемпотентны ли внешние события и сохраняются ли они до применения?
  • Есть ли сверка, способная восстановить незавершенные операции?
  • Вычисляются ли разрешения из локальной проекции, а не из ответа об оплате в реальном времени?
  • Может ли поддержка расследовать и исправлять с аудитом, без прямых изменений в production?
  • Охватывают ли тесты задержки, дубликаты, нарушение порядка и противоречия?

Восстанавливаемая модель не устраняет внешние сбои. Она делает их обнаруживаемыми, ограниченными и исправимыми, не превращая платежный инцидент в потерю контроля над доступом к продукту.

Хотите применить эти идеи в своем проекте?Давайте обсудим вашу PHP-платформу.
Посмотреть связанные услуги