Background
Thanks for getting started with Helium 🎈 Helium is an upsell experimentation and optimization platform for mobile apps of all sizes. We take your app’s existing paywalls and turn them into remotely editable templates that you can experiment with and optimize without waiting for new app releases. Email founders@tryhelium.com for help/questions.Installation
Add the Helium SDK to your project using Gradle.Requirements
- Kotlin Version: 2.0.0 or higher
- Java Version: 8 or higher
- Minimum Android SDK: 23 or higher
- Compile Android SDK: 35 or higher
settings.gradle.kts file:
Ensure you have mavenCentral() and google() in your repositories blocks.
dependencyResolutionManagement block, ensure google() and mavenCentral() are present in your pluginManagement { repositories { ... } } block.
2. Add the dependencies to your module-level build.gradle.kts file (e.g., app/build.gradle.kts):
- Core (Android View System)
- Jetpack Compose UI
- RevenueCat
Initialize Helium
You need to initialize Helium before you can present a paywall. The best place to do this is in yourMainActivity’s onCreate() method. When initializing, you must specify the environment, which can be HeliumEnvironment.SANDBOX for development and testing, or HeliumEnvironment.PRODUCTION for your live app. Note that for debug builds, the SDK will automatically force the sandbox environment.
Observing Paywall Configuration Download Status
The Helium SDK provides adownloadStatus flow that you can observe to get updates on the status of the paywall configuration download. This is useful for showing loading indicators or handling download failures.
The downloadStatus is a Kotlin Flow that emits HeliumConfigStatus states. The possible states are:
HeliumConfigStatus.NotYetDownloaded: The initial state before the download has started.HeliumConfigStatus.Downloading: Indicates that the paywall configuration is currently being downloaded.HeliumConfigStatus.DownloadFailure: Indicates that the paywall configuration download has failed.HeliumConfigStatus.DownloadSuccess: Indicates that the paywall configuration has been successfully downloaded.
downloadStatus flow in your Activity or Fragment:
HeliumPaywallDelegate
You can provide an implementation of theHeliumPaywallDelegate or use one of the default implementations that we have provided, such as PlayStorePaywallDelegate or RevenueCatPaywallDelegate.
- PlayStorePaywallDelegate
- RevenueCatPaywallDelegate
- Custom Delegate
Use the
PlayStorePaywallDelegate to handle purchases using Google Play Billing.Presenting Paywalls
To present a Paywall, ensure you have initialized the library. The SDK provides UI components that handle the underlyingPaywallWebViewManager.
The first step to presenting a paywall is to create an Intent using the createPaywallIntent helper function. This function configures and returns an Intent that can be used to launch the HeliumPaywallActivity.
Here are the available options for createPaywallIntent:
context: The AndroidContextrequired to create the intent. Usethisin an Activity orLocalContext.currentin a Composable.trigger: The specific paywall trigger you want to display. This is a required parameter.fullscreen: ABooleanto determine if the paywall should be displayed in fullscreen immersive mode, where the system bars (status and navigation) are hidden. This is optional and defaults tofalse.disableSystemBackNavigation: ABooleanto control the system back button behavior. Iftrue, the back button will not close the paywall. This is optional and defaults totrue.
- Jetpack Compose
- Android View System
The recommended way to present a paywall in Jetpack Compose is by launching the Alternatively, if you are using To present a paywall, you can then navigate to the Helium route with a specific trigger:
HeliumPaywallActivity using rememberLauncherForActivityResult. This approach allows you to receive a result back from the paywall, such as whether a purchase was successful.Here is an example of how to set it up in your Composable function:NavController, you can add the paywall to your navigation graph using buildHelium():PaywallEventHandlers
The Helium SDK allows you to listen for various paywall-related events. This is useful for tracking analytics, responding to user interactions, or handling the paywall lifecycle. There are two ways to listen for events: using thePaywallEventHandlers class for specific callbacks, or implementing the HeliumEventListener interface to receive all events.
Option 1: Using PaywallEventHandlers
You can create an instance ofPaywallEventHandlers and provide lambdas for the events you are interested in.
The available handlers are:
onOpen: Called when a paywall is displayed to the user.onClose: Called when a paywall is closed for any reason.onDismissed: Called when the user explicitly dismisses a paywall without purchasing.onPurchaseSucceeded: Called when a purchase completes successfully.onOpenFailed: Called when a paywall fails to open.onCustomPaywallAction: Called when a custom action is triggered from the paywall.
Helium.shared.addPaywallEventListener. You can either tie the listener to a lifecycle (recommended) or manage it manually.
Lifecycle-Aware (Recommended)
Pass a LifecycleOwner (like an Activity or Fragment) to have the listener automatically removed when the lifecycle is destroyed.
LifecycleOwner, you are responsible for removing the listener to prevent memory leaks.
Option 2: Implementing HeliumEventListener
For a more centralized approach, your class can implement theHeliumEventListener interface and handle all events in a single onHeliumEvent method.
Event Timing and Guidelines
-
Event Timing:
onDismissedis triggered only when a user manually dismisses a paywall (e.g., by tapping an ‘X’ button).onCloseis triggered any time the paywall is removed from the screen. This includes both when it’s manually dismissed and when a successful purchase closes the paywall.onPurchaseSucceededis triggered as soon as the purchase is confirmed by the billing system.
-
Usage Guidelines:
- Use
onDismissedfor post-paywall navigation when the user’s entitlement has not changed. - Use
onPurchaseSucceededto trigger your post-purchase flow, like showing a confirmation or premium onboarding. - Use
onClosefor general cleanup logic that should run regardless of how the paywall was closed.
- Use
Fallbacks and Loading Budgets
If a paywall has not completed downloading when you attempt to present it, a loading state can be displayed. By default, Helium will show this loading state (a shimmer view) for up to 2 seconds (2000ms). You can configure this behavior, turn it off, or set trigger-specific loading budgets using the HeliumFallbackConfig object during initialization.
If the loading budget expires before the paywall is ready, a fallback paywall will be shown if one is provided. Otherwise, the loading state will hide, and a PaywallOpenFailed event will be dispatched.
There are three options for fallbacks in the Android SDK:
- Fallback bundles: A pre-packaged paywall bundle stored in your app’s
assetsdirectory. - Default fallback view: A custom Android
Viewto be used for all triggers. - Fallback view per trigger: A map of trigger names to specific Android
Views.
HeliumFallbackConfig object passed into Helium.initialize().
Here are some examples:
1. Providing a fallback bundle:
Place your fallback JSON file in the src/main/assets directory of your module. Then, initialize Helium with the fallbackBundleName.
View and fine-tune the.