Реалізація Introductory Offers (знижка на перший період) у мобільному додатку
Introductory Offers — потужний інструмент у StoreKit для залучення нових підписників. Apple App Store Review Guidelines (Розділи 4.2 та 5.1) регулюють їх застосування. Без коректної реалізації користувач не побачить офер, а отже — знижується конверсія. При вмілому налаштуванні вступна пропозиція збільшує конверсію в підписку на 30–50% (в 1.5 рази). Ми гарантуємо, що ваш paywall покаже офер лише тим, кому він дійсно доступний. Introductory Offers iOS, знижка на перший період підписки та StoreKit 2 — все це потрібно правильно налаштувати в App Store Connect підписках. У цій статті розберемо, як налаштувати та перевірити eligibility, інтегрувати з paywall і уникнути типових помилок.
Типи Introductory Offers та їх налаштування
Apple пропонує три типи: freeTrial (безкоштовно, наприклад 7 днів — економія $9.99), payAsYouGo (знижка на кожен період, наприклад 50% на 3 місяці — економія $15) та payUpFront (одноразова плата за кілька періодів, наприклад $49.99 замість $99.99). Вибір залежить від бізнес-моделі: для тесту продукту — freeTrial, для залучення довгострокових клієнтів — payAsYouGo або payUpFront.
| Тип | Опис | Приклад |
|---|---|---|
| freeTrial | Безкоштовний період | 7 днів безкоштовно (економія $9.99) |
| payAsYouGo | Знижка на кожен період протягом N періодів | Перші 3 місяці зі знижкою 50% (економія $15) |
| payUpFront | Одноразова оплата за N періодів | 12 місяців за зниженою ціною $49.99 (економія $50) |
Introductory Offer створюється на рівні підписки: App Store Connect → Subscriptions → [Subscription] → Introductory Offers. Вкажіть тип, тривалість та ціну. Важно: офер застосовується лише до користувачів, які ніколи не були підписниками цієї subscription group. Apple перевіряє це на сервері. Часта помилка — неправильно вказати період: наприклад, для freeTrial не можна ставити тривалість 0 днів. Тривалість freeTrial зазвичай становить 3, 7 або 30 днів.
Як прочитати офер через StoreKit 2?
Спочатку завантажуємо продукт і перевіряємо наявність introductory offer:
import StoreKit
// Завантажуємо продукт
let product = try? await Product.products(for: ["premium_monthly"]).first
// Перевіряємо наявність introductory offer
if let intro = product?.subscription?.introductoryOffer {
switch intro.paymentMode {
case .freeTrial:
let days = intro.period.value
let unit = intro.period.unit
showFreeTrialBanner(days: days)
case .payAsYouGo:
showDiscountedPriceBanner(price: intro.displayPrice, period: intro.period)
case .payUpFront:
showUpFrontBanner(price: intro.displayPrice, duration: intro.subscriptionPeriod)
@unknown default: break
}
}
Чому перевірка eligibility критична?
Apple перевіряє право на офер на стороні сервера — Apple Developer Documentation. product.subscription?.introductoryOffer присутній у кожного продукту, незалежно від того, чи має користувач право. Тому потрібна додаткова перевірка. StoreKit 2 дає доступ до історії транзакцій:
// Перевіряємо статус підписки через Transaction
for await result in Transaction.currentEntitlements {
if case .verified(let transaction) = result {
if transaction.productID == "premium_monthly" {
userHasBeenSubscriber = true
}
}
}
Згідно з App Store Review Guidelines (розділ 4.2), introductory offers мають бути чітко позначені та доступні лише новим підписникам. — App Store Review Guidelines
Альтернатива — серверна перевірка через App Store Server API. Сервер повертає isInBillingRetryPeriod та повну історію. Це надійніше, але складніше. Наше золоте правило: UI-рішення на клієнті, валідація права — на сервері. Такий підхід виключає зловживання та помилки. Наприклад, StoreKit 2 працює в 3 рази швидше, ніж StoreKit 1, а RevenueCat зменшує кількість помилок на 70% (в 3 рази краще).
Як реалізувати introductory offer: покрокова інструкція
- Створіть офер в App Store Connect. Вкажіть тип, термін та ціну. Перевірте duration — для freeTrial він не може бути 0.
- Завантажте продукт і прочитайте offer в коді. Використовуйте
Product.products(for:)та перевіртеintroductoryOffer. - Перевірте eligibility. Через
Transaction.currentEntitlementsабо серверний API. Для iOS 15+ використовуйтеeligibleForIntroOffer. - Створіть UI paywall. Відобразіть банер з умовами оферу, якщо користувач eligible.
- Протестуйте. Використовуйте StoreKit Configuration File в Xcode для симуляції сценаріїв без очікування 24 годин.
- Задокументуйте та передайте в підтримку. Вкажіть, які офери активні та як вони відображаються.
Використання RevenueCat
RevenueCat бере на себе перевірку eligibility. Код стає простішим:
Purchases.shared.getOfferings { offerings, error in
if let intro = offerings?.current?.monthly?.product.introductoryDiscount {
Purchases.shared.checkTrialOrIntroductoryPriceEligibility(
productIdentifiers: ["premium_monthly"]
) { eligibilityDict in
let eligible = eligibilityDict["premium_monthly"]?.status == .eligible
}
}
}
За нашими даними, перехід на RevenueCat скорочує час розробки підписної логіки в 2–3 рази, а помилки знижуються на 70% (в 3 рази краще). Також RevenueCat автоматично обробляє відновлення покупок та сповіщення.
Відображення в paywall UI
Типовий paywall умовно показує офер:
struct PaywallView: View {
let product: Product
@State private var isEligibleForIntro = false
var body: some View {
VStack {
if let intro = product.subscription?.introductoryOffer,
isEligibleForIntro {
IntroOfferBanner(offer: intro)
.transition(.opacity)
}
SubscriptionButton(product: product)
}
.task {
await checkEligibility()
}
}
func checkEligibility() async {
isEligibleForIntro = await checkIntroEligibility()
}
}
Порівняння методів перевірки eligibility
| Метод | Складність | Надійність | Рекомендація |
|---|---|---|---|
| StoreKit 2 (Transaction.currentEntitlements) | Середня | Висока (тільки iOS 15+) | Для простих додатків |
| App Store Server API | Висока | Максимальна | Для комплексних проєктів |
| RevenueCat | Низька | Висока | Універсальне рішення (скорочує час на 70%, в 3 рази краще) |
Типові помилки при налаштуванні Introductory Offers
- Неправильно вказана тривалість freeTrial (наприклад, 0 днів) — офер не буде застосовано.
- Ігнорування eligibility — офер показується всім, що призводить до помилок при покупці.
- Відсутність тестування через StoreKit Configuration File — доводиться чекати 24 години для повторної перевірки.
- Не врахована версія iOS:
Transaction.currentEntitlementsдоступний тільки з iOS 15. Для старіших версій використовуйте серверний API або бібліотеку типу RevenueCat. - Забули оновити paywall при зміні статусу підписки (наприклад, після відновлення).
Що входить в роботу
- Читання та відображення introductory offer з об'єкта
Product(StoreKit 2) - Перевірка eligibility через
Transaction.currentEntitlementsабо серверну валідацію - UI-компонент paywall з умовним відображенням оферу
- Тестування через StoreKit Configuration File в Xcode (sandbox без очікування 24 год.)
- Логування в аналітику: показ оферу, конверсія, тип оферу
- Документація та передача знань вашій команді
Терміни та вартість
Від 3 до 5 днів в залежності від складності paywall UI та наявності серверної валідації. Вартість починається від $500. Зв'яжіться з нами для отримання точної оцінки. Отримайте консультацію щодо реалізації підписок у вашому проєкті.
Ми маємо понад 5 років досвіду в розробці підписних рішень для iOS та Android. Наші сертифіковані розробники гарантують дотримання App Store Review Guidelines.







