Paywall Screen
PaywallScreen — where users subscribe. Renders RevenueCat's prebuilt Compose paywall,
so the design, copy, prices, and offerings live in the RevenueCat dashboard (no UI code to
maintain). Hard or soft.
/docs/screens/paywall-light.png/docs/screens/paywall-dark.pngfeature/paywall/PaywallScreen.kt
How it's wired
KitNavHost shows the paywall after auth when the user isn't subscribed. Configure with:
/kit-setup-paywall// KitConfig.kt — set for you
const val PAYWALL_ENABLED = true
val PAYWALL_MODE = PaywallMode.HARD // SOFT (skippable) · HARD (blocking)
const val ENTITLEMENT_ID = "premium"
| Mode | Behaviour |
|---|---|
| SOFT | Shows a dismiss (✕) — user can skip into the app |
| HARD | Blocking — Home only after subscribing or restoring |
Subscribers (anyone holding the premium entitlement) skip the paywall automatically on next
launch — PurchaseManager.isPremium drives the nav resolver.
What's in the code (and what isn't)
PaywallScreen.kt is tiny on purpose — it just hosts RevenueCat's Paywall composable and
forwards events:
- The design, copy, prices, and offerings are NOT in the app. You build them in the RevenueCat dashboard (Project → Paywalls); the app downloads and renders whatever you publish. Change the paywall there and the app picks it up — no rebuild.
- A
PaywallListenerforwards purchase and restore completions to navigation (the built-in paywall already shows the Restore button + price options). - During development, before you've published an offering, the composable shows RevenueCat's own empty/offering state on device — that's expected, not a bug.
Because the whole paywall UI is RevenueCat's, the kit deliberately does not ship a custom pricing screen. (
KitPricingCard/KitFeatureRowexist for other upsell UIs you might build — they are not the paywall.)
Turning it on + going live
/kit-setup-paywallThis sets the config above, pastes your API key, and uncomments the
com.android.vending.BILLING permission in the manifest (a free app keeps it commented).
Real purchases need a few dashboard-side pieces — products, an offering, and the RevenueCat↔Play link — plus some lead time (~36 h for the service-account link, and a build on an internal testing track). The paywall renders before all that is done; it just can't complete a real purchase yet.
→ Full setup, billing, testing + troubleshooting: Paywall & Subscriptions.
For a free app, /kit-start-setup sets PAYWALL_ENABLED = false and the screen never
appears. The paywall talks to PurchaseManager — see Backend.