1.1.5: conversion funnel overhaul

Paywall:
- Redesigned PremiumView with yearly/monthly/lifetime side by side
- 7-day free trial badge with savings % vs monthly
- Social proof line, BEST VALUE highlight on yearly
- StoreManager: new yearlyProduct, lifetimeProduct, yearlySavingsPercent, hasTrialAvailable

Funnel:
- Paywall step added to onboarding (PaywallStepView)
- Contextual modal at dish limit (replaces silent block)
- Visible "X/15 dishes" counter in DishListView
- BottomPromoBanner rotates AdMob with internal "Remove ads" CTA (1 in 4)
- Free dish limit lowered 20 → 15
- Review prompt earlier: 2 weeks → 1 week

Analytics:
- paywall_viewed/dismissed with source + seconds_on_screen
- dish_limit_hit, week_limit_hit, free_trial_started events
- Every PremiumView call site now passes its source

StoreKit:
- MealMood.storekit: added yearly $19.99 + 7d trial, monthly trial, lifetime $39.99
- AppStoreConnect-1.1.5-setup.md with full manual setup instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-06-11 22:21:36 +02:00
parent 72770801d3
commit b45cb2a530
31 changed files with 1067 additions and 104 deletions
+217
View File
@@ -0,0 +1,217 @@
# App Store Connect — Setup para 1.1.5
Esta guía cubre los 3 cambios manuales que hay que hacer en App Store Connect antes de subir la build 51 a TestFlight / App Store. Todo está alineado con `MealMood.storekit` local, así que puedes probar el flujo en simulador antes de tocar producción.
Resumen:
1. **Crear yearly subscription** ($19.99 / 7-day trial)
2. **Añadir 7-day trial al monthly existente**
3. **Actualizar el lifetime existente** (precio $39.99, renaming opcional)
---
## 1. Crear yearly subscription
**Path:** App Store Connect → MealMood → Subscriptions → Subscription Group "MealMood Premium" → **+** Create Subscription
### Datos principales
| Campo | Valor |
|---|---|
| Reference Name | `MealMood Premium Yearly` |
| Product ID | `com.alexandrevazquez.mealmood.premium.yearly.sub` |
| Subscription Group | MealMood Premium *(mismo grupo que el monthly)* |
| Subscription Duration | 1 year |
| Price (USD) | **$19.99** |
| Family Sharing | ✅ Enabled |
| Available Countries | Mismas que el monthly (All Countries/Regions recomendado) |
| Cleared for Sale | ✅ |
> ️ Al guardar, App Store Connect te asignará automáticamente el tier de precio equivalente en cada divisa.
### Localizations (6 idiomas)
**Subscription Display Name** + **Description** por idioma:
#### English (U.S.) — Primary
- **Display Name:** `MealMood Premium Yearly`
- **Description:** `Unlimited dishes, advanced rotation rules, ad-free and stats — billed yearly. Best value, save vs monthly.`
#### Spanish (Spain)
- **Display Name:** `MealMood Premium Anual`
- **Description:** `Platos ilimitados, reglas avanzadas de rotación, sin anuncios y estadísticas — facturación anual. La mejor oferta, ahorra frente al plan mensual.`
#### French (France)
- **Display Name:** `MealMood Premium Annuel`
- **Description:** `Plats illimités, règles avancées de rotation, sans publicité et statistiques — facturation annuelle. Meilleur prix, économisez par rapport au mensuel.`
#### German
- **Display Name:** `MealMood Premium Jährlich`
- **Description:** `Unbegrenzte Gerichte, erweiterte Rotationsregeln, werbefrei und Statistiken — jährliche Abrechnung. Bestes Angebot, sparen Sie gegenüber dem Monatsplan.`
#### Italian
- **Display Name:** `MealMood Premium Annuale`
- **Description:** `Piatti illimitati, regole avanzate di rotazione, senza pubblicità e statistiche — fatturazione annuale. Miglior prezzo, risparmia rispetto al piano mensile.`
#### Portuguese (Brazil)
- **Display Name:** `MealMood Premium Anual`
- **Description:** `Pratos ilimitados, regras avançadas de rotação, sem anúncios e estatísticas — cobrança anual. Melhor oferta, economize em relação ao plano mensal.`
### Subscription Introductory Offer (free trial)
**Path:** En el detalle del yearly → **Subscription Prices****Introductory Offers****+** Create Introductory Offer
| Campo | Valor |
|---|---|
| Countries | All Countries (where the subscription is available) |
| Offer Type | **Free** |
| Duration | **1 Week** |
| Available to | New Subscribers only |
| Start Date | Today |
| End Date | (none — open-ended) |
> ⚠️ Esto es lo que activa el "7-day free trial" en la app. Sin esto, el `introductoryOffer` será null en el StoreKit response.
### Review Information (lo verá Apple Review)
- **Screenshot:** sube una captura del paywall mostrando el plan anual seleccionado con el badge "BEST VALUE" y el botón "Start free trial"
- **Review Notes:**
```
Yearly subscription unlocking Premium features: unlimited dishes,
advanced tag rotation rules, ad removal, statistics dashboard,
unlimited future weeks planning, and meal plan export.
Includes a 7-day free trial for new subscribers.
To test: launch app → Settings → Premium, or trigger any paywall
from dish limit / share button.
```
---
## 2. Añadir 7-day free trial al monthly existente
**Path:** App Store Connect → MealMood → Subscriptions → `com.alexandrevazquez.mealmood.premium.monthly.sub` → **Subscription Prices** → **Introductory Offers** → **+** Create Introductory Offer
| Campo | Valor |
|---|---|
| Countries | All Countries (where the subscription is available) |
| Offer Type | **Free** |
| Duration | **1 Week** |
| Available to | New Subscribers only |
| Start Date | Today |
| End Date | (none) |
> ️ No hace falta tocar nada más del monthly. El precio se queda en $2.99, sólo se le añade el trial.
---
## 3. Actualizar el lifetime existente
**Path:** App Store Connect → MealMood → In-App Purchases → `com.mealmood.premium.monthly` (es Non-Consumable, no toques el ID — sí, el nombre es engañoso pero es el legacy lifetime)
### Cambios
| Campo | Valor actual | Valor nuevo |
|---|---|---|
| Reference Name | MealMood Premium Legacy | `MealMood Premium Lifetime` |
| Price (USD) | $2.99 | **$39.99** |
| Family Sharing | Disabled | ✅ **Enabled** |
| Cleared for Sale | ✅ | ✅ (mantener) |
> ⚠️ El **Product ID NO se puede cambiar** una vez creado. Por eso aunque diga `monthly` en el nombre, sigue siendo nuestro lifetime. El código ya lo trata como tal (`StoreManager.legacyOneTimeProductId`).
### Localizations (6 idiomas)
Actualiza los display names y descriptions:
#### English (U.S.) — Primary
- **Display Name:** `MealMood Premium Lifetime`
- **Description:** `Unlock everything forever with a single one-time payment. No subscription, no renewals — yours to keep.`
#### Spanish (Spain)
- **Display Name:** `MealMood Premium De Por Vida`
- **Description:** `Desbloquea todo para siempre con un único pago. Sin suscripción, sin renovaciones — tuyo para siempre.`
#### French (France)
- **Display Name:** `MealMood Premium À Vie`
- **Description:** `Débloquez tout pour toujours avec un seul paiement unique. Sans abonnement, sans renouvellement — c'est à vous pour toujours.`
#### German
- **Display Name:** `MealMood Premium Lebenslang`
- **Description:** `Schalte alles dauerhaft mit einer einmaligen Zahlung frei. Kein Abo, keine Verlängerung — gehört dir für immer.`
#### Italian
- **Display Name:** `MealMood Premium A Vita`
- **Description:** `Sblocca tutto per sempre con un unico pagamento. Niente abbonamento, niente rinnovi — è tuo per sempre.`
#### Portuguese (Brazil)
- **Display Name:** `MealMood Premium Vitalício`
- **Description:** `Desbloqueie tudo para sempre com um único pagamento. Sem assinatura, sem renovações — é seu para sempre.`
### Review Information (si Apple lo pide)
- **Screenshot:** captura del paywall con el lifetime visible debajo de los planes mensual/anual con el badge "PAY ONCE"
- **Review Notes:**
```
One-time purchase unlocking all Premium features permanently:
unlimited dishes, advanced tag rules, ad removal, statistics,
unlimited future weeks, meal plan export. Family Sharing enabled.
Acts as an alternative to the monthly/yearly subscriptions for
users who prefer a single payment.
```
---
## 4. Verificación post-setup
Antes de subir la build:
### Comprobaciones rápidas
- [ ] El yearly aparece en el subscription group **MealMood Premium**
- [ ] Yearly tiene el introductory offer activo (debe aparecer "Free for 1 week" en la sección Prices)
- [ ] Monthly tiene el introductory offer activo igual
- [ ] El lifetime está en $39.99 y Family Sharing está enabled
- [ ] Todos los productos están **"Ready to Submit"** o **"Approved"** *(no "Missing Metadata")*
### Estado esperado en App Store Connect
```
Subscriptions:
Group: MealMood Premium
├─ com.alexandrevazquez.mealmood.premium.monthly.sub $2.99 Ready [Intro: Free 1 week]
└─ com.alexandrevazquez.mealmood.premium.yearly.sub $19.99 Ready [Intro: Free 1 week]
In-App Purchases:
└─ com.mealmood.premium.monthly (Non-Consumable Lifetime) $39.99 Ready
```
---
## 5. Test en simulator (sin tocar producción)
El `.storekit` local ya tiene los 3 productos con sus precios y trial. Para probar:
1. Abre `MealMood.xcworkspace` (o el `.xcodeproj`)
2. Edit Scheme → Run → Options → **StoreKit Configuration:** `MealMood.storekit`
3. Run en simulator → abre paywall (Settings → Premium)
4. Deberías ver los 3 planes con el yearly preseleccionado, badge SAVE, lifetime debajo
5. Tap "Start free trial" → sandbox dialog → success → la app marca `isPremium = true`
Para resetear el estado del sandbox:
- En simulator: Debug → StoreKit → Manage Transactions → Delete All
---
## 6. Submit a TestFlight
Una vez los 3 productos estén "Ready to Submit":
```bash
fastlane beta
```
> ️ Apple necesita revisar las suscripciones nuevas + el intro offer junto con la app cuando subas a App Store (no a TestFlight). Para TestFlight no requiere review de IAP.
Cuando submitas a App Store con `fastlane release`, los 3 productos van **incluidos automáticamente** en el submission. Apple los revisa en paralelo con el binario.