Реалізація Grace Period при невдалому списанні підписки

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація Grace Period при невдалому списанні підписки
Середній
~2-3 дні
Часті запитання

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

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Реалізація Grace Period при неудачному списанні підписки

Grace Period — це тимчасове вікно, яке Apple і Google дають користувачам після неудачного списання: карта вичерпала, недостатньо коштів, тимчасовий збій банку. Протягом grace period підписка вважається активною. Завдання розробника — коректно читати цей статус і не відрізати користувача від контенту передчасно.

Без реалізації grace period застосунок блокує доступ одразу після неудачного списання. Користувач оновляє карту, але вже пішов — прямі втрати в retention.

Grace Period на iOS (StoreKit 2)

Apple автоматично активує grace period, якщо він включений у App Store Connect → Subscriptions → [Subscription Group] → Grace Period. Варіанти тривалості: 3, 6 або 16 днів.

Для читання статусу використовуємо Product.SubscriptionInfo.Status:

import StoreKit

func checkSubscriptionStatus(productId: String) async -> SubscriptionAccessLevel {
    guard let product = try? await Product.products(for: [productId]).first,
          let statuses = try? await product.subscription?.status else {
        return .notSubscribed
    }

    for status in statuses {
        switch status.state {
        case .subscribed:
            return .active

        case .inGracePeriod:
            // Списання не пройшло, але grace period активен
            // Показуємо м'яке попередження, не блокуємо контент
            return .gracePeriod

        case .inBillingRetryPeriod:
            // Grace period спливу, Apple продовжує спроби списання (до 60 днів)
            // Контент НЕ доступен
            return .billingRetry

        case .expired, .revoked:
            return .notSubscribed

        default:
            continue
        }
    }
    return .notSubscribed
}

enum SubscriptionAccessLevel {
    case active, gracePeriod, billingRetry, notSubscribed
}

Що показувати користувачу у grace period

Ключовий принцип: не блокувати контент, але показати м'яке повідомлення з закликом оновити платіжні дані. Агресивний paywall у grace period — це поганий UX та порушення гайдлайнів Apple.

// SwiftUI-баннер
if subscriptionStatus == .gracePeriod {
    GracePeriodWarningBanner(
        message: "Не вдалося обробити платіж. Оновіть дані карти, щоб зберегти доступ.",
        actionTitle: "Управління підпискою",
        action: { openManageSubscriptions() }
    )
}

// Відкриваємо системний екран управління підписками
func openManageSubscriptions() {
    Task {
        try? await AppStore.showManageSubscriptions(in: windowScene)
    }
}

Grace Period на Android (Google Play Billing)

У Google Play Billing grace period реалізується через purchaseState та isAutoRenewing:

// Через RTDN (Real-Time Developer Notifications) або PurchasesUpdatedListener
// Google відправляє SubscriptionNotification.SUBSCRIPTION_IN_GRACE_PERIOD

fun handleSubscriptionNotification(notification: SubscriptionNotification) {
    when (notification.notificationType) {
        SubscriptionNotification.SUBSCRIPTION_IN_GRACE_PERIOD -> {
            // Контент доступен, показуємо попередження
            showGracePeriodWarning()
        }
        SubscriptionNotification.SUBSCRIPTION_EXPIRED -> {
            // Grace period спливу
            revokeAccess()
        }
    }
}

Серверна обробка переважна: RTDN надходить на backend через Pub/Sub, бэкенд оновлює статус користувача, мобільний клієнт отримує актуальний статус при наступному запиті.

Серверна валідація — надійніша клієнтської

Клієнтська перевірка через StoreKit — зручна для UI, але не повинна бути єдиним джерелом істини. Правильна архітектура:

  1. Сервер отримує транзакції через App Store Server Notifications V2 (типи DID_FAIL_TO_RENEW, GRACE_PERIOD_EXPIRED)
  2. Оновлює поле subscription_status у базі
  3. Мобільний клієнт при запиті /me/subscription отримує актуальний статус

Це єдиний надійний спосіб, якщо користувач відкрив застосунок через кілька днів — кеш StoreKit міг не оновитися.

Що входить у роботу

  • Включення grace period у App Store Connect / Google Play Console
  • Клієнтське читання inGracePeriod / inBillingRetryPeriod (StoreKit 2)
  • UI-баннер з попередженням та посиланням на управління підпискою
  • Логіка доступу до контенту: grace = дозволено, billingRetry = заблоковано
  • Опційно: серверна обробка App Store Server Notifications

Терміни

2–3 дні — клієнтська частина з UI-логікою. З серверною обробкою сповіщень: 4–5 днів. Вартість розраховується індивідуально.