Перед отправкой версии 1.1 моего дневника Lanternly я вставил один и тот же блок из четырёх строк в конец 39 описаний App Store, для iOS и для macOS. Блок скучный: черта, лицензионное соглашение, политика конфиденциальности, условия. Но без него подписочное приложение рискует уйти обратно с пометкой 3.1.2, хотя сама подписка, пейволл и StoreKit сделаны правильно.
Ниже разобрано, откуда это требование берётся на самом деле, почему для политики в App Store Connect есть поле, а для условий нет, и какой текст я в итоге поставил. Цитаты Apple приведены дословно и сверены 13 октября 2026 года.
Где Apple это требует#
Забавно, но в тексте самого правила 3.1.2 ни ссылок, ни слова EULA нет. Пункт 3.1.2(c) просит понятно объяснить, что человек получает за деньги, и отсылает к Schedule 2 лицензионного соглашения программы разработчиков. Требования лежат в трёх других местах.
Schedule 2, раздел 3.8(b). Там перечислено, что нужно «ясно и заметно» показать про автопродлеваемую подписку: название, длительность, цену. И отдельной строкой:
Links to Your Privacy Policy and Terms of Use must be accessible within Your Licensed Application.
Это про само приложение.
Страница Auto-renewable subscriptions добавляет метаданные:
Please note that your app and App Store metadata must include links to your Terms of Use and Privacy Policy.
Правило 5.1.1(i) говорит о политике конфиденциальности для всех приложений, не только подписочных:
All apps must include a link to their privacy policy in the App Store Connect metadata field and within the app in an easily accessible manner.
Итого две ссылки, и каждая нужна в двух местах: в приложении и в карточке магазина.
Почему для условий нет своего поля#
С политикой просто. В разделе «Информация о приложении» есть поле Privacy Policy URL, оно обязательное для iOS и macOS и заполняется для каждой локали отдельно.
Поля «Terms of Use URL» в App Store Connect нет. Есть поле License Agreement, и про него документация пишет так:
Apple provides a standard EULA (End-User License Agreement) that applies in all regions. You may provide a custom license agreement that supersedes the Apple EULA for one or more regions.
Получается два пути:
| Путь | Что делаете | Когда подходит |
|---|---|---|
| Свой EULA в поле License Agreement | Вставляете полный текст условий, он заменяет стандартный | Есть юрист и единые условия для всех регионов |
| Стандартный EULA + ссылки в описании | Поле не трогаете, ссылки ставите в конец Description | Почти все инди-приложения |
Я выбрал второй путь. Свои условия у Lanternly есть, но они описывают подписку и приложение, а лицензию на сам софт стандартный EULA Apple закрывает нормально.
Готовый блок#
Вот что стоит в конце каждого описания Lanternly. Над чертой идёт обычный текст, под ней только ссылки:
_____________________
LICENSED APPLICATION END USER LICENSE AGREEMENT - https://www.apple.com/legal/macapps/stdeula/
Privacy Policy - https://dodecaidr.pro/en/projects/lanternly/privacy-policy/
Terms and Conditions - https://dodecaidr.pro/en/projects/lanternly/terms-of-service/Несколько решений, которые в нём спрятаны.
Названия строк на английском во всех языках. Меняется только адрес документа, подписи остаются прежними. Строку «LICENSED APPLICATION END USER LICENSE AGREEMENT» человек, который проверяет приложение, узнаёт с первого взгляда, на каком бы языке ни было остальное описание. Это мой выбор, а не требование Apple.
Ссылка на стандартный EULA, хотя его не меняли. Без неё в метаданных есть политика и мои условия, но нет лицензии, которая реально действует. Я показываю все три документа, чтобы ревьюеру не пришлось догадываться.
Ссылки голые, полные, с протоколом. Описание в App Store — простой текст, HTML не поддерживается. Адрес без https:// может не стать ссылкой.
Все ссылки открываются без входа и без редиректов. На этом я уже обжигался. Mac-версию отклонили по правилу 1.5, потому что Support URL вёл через редирект в соцсеть и у ревьюера не открылся. Поэтому перед отправкой каждый адрес из карточки стоит прогнать через curl -sIL и убедиться, что в конце цепочки 200, а не страница входа.
Блок занимает 280 символов из 4000. На французском описании это оказалось важно: текст не влезал. Я убрал строки «Privacy policy / Terms of use» из середины описания, они повторяли блок, и французский уложился в 3917 символов.
Над блоком: абзац про подписку#
Ссылки закрывают документы. Но 3.8(b) просит ещё и показать условия самой подписки. Цену в описание я не пишу: она разная в каждой стране, и её показывает пейволл в валюте покупателя. Остальное пишу одним абзацем:
Lanternly+ is a monthly, six-month or yearly subscription with a 7-day free trial.
Payment is charged to your Apple account at confirmation of purchase.
The subscription renews automatically unless cancelled at least 24 hours
before the end of the current period. Manage or cancel it in your Apple account settings.В описании пробная неделя упомянута как свойство подписки. В самом приложении фраза про неделю появляется, только если человеку пробный период ещё положен (isEligibleForIntroOffer), иначе это обещание, которое магазин не выполнит.
Те же ссылки в приложении#
Вторая половина требования живёт в коде. На пейволле Lanternly под кнопкой покупки стоит ряд «Восстановить · Условия · Политика». Минимальная рабочая версия на SwiftUI и StoreKit 2:
import SwiftUI
import StoreKit
enum LegalLinks {
// Язык документа — по языку интерфейса приложения, а не по региону устройства
private static var lang: String {
(Bundle.main.preferredLocalizations.first ?? "en").hasPrefix("ru") ? "ru" : "en"
}
static var privacy: URL { URL(string: "https://example.com/\(lang)/privacy-policy/")! }
static var terms: URL { URL(string: "https://example.com/\(lang)/terms-of-service/")! }
}
struct PaywallLegalRow: View {
var body: some View {
HStack(spacing: 6) {
Button("Restore") { Task { try? await AppStore.sync() } }
Text("·")
Link("Terms", destination: LegalLinks.terms)
Text("·")
Link("Privacy", destination: LegalLinks.privacy)
}
.font(.footnote)
.foregroundStyle(.secondary)
.lineLimit(1)
}
}Обратите внимание на preferredLocalizations. Регион устройства тут плохая подсказка: у человека с русским интерфейсом, живущего в Германии, регион немецкий. А язык интерфейса — это язык, на котором он только что читал пейволл. Кнопка «Восстановить» стоит в том же ряду по той же причине, по которой там стоят ссылки: Apple требует её на экране оформления подписки.
Если языков много#
У Lanternly интерфейс на двух языках, а карточка в магазине на 39. Документы на сайте есть на пяти: английском, русском, испанском, японском и китайском. Правило получилось такое: локаль ведёт на документ своего языка, если он есть. Испанские локали идут на /es/, японская на /ja/, обе китайские на /zh-CN/, все остальные на /en/.
Поле Privacy Policy URL в «Информации о приложении» тоже локализуется. Документация называет его обязательным для iOS и macOS, так что при добавлении локали его легко забыть: оно живёт в другом разделе, не рядом с описанием.
Чего Apple не уточняет#
- В каком именно поле метаданных должна быть ссылка на условия. Страница подписок говорит «App Store metadata» и не называет поле. Описание — самый очевидный вариант, но формально подходит и свой текст в License Agreement.
- Нужен ли блок в каждой локали. Нигде не сказано. Я ставлю его во все: ревьюер может открыть карточку на любом языке, а 280 символов — небольшая цена.
- Достаточно ли стандартного EULA вместо своих условий. Для многих приложений, видимо, да. Но если подписка даёт сервис с собственными правилами, нужны свои условия, и писать их лучше вместе с юристом.
Короткий чек-лист перед отправкой: Privacy Policy URL заполнен во всех локалях, в конце описания стоит блок с тремя ссылками, все адреса отдают 200 без входа, на пейволле есть «Восстановить», «Условия» и «Политика». Как я перевёл и проверил остальные поля этих 39 карточек, рассказываю в следующей статье.



