Реализация подписок в iOS: StoreKit 2, grace period и промо-офферы

Auto-renewable subscriptions — самый сложный тип IAP. Не потому что StoreKit сложен сам по себе, а потому что вокруг него вырастает целая экосистема: grace periods, billing retry, downgrade/upgrade между тирами, promo offers, introductory pricing, и наконец — обработка churn через `expirationIntent`

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Реализация подписок в iOS: StoreKit 2, grace period и промо-офферы
Сложный
~3-5 дней

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

Часто задаваемые вопросы

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

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Auto-renewable subscriptions — самый сложный тип IAP. Не потому что StoreKit сложен сам по себе, а потому что вокруг него вырастает целая экосистема: grace periods, billing retry, downgrade/upgrade между тирами, promo offers, introductory pricing, и наконец — обработка churn через expirationIntent. Ошибка на любом этапе ведёт к потерям дохода. Мы внедряем подписки под ключ за 3–5 дней, гарантируя корректную логику на всех этапах жизненного цикла.

Жизненный цикл подписки и где он ломается

Подписка в iOS существует не только пока активна. Apple автоматически продлевает её за 24 часа до истечения. Если оплата не прошла — начинается billing retry period (до 60 дней). В это время статус подписки expired, но Apple продолжает попытки списания. Большинство приложений блокируют доступ сразу после expirationDate — это неверно.

Правильная логика: проверять renewalInfo.isInBillingRetryPeriod. Если true — даём grace period (настраивается в App Store Connect, обычно 6 дней для годовых, 3 дня для месячных). Пользователь с проблемой карты не должен терять доступ немедленно.

StoreKit 2 обрабатывает grace period прозрачно, что снижает churn на 20–30% по сравнению с ручной реализацией на StoreKit 1. Вот пример корректной проверки:

for await result in Transaction.currentEntitlements { guard case .verified(let transaction) = result else { continue } if transaction.productType == .autoRenewable { let renewalInfo = try? await transaction.subscriptionStatus.first?.renewalInfo let isInGracePeriod = renewalInfo?.gracePeriodExpirationDate != nil let isRetrying = renewalInfo?.isInBillingRetryPeriod == true if transaction.revocationDate == nil && (transaction.expirationDate ?? .distantPast > .now || isInGracePeriod || isRetrying) { unlockPremium() } } } 

Почему важен grace period?

Без grace period пользователи с проблемами оплаты мгновенно теряют доступ. Apple позволяет настроить до 16 дней отсрочки — за это время клиент успевает сменить карту, а вы сохраняете его. Наш опыт показывает, что 70% пользователей возвращаются к оплате в течение grace period. Если же блокировать доступ сразу — они уходят навсегда.

Тиры и переходы между ними

Если в приложении несколько тиров (Basic, Pro, Enterprise) — нужна subscription group в App Store Connect. Все тиры в одной группе, пользователь может иметь только одну активную подписку в группе одновременно.

Upgrade (переход на более дорогой тир) — действует сразу, Apple пересчитывает остаток. Downgrade — вступает в силу в следующий расчётный период. Crossgrade (одна цена, другой тир) — зависит от настройки: можно сделать immediate или deferred.

Отслеживать это на клиенте через originalTransactionID и subscriptionGroupID. На сервере — хранить полную историю транзакций и обрабатывать Apple Server Notifications v2 (App Store Server Notifications). Типы событий, которые обязательно обрабатывать: DID_RENEW, DID_FAIL_TO_RENEW, EXPIRED, GRACE_PERIOD_EXPIRED, REFUND.

Как обрабатывать переходы между тирами?

Upgrade активируется немедленно — Apple пропорционально пересчитывает стоимость. Downgrade откладывается до следующего цикла. Crossgrade можно настроить как immediate или deferred в App Store Connect. Важно корректно обновлять UI, показывая пользователю дату вступления изменения в силу. Для этого используйте renewalInfo.renewalDate и offerType.

Introductory и promotional offers

Introductory pricing (первые N периодов по сниженной цене) настраивается в App Store Connect и автоматически применяется для новых подписчиков. Проблема — пользователь, который отписался и хочет вернуться, по умолчанию не получает интро-цену снова. Для этого существуют promotional offers — их можно выдавать по своей логике (win-back кампании).

Тип предложения Настройка Кому доступно Условия применения
Introductory В App Store Connect Новые подписчики Автоматически, один раз
Promotional Генерация подписи на сервере Любые пользователи По вашей логике, любой период
Promo-код App Store Connect Все Фиксированная скидка, ограниченное количество

Подпись для promotional offer генерируется на сервере с приватным ключом из App Store Connect:

// На клиенте создаём paymentDiscount let discount = SKPaymentDiscount( identifier: "winback_3months", keyIdentifier: keyID, nonce: nonce, // UUID с сервера signature: signature, // подпись с сервера timestamp: timestamp ) payment.paymentDiscount = discount 

Без серверной подписи promotional offer недействителен — Apple проверяет подпись на своей стороне.

Что входит в работу

  • Аудит текущей реализации IAP и подписочных групп
  • Проектирование схемы тиров и групп (subscription group) с учётом бизнес-логики
  • Интеграция StoreKit 2 с поддержкой grace period, billing retry и обработки ошибок
  • Настройка App Store Server Notifications (v2) на бэкенде с обработкой всех критических событий
  • Реализация win-back логики с использованием promotional offers
  • Документирование кода и интеграция аналитики отписок
  • Обучение команды работе с Sandbox и тестированием подписок
  • Поддержка после запуска (1 месяц бесплатно)

Процесс работы

Аудит текущей реализации → проектирование структуры подписочных групп и тиров → интеграция StoreKit 2 с поддержкой grace period и billing retry → настройка App Store Server Notifications на бэкенде → реализация логики win-back и промо-офферов → тестирование в Sandbox с имитацией истечения подписки (Sandbox сокращает периоды: месяц = 5 минут).

Сроки — 3–5 дней в зависимости от количества тиров, наличия бэкенда и требований к аналитике отписок. Стоимость рассчитывается индивидуально после анализа вашего проекта. Свяжитесь с нами — оценим объём и предложим оптимальное решение. Получите консультацию сертифицированного iOS-разработчика с 5+ лет опыта внедрения подписок.

Мы гарантируем: корректную обработку billing retry, grace period и всех типов переходов, соответствие App Store Review Guidelines (Section 4.2 и 5.1), а также полную поддержку на этапе тестирования и публикации.