Синхронизация подписок с App Store и Google Play: где теряется консистентность
Главная ошибка — считать магазин источником истины по всем состояниям. На практике у вас есть как минимум две модели: локальный биллинг с собственной жизнью подписки и внешняя витрина, где статус может запаздывать, дублироваться или приходить вне порядка. Идемпотентность в биллинге — это не рекомендация, а базовый вопрос выживания системы.
Нужно проектировать не «обновление статуса», а конвейер событий: purchase, renew, cancel, grace, billing retry, refund. Для каждого события фиксируйте сырой payload, версию обработки и корреляционный ключ. Любая повторная доставка должна быть безопасной, иначе вы получите двойное продление, преждевременную деактивацию или revenue leakage.
Особое внимание — конфликтам состояний. Если локально подписка активна, а магазин уже прислал отмену, не выключайте доступ мгновенно без проверки срока оплаты и grace period. Если пришло продление после таймаута шлюза, сначала сверяйте цепочку транзакций, потом обновляйте entitlement. Давайте разберем, что происходит с транзакцией в момент сетевого сплита шлюза: именно там чаще всего рождаются фантомные статусы.
Минимальный набор защиты: журнал событий, дедупликация по transaction/order id, ретраи с экспоненциальной задержкой, отдельный reconciliation-job и алерты на расхождение между entitlement и магазином. Грамотно спроектированная dunning-стратегия способна спасти до 15% уходящей регулярной выручки.
Если у вас нет формальной модели состояний, начните не с интеграции, а с матрицы переходов: кто переводит подписку, при каком событии и что считать финальной истиной в споре локального и внешнего мира.
Подписки: биллинг-лаб
@subscriptions_billing_lab_arb
Синхронизация подписок с App Store и Google Play: где теряется консистентность
Этот пост опубликован в Telegram-канале Подписки: биллинг-лаб. Подписаться можно по ссылке: @subscriptions_billing_lab_arb.