Antes de enviar la versión 1.1 de mi diario Lanternly pegué el mismo bloque de cuatro líneas al final de 39 descripciones del App Store, para iOS y para macOS. Es un bloque aburrido: una línea separadora, el acuerdo de licencia, la política de privacidad y los términos. Pero sin él, una app de suscripción corre el riesgo de volver con la marca 3.1.2, aunque la suscripción, el paywall y StoreKit estén bien hechos.
Aquí repaso de dónde sale realmente este requisito, por qué App Store Connect tiene un campo para la política y no para los términos, y qué texto acabé poniendo. Las citas de Apple son literales y las comprobé el 13 de octubre de 2026.
Dónde lo exige Apple#
Curiosamente, el texto de la propia regla 3.1.2 no menciona enlaces ni la palabra EULA. El apartado 3.1.2(c) pide explicar con claridad qué recibe la persona a cambio de su dinero y remite al Schedule 2 del acuerdo de licencia del programa de desarrolladores. Los requisitos están en otros tres sitios.
Schedule 2, sección 3.8(b). Enumera lo que hay que mostrar «de forma clara y visible» sobre una suscripción de renovación automática: nombre, duración y precio. Y en una línea aparte:
Links to Your Privacy Policy and Terms of Use must be accessible within Your Licensed Application.
Esto se refiere a la propia app.
La página Auto-renewable subscriptions añade los metadatos:
Please note that your app and App Store metadata must include links to your Terms of Use and Privacy Policy.
La regla 5.1.1(i) habla de la política de privacidad para todas las apps, no solo las de suscripción:
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.
En total son dos enlaces, y cada uno tiene que estar en dos sitios: en la app y en la ficha de la tienda.
Por qué los términos no tienen campo propio#
Con la política es sencillo. En «Información de la app» hay un campo Privacy Policy URL, obligatorio para iOS y macOS, que se rellena por separado para cada idioma.
Un campo «Terms of Use URL» no existe en App Store Connect. Hay un campo License Agreement, y la documentación dice esto sobre él:
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.
Así que hay dos caminos:
| Camino | Qué haces | Cuándo encaja |
|---|---|---|
| EULA propio en el campo License Agreement | Pegas el texto completo de tus términos, que sustituye al estándar | Tienes abogado y unos términos únicos para todas las regiones |
| EULA estándar + enlaces en la descripción | No tocas el campo y pones los enlaces al final de la Description | Casi todas las apps indie |
Yo elegí el segundo. Lanternly tiene sus propios términos, pero describen la suscripción y la app, y la licencia del software en sí la cubre sin problema el EULA estándar de Apple.
El bloque listo#
Esto es lo que va al final de cada descripción de Lanternly. Por encima de la línea está el texto normal; por debajo, solo los enlaces:
_____________________
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/Dentro hay varias decisiones.
Los nombres de las líneas van en inglés en todos los idiomas. Solo cambia la dirección del documento; las etiquetas se quedan igual. La línea «LICENSED APPLICATION END USER LICENSE AGREEMENT» la reconoce a primera vista quien revisa la app, esté en el idioma que esté el resto de la descripción. Esto es elección mía, no un requisito de Apple.
Enlace al EULA estándar aunque no lo haya cambiado. Sin él, los metadatos tienen la política y mis términos, pero no la licencia que de verdad se aplica. Muestro los tres documentos para que el revisor no tenga que adivinar.
Enlaces desnudos, completos y con protocolo. La descripción del App Store es texto plano y no admite HTML. Una dirección sin https:// puede no convertirse en enlace.
Todos los enlaces se abren sin iniciar sesión y sin redirecciones. Con esto ya me quemé. Rechazaron la versión de Mac por la regla 1.5 porque la Support URL pasaba por una redirección a una red social y al revisor no le cargó. Por eso, antes de enviar, conviene pasar cada dirección de la ficha por curl -sIL y comprobar que al final de la cadena hay un 200 y no una página de inicio de sesión.
El bloque ocupa 280 caracteres de 4000. En la descripción en francés eso resultó importante: el texto no cabía. Quité las líneas «Privacy policy / Terms of use» de la mitad de la descripción, que repetían el bloque, y el francés se quedó en 3917 caracteres.
Encima del bloque: el párrafo sobre la suscripción#
Los enlaces cubren los documentos. Pero la 3.8(b) también pide mostrar las condiciones de la propia suscripción. El precio no lo escribo en la descripción: cambia en cada país y el paywall lo muestra en la moneda del comprador. El resto lo pongo en un párrafo:
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.En la descripción, la semana de prueba aparece como una característica de la suscripción. Dentro de la app, la frase sobre la semana solo aparece si a esa persona todavía le corresponde el periodo de prueba (isEligibleForIntroOffer); si no, sería una promesa que la tienda no va a cumplir.
Los mismos enlaces en la app#
La otra mitad del requisito vive en el código. En el paywall de Lanternly, debajo del botón de compra, hay una fila «Restaurar · Términos · Política». Una versión mínima que funciona, con SwiftUI y StoreKit 2:
import SwiftUI
import StoreKit
enum LegalLinks {
// Idioma del documento: según el idioma de la interfaz de la app, no según la región del dispositivo
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)
}
}Fíjate en preferredLocalizations. La región del dispositivo es una mala pista: alguien con la interfaz en ruso que vive en Alemania tiene la región alemana. El idioma de la interfaz, en cambio, es el idioma en el que acaba de leer el paywall. El botón «Restaurar» está en la misma fila por la misma razón que los enlaces: Apple lo exige en la pantalla de contratación de la suscripción.
Si hay muchos idiomas#
Lanternly tiene la interfaz en dos idiomas y la ficha de la tienda en 39. Los documentos en el sitio web están en cinco: inglés, ruso, español, japonés y chino. La regla quedó así: cada idioma de la ficha enlaza al documento en su idioma si existe. Los idiomas españoles van a /es/, el japonés a /ja/, los dos chinos a /zh-CN/ y todos los demás a /en/.
El campo Privacy Policy URL de «Información de la app» también se localiza. La documentación lo marca como obligatorio para iOS y macOS, así que al añadir un idioma es fácil olvidarlo: vive en otra sección, no junto a la descripción.
Lo que Apple no aclara#
- En qué campo exacto de los metadatos debe ir el enlace a los términos. La página de suscripciones dice «App Store metadata» y no nombra el campo. La descripción es la opción más evidente, pero formalmente también vale un texto propio en License Agreement.
- Si hace falta el bloque en cada idioma. No lo dice en ninguna parte. Yo lo pongo en todos: el revisor puede abrir la ficha en cualquier idioma, y 280 caracteres no es mucho precio.
- Si basta el EULA estándar en lugar de unos términos propios. Para muchas apps, al parecer, sí. Pero si la suscripción da acceso a un servicio con sus propias reglas, necesitas unos términos propios, y conviene redactarlos con un abogado.
Una lista corta antes de enviar: la Privacy Policy URL está rellenada en todos los idiomas, al final de la descripción está el bloque con los tres enlaces, todas las direcciones devuelven 200 sin iniciar sesión y en el paywall están «Restaurar», «Términos» y «Política». Cómo traduje y revisé el resto de campos de esas 39 fichas lo cuento en el siguiente artículo.



