Skip to main content

User Flows & UX Decisions

Questo documento descrive i flussi utente completi per la gestione abbonamenti e ti aiuta a scegliere tra diverse opzioni UX.

🎯 Decisioni Chiave​

Prima di implementare, devi decidere su questi punti:


1. Dove mostrare la Subscription UI?​

Opzione A: Tab dedicata "Premium" (Consigliato)​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 🏠 Home β”‚ πŸ“ Map β”‚ ⭐ Premium β”‚ βš™οΈ Settings β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pro: Sempre visibile, facile da trovare, alta conversione Contro: Occupa spazio nella tab bar

Opzione B: Dentro Settings​

Settings
β”œβ”€β”€ Profile
β”œβ”€β”€ Devices
β”œβ”€β”€ ⭐ Subscription ← qui
β”œβ”€β”€ Notifications
└── About

Pro: UI pulita, meno invasivo Contro: PiΓΉ nascosto, conversione piΓΉ bassa

Opzione C: Modal/Paywall quando serve​

Mostra paywall solo quando l'utente prova a usare feature premium.

[Vuoi aggiungere il 6Β° dispositivo?]
[Passa a Pro per dispositivi illimitati!]
[ Scopri Pro ] [Annulla]

Pro: Contestuale, l'utente capisce il valore Contro: PuΓ² essere frustrante

🎯 Raccomandazione​

Ibrido: Opzione A + C

  • Tab "Premium" per chi vuole esplorare
  • Paywall contestuale per feature bloccate

2. Flusso Acquisto iOS (StoreKit 2)​

Flusso Completo​

Opzione: Verifica Backend Immediata?​

A) Trust StoreKit (Consigliato per UX)

// Dopo purchase success, fidati di StoreKit
if case .success = result {
// Mostra subito Premium senza chiamare backend
showPremiumFeatures()
}

Pro: UX instantanea Contro: Se webhook fallisce, c'Γ¨ disallineamento (raro)

B) Verifica Backend

if case .success = result {
// Chiama backend per conferma
let status = try await api.checkSubscription(userId)
if status.isSubscribed {
showPremiumFeatures()
}
}

Pro: Stato sempre sincronizzato Contro: Latenza, puΓ² fallire

🎯 Raccomandazione​

Trust StoreKit + Sync periodico: Fidati di StoreKit per UX immediata, ma verifica con backend ogni volta che l'app torna in foreground.


3. Flusso Acquisto Android (Play Billing)​

Flusso Completo​

Acknowledge: Quando?​

A) Subito dopo purchase (Consigliato)

override fun onPurchasesUpdated(result, purchases) {
purchases?.forEach { purchase ->
if (purchase.purchaseState == PURCHASED) {
acknowledgePurchase(purchase) // Subito!
updateUI()
}
}
}

B) Dopo verifica backend

// Rischio: se backend non risponde, rischi refund automatico
val verified = api.verifyPurchase(purchase.purchaseToken)
if (verified) acknowledgePurchase(purchase)

4. Flusso Acquisto Web (Stripe)​

Flusso Checkout​

Opzione: Checkout Embedded vs Redirect​

A) Redirect a Stripe Hosted (Consigliato)

// Semplice, sicuro, meno responsabilitΓ  PCI
const { error } = await stripe.redirectToCheckout({ sessionId });

Pro: Stripe gestisce tutto, compliance PCI semplificata Contro: Utente esce dal tuo sito

B) Embedded Checkout

// Checkout inline nel tuo sito
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>

Pro: Esperienza seamless Contro: PiΓΉ complesso, piΓΉ responsabilitΓ 

Dopo il Pagamento​

Opzione: Polling vs Webhook

A) Solo Webhook (Consigliato)

  • Redirect a /subscription/success
  • Mostra "Processing..."
  • In background, webhook aggiorna DB
  • Utente fa refresh o torna piΓΉ tardi

B) Polling

// success_url?session_id=xxx
const checkStatus = async () => {
const session = await fetch(`/api/checkout/status/${sessionId}`);
if (session.payment_status === 'paid') {
showSuccess();
} else {
setTimeout(checkStatus, 2000);
}
};

5. Gestione Abbonamento Esistente​

Dove mettere "Manage Subscription"?​

Settings
└── Subscription
β”œβ”€β”€ Current Plan: Pro Monthly βœ“
β”œβ”€β”€ Renews: Jan 15, 2026
β”œβ”€β”€ [Change Plan] ← Upgrade/downgrade
└── [Cancel Subscription]

Come gestire Cancel/Change?​

ProviderMetodo
StripeRedirect a Billing Portal
AppleDeep link a Settings App Store
GoogleDeep link a Play Store subscriptions
// iOS - Apri gestione abbonamenti
if let url = URL(string: "https://apps.apple.com/account/subscriptions") {
UIApplication.shared.open(url)
}
// Android - Apri gestione abbonamenti
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://play.google.com/store/account/subscriptions")
}
startActivity(intent)

6. Restore Purchases (Mobile)​

Quando mostrare "Restore Purchases"?​

A) Sempre visibile (Consigliato per Apple Review)

Subscription Screen
β”œβ”€β”€ [Pro Monthly - €9.99]
β”œβ”€β”€ [Pro Annual - €99.99]
└── [Restore Purchases] ← Sempre visibile

Apple richiede questo button per approvazione.

B) Solo se non abbonato Mostra solo se currentEntitlements Γ¨ vuoto.

Flusso Restore​


7. Sincronizzazione Stato​

Quando verificare lo stato subscription?​

MomentoAzione
App LaunchTransaction.currentEntitlements / queryPurchases()
ForegroundRi-verifica entitlements
Tab Premium apertaFetch da backend
Dopo 24hSync con backend

Backend come Source of Truth?​

A) Client-first (Consigliato per UX)

  • StoreKit/Billing Library sono source of truth per UI
  • Backend Γ¨ per analytics e cross-platform check

B) Backend-first

  • Ogni check passa dal backend
  • PiΓΉ lento ma piΓΉ controllato

πŸ“Š Riepilogo Raccomandazioni​

DecisioneScelta Consigliata
Dove UITab Premium + Paywall contestuale
Verifica acquistoTrust store SDK, sync periodico
Acknowledge AndroidSubito dopo purchase
Web CheckoutStripe Hosted (redirect)
Gestione abbonamentoLink nativi a store
RestoreSempre visibile (Apple requirement)
Source of truthClient-first, backend-sync

βœ… Decisioni Implementate (Gennaio 2026)​

Dove mostrare la Subscription UI?​

Scelta: Opzione B + C - In Settings con Paywall contestuale

  • Impostazioni β†’ Gestisci Piano apre SubscriptionManagementView
  • Paywall contestuale quando utente prova ad aggiungere dispositivo senza licenze

Upgrade/Downgrade​

Implementato: Sì, l'utente può cambiare piano

  • Da SubscriptionManagementView β†’ Modifica Piano β†’ PlanSelectionView
  • Pulsante dinamico: "Aumenta Licenze" / "Riduci Licenze" / "Piano Attuale"
  • Protezione downgrade: Non puoi ridurre a meno dispositivi di quanti ne hai attivi

Gestione Cancellazione​

Implementato: Link diretto all'App Store

  • Pulsante "Disdici Abbonamento" apre https://apps.apple.com/account/subscriptions
  • Disclaimer: "Per aumentare o ridurre le licenze, usa 'Modifica Piano'. Non serve disdire l'abbonamento."

Free Trial​

Non implementato - Decisione futura

Cross-Platform​

Non implementato - Single provider policy (se compri su iOS, vale solo iOS)


πŸ“– Documentazione Correlata​