Install the SDK using your preferred package manager:
Copy
Ask AI
npx expo install expo-helium
We support Expo 49+ but recommend using Helium with Expo 53 and up. If you’re on an older version and having issues, ping us - we’ve got experience with all kinds of versioning, upgrade, and custom build plugin work.
To use your own purchase logic, pass in a custom purchase config to initialize:
Copy
Ask AI
import { createCustomPurchaseConfig } from 'expo-helium';// In your initialize call:purchaseConfig: createCustomPurchaseConfig({ // NOTE - on version 3.1.0+ makePurchase is deprecated in favor of // makePurchaseIOS and makePurchaseAndroid makePurchase: async (productId) => { // Your purchase logic here // Return a HeliumTransactionStatus return { status: 'purchased' }; }, restorePurchases: async () => { // Your restore logic here return true; }}),
You can pass in a custom user ID and custom user traits if desired to initialize:
Copy
Ask AI
// (Optional) Custom user id, e.g. your amplitude analytics user id.customUserId: '<your-custom-user-id>',// (Optional) Custom user traitscustomUserTraits: { "example_trait": "example_value",},
This will be called when paywall fails to show due to an unsuccessful paywall download or if an invalid trigger is provided. (See Fallbacks section for more details.)
(Optional) If true, the paywall will not show if the user already has entitlements for any product in the paywall. See the Entitlements section of this guide for more details.
Copy
Ask AI
import { presentUpsell } from 'expo-helium';function YourComponent() { const handlePremiumPress = () => { presentUpsell({ triggerName: 'premium_feature_press', onFallback: () => { // Implement logic to open a default paywall or display error dialog console.log('[Helium] onFallback called!'); } }); }; return ( <Button title="Try Premium" onPress={handlePremiumPress} /> );}
You can pass in paywall event handlers to listen for specific paywall events. (See the next section Helium Events for a way to handle global events).
Copy
Ask AI
eventHandlers: { onOpen: (event) => { console.log(`${event.type}`) }, onClose: (event) => { console.log(`${event.type}`) }, onPurchaseSucceeded: (event) => { console.log(`${event.type}`) }, onDismissed: (event) => { console.log(`${event.type}`) }, onOpenFailed: (event) => { console.log(`${event.type}`) }, onCustomPaywallAction: (event) => { console.log(`${event.type}`) }, onAnyEvent: (event) => { // A handler for all paywall-related events. // Note that if you have other handlers (i.e. onOpen) set up, // both that handler AND this one will fire during paywall open. },},
You should now be able to see Helium paywalls in your app! Well done! 🎉
Use these methods to check current user subscription status.
Copy
Ask AI
/** * Checks if the user has any active subscription (including non-renewable) */export const hasAnyActiveSubscription = async (): Promise<boolean>;/** * Checks if the user has any entitlement */export const hasAnyEntitlement = async (): Promise<boolean>;/** * Checks if the user has an active entitlement for any product attached to the paywall that will show for provided trigger. * @param trigger The trigger name to check entitlement for * @returns Promise resolving to true if entitled, false if not, or undefined if not known (i.e. the paywall is not downloaded yet) */export const hasEntitlementForPaywall = async (trigger: string): Promise<boolean | undefined>;
There are currently two ways you can handle a “fallback” situation in the rare case that a paywall fails to download or an invalid trigger is provided. You can also do both. Better to be prepared!
If a paywall has not completed downloading when you attempt to present it, a loading state can show.By default, Helium will show this loading state as needed (a shimmer view for up to 7 seconds). You can configure, turn off, or set trigger-specific loading budgets.If the budget expires before the paywall is ready, a fallback paywall will show if available otherwise the loading state will hide and onFallback will be called.
To verify that the Helium pod is correctly installed in your project, run:
Copy
Ask AI
grep -E "Helium" ios/Podfile.lock > /dev/null && echo "✅ Helium found in ios/Podfile.lock" || echo "❌ Helium not found in ios/Podfile.lock" && grep -E "HeliumPaywallSdk" ios/Podfile.lock > /dev/null && echo "✅ HeliumPaywallSdk found in ios/Podfile.lock" || echo "❌ HeliumPaywallSdk not found in ios/Podfile.lock"
If not found, try these commands:
Copy
Ask AI
# regenerate the ios (and android) directoriesnpx expo prebuild --clean# run a development buildnpx expo run:ios # or npx expo run:ios --device