expo-helium 3.1.2 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -1
- package/android/src/main/java/expo/modules/paywallsdk/HeliumPaywallSdkModule.kt +3 -1
- package/build/HeliumPaywallSdk.types.d.ts.map +1 -1
- package/build/HeliumPaywallSdk.types.js.map +1 -1
- package/build/revenuecat/revenuecat.d.ts +2 -0
- package/build/revenuecat/revenuecat.d.ts.map +1 -1
- package/build/revenuecat/revenuecat.js +50 -72
- package/build/revenuecat/revenuecat.js.map +1 -1
- package/package.json +1 -1
- package/src/HeliumPaywallSdk.types.ts +0 -1
- package/src/revenuecat/revenuecat.ts +59 -81
package/android/build.gradle
CHANGED
|
@@ -43,7 +43,7 @@ android {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
dependencies {
|
|
46
|
-
implementation("com.tryhelium.paywall:core:0.1.
|
|
46
|
+
implementation("com.tryhelium.paywall:core:0.1.16")
|
|
47
47
|
implementation("com.google.code.gson:gson:2.10.1")
|
|
48
48
|
implementation("com.android.billingclient:billing:8.0.0")
|
|
49
49
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
|
@@ -102,6 +102,7 @@ class HeliumPaywallSdkModule : Module() {
|
|
|
102
102
|
val apiKey = config["apiKey"] as? String ?: ""
|
|
103
103
|
val customUserId = config["customUserId"] as? String
|
|
104
104
|
val customAPIEndpoint = config["customAPIEndpoint"] as? String
|
|
105
|
+
val revenueCatAppUserId = config["revenueCatAppUserId"] as? String
|
|
105
106
|
val useDefaultDelegate = config["useDefaultDelegate"] as? Boolean ?: false
|
|
106
107
|
|
|
107
108
|
@Suppress("UNCHECKED_CAST")
|
|
@@ -163,6 +164,7 @@ class HeliumPaywallSdkModule : Module() {
|
|
|
163
164
|
customUserId = customUserId,
|
|
164
165
|
customApiEndpoint = customAPIEndpoint,
|
|
165
166
|
customUserTraits = customUserTraits,
|
|
167
|
+
revenueCatAppUserId = revenueCatAppUserId,
|
|
166
168
|
fallbackConfig = fallbackConfig,
|
|
167
169
|
environment = environment
|
|
168
170
|
)
|
|
@@ -445,7 +447,7 @@ class HeliumPaywallSdkModule : Module() {
|
|
|
445
447
|
is String -> HeliumUserTraitsArgument.StringParam(value)
|
|
446
448
|
is Int -> HeliumUserTraitsArgument.IntParam(value)
|
|
447
449
|
is Long -> HeliumUserTraitsArgument.LongParam(value)
|
|
448
|
-
is Double -> HeliumUserTraitsArgument.DoubleParam(value
|
|
450
|
+
is Double -> HeliumUserTraitsArgument.DoubleParam(value)
|
|
449
451
|
is Boolean -> HeliumUserTraitsArgument.BooleanParam(value)
|
|
450
452
|
is List<*> -> {
|
|
451
453
|
val items = value.mapNotNull { convertToHeliumUserTraitsArgument(it) }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdk.types.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdk.types.d.ts","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeliumPaywallSdk.types.js","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"AAoGA,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,SAM1C;IACC,OAAO;QACL,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,eAAe,EAAE,SAAS,CAAC,eAAe;QAC1C,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;QAClD,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC7C,CAAC;AACJ,CAAC;AAoJD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;CACrC,CAAA","sourcesContent":["import type { StyleProp, ViewStyle } from 'react-native';\n\nexport type OnLoadEventPayload = {\n url: string;\n};\n\nexport type HeliumPaywallSdkModuleEvents = {\n onHeliumPaywallEvent: (params: HeliumPaywallEvent) => void;\n onDelegateActionEvent: (params: DelegateActionEvent) => void;\n paywallEventHandlers: (params: HeliumPaywallEvent) => void;\n};\nexport type HeliumPaywallEvent = {\n type: 'paywallOpen' | 'paywallClose' | 'paywallDismissed' |\n 'paywallOpenFailed' | 'paywallSkipped' | 'paywallButtonPressed' |\n 'productSelected' | 'purchasePressed' | 'purchaseSucceeded' |\n 'purchaseCancelled' | 'purchaseFailed' | 'purchaseRestored' |\n 'purchaseRestoreFailed' | 'purchasePending' | 'initializeStart' |\n 'paywallsDownloadSuccess' | 'paywallsDownloadError' | 'paywallWebViewRendered' |\n 'customPaywallAction' | 'userAllocated';\n triggerName?: string;\n paywallName?: string;\n /**\n * @deprecated Use `paywallName` instead.\n */\n paywallTemplateName?: string;\n productId?: string;\n /**\n * @deprecated Use `productId` instead.\n */\n productKey?: string;\n buttonName?: string;\n /**\n * @deprecated Use `buttonName` instead.\n */\n ctaName?: string;\n configId?: string;\n numAttempts?: number;\n downloadTimeTakenMS?: number;\n webviewRenderTimeTakenMS?: number;\n imagesDownloadTimeTakenMS?: number;\n fontsDownloadTimeTakenMS?: number;\n bundleDownloadTimeMS?: number;\n dismissAll?: boolean;\n isSecondTry?: boolean;\n error?: string;\n /**\n * @deprecated Use `error` instead.\n */\n errorDescription?: string;\n /**\n * Unix timestamp in seconds\n */\n timestamp?: number;\n paywallUnavailableReason?: string;\n customPaywallActionName?: string;\n customPaywallActionParams?: Record<string, any>;\n};\nexport type DelegateActionEvent = {\n type: 'purchase' | 'restore';\n productId?: string;\n /** Android-specific: Base plan ID for subscriptions */\n basePlanId?: string;\n /** Android-specific: Offer ID for promotional offers */\n offerId?: string;\n};\n\nexport type HeliumPaywallSdkViewProps = {\n url: string;\n onLoad: (event: { nativeEvent: OnLoadEventPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type HeliumTransactionStatus = 'purchased' | 'failed' | 'cancelled' | 'pending' | 'restored';\nexport type HeliumPurchaseResult = {\n status: HeliumTransactionStatus;\n error?: string; // Optional error message\n};\nexport type HeliumDownloadStatus = 'downloadSuccess' | 'downloadFailure' | 'inProgress' | 'notDownloadedYet';\nexport type HeliumLightDarkMode = 'light' | 'dark' | 'system';\nexport type HeliumEnvironment = 'sandbox' | 'production';\n\n// --- Purchase Configuration Types ---\n\n/** Interface for providing custom purchase handling logic. */\nexport interface HeliumPurchaseConfig {\n /**\n * @deprecated Use makePurchaseIOS / makePurchaseAndroid instead for platform-specific handling.\n * This method will continue to work for backward compatibility but doesn't provide Android subscription parameters.\n */\n makePurchase?: (productId: string) => Promise<HeliumPurchaseResult>;\n\n /** iOS-specific purchase handler. Receives a simple product ID string. */\n makePurchaseIOS?: (productId: string) => Promise<HeliumPurchaseResult>;\n\n /** Android-specific purchase handler. Receives product ID and optional subscription parameters. */\n makePurchaseAndroid?: (productId: string, basePlanId?: string, offerId?: string) => Promise<HeliumPurchaseResult>;\n\n restorePurchases: () => Promise<boolean>;\n}\n\n// Helper function for creating Custom Purchase Config\nexport function createCustomPurchaseConfig(callbacks: {\n /** @deprecated Use makePurchaseIOS or makePurchaseAndroid instead */\n makePurchase?: (productId: string) => Promise<HeliumPurchaseResult>;\n makePurchaseIOS?: (productId: string) => Promise<HeliumPurchaseResult>;\n makePurchaseAndroid?: (productId: string, basePlanId?: string, offerId?: string) => Promise<HeliumPurchaseResult>;\n restorePurchases: () => Promise<boolean>;\n}): HeliumPurchaseConfig {\n return {\n makePurchase: callbacks.makePurchase,\n makePurchaseIOS: callbacks.makePurchaseIOS,\n makePurchaseAndroid: callbacks.makePurchaseAndroid,\n restorePurchases: callbacks.restorePurchases,\n };\n}\n//wtf do we even have createCustomPurchaseConfig...\n\nexport type TriggerLoadingConfig = {\n /** Whether to show loading state for this trigger. Set to nil to use the global `useLoadingState` setting. */\n useLoadingState?: boolean;\n /** Maximum seconds to show loading for this trigger. Set to nil to use the global `loadingBudget` setting. */\n loadingBudget?: number;\n};\n\nexport type HeliumPaywallLoadingConfig = {\n /**\n * Whether to show a loading state while fetching paywall configuration.\n * When true, shows a loading view for up to `loadingBudget` seconds before falling back.\n * Default: true\n */\n useLoadingState?: boolean;\n /**\n * Maximum time (in seconds) to show the loading state before displaying fallback.\n * After this timeout, the fallback view will be shown even if the paywall is still downloading.\n * Default: 2.0 seconds\n */\n loadingBudget?: number;\n /**\n * Optional per-trigger loading configuration overrides.\n * Use this to customize loading behavior for specific triggers.\n * Keys are trigger names, values are TriggerLoadingConfig instances.\n * Example: Disable loading for \"onboarding\" trigger while keeping it for others.\n */\n perTriggerLoadingConfig?: Record<string, TriggerLoadingConfig>;\n};\n\nexport interface HeliumConfig {\n /** Your Helium API Key */\n apiKey: string;\n /**\n * Configuration for handling purchases. Can be custom functions or a pre-built handler config.\n * If not provided, Helium will handle purchases for you.\n */\n purchaseConfig?: HeliumPurchaseConfig;\n /** Callback for receiving all Helium paywall events. */\n onHeliumPaywallEvent: (event: HeliumPaywallEvent) => void; // Still mandatory\n\n // Optional configurations\n /** Fallback bundle in the rare situation that paywall is not ready to be shown. Highly recommended. See docs at https://docs.tryhelium.com/guides/fallback-bundle#react-native */\n fallbackBundle?: object;\n /** Configure loading behavior for paywalls that are mid-download. */\n paywallLoadingConfig?: HeliumPaywallLoadingConfig;\n /** Environment to use for Android. (iOS auto-detects this.)\n * If not specified, Android environment will be \"sandbox\" if app is a debug build, \"production otherwise\".\n * Recommended to pass in \"sandbox\" for QA builds that behave like a production build but are actually just for testing.\n */\n environment?: HeliumEnvironment;\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n}\n\nexport interface NativeHeliumConfig {\n apiKey: string;\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n fallbackBundleUrlString?: string;\n fallbackBundleString?: string;\n paywallLoadingConfig?: HeliumPaywallLoadingConfig;\n useDefaultDelegate?: boolean;\n environment?: string;\n}\n\nexport type PresentUpsellParams = {\n triggerName: string;\n /** Optional. This will be called when paywall fails to show due to an unsuccessful paywall download or if an invalid trigger is provided. */\n onFallback?: () => void;\n eventHandlers?: PaywallEventHandlers;\n customPaywallTraits?: Record<string, any>;\n /** Optional. If true, the paywall will not be shown if the user already has an entitlement for a product in the paywall. */\n dontShowIfAlreadyEntitled?: boolean;\n};\n\nexport interface PaywallInfo {\n paywallTemplateName: string;\n shouldShow: boolean;\n}\n\n// Event handler types for per-presentation event handling\nexport interface PaywallEventHandlers {\n onOpen?: (event: PaywallOpenEvent) => void;\n onClose?: (event: PaywallCloseEvent) => void;\n onDismissed?: (event: PaywallDismissedEvent) => void;\n onPurchaseSucceeded?: (event: PurchaseSucceededEvent) => void;\n onOpenFailed?: (event: PaywallOpenFailedEvent) => void;\n onCustomPaywallAction?: (event: CustomPaywallActionEvent) => void;\n /** A handler that will fire for any paywall-related event. */\n onAnyEvent?: (event: HeliumPaywallEvent) => void;\n}\n\n// Typed event interfaces\nexport interface PaywallOpenEvent {\n type: 'paywallOpen';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n viewType?: 'presented' | 'embedded' | 'triggered';\n}\n\nexport interface PaywallCloseEvent {\n type: 'paywallClose';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PaywallDismissedEvent {\n type: 'paywallDismissed';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PurchaseSucceededEvent {\n type: 'purchaseSucceeded';\n productId: string;\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PaywallOpenFailedEvent {\n type: 'paywallOpenFailed';\n triggerName: string;\n paywallName: string;\n error: string;\n paywallUnavailableReason?: string;\n isSecondTry: boolean;\n}\n\nexport interface CustomPaywallActionEvent {\n type: 'customPaywallAction';\n triggerName: string;\n paywallName: string;\n actionName: string;\n params: Record<string, any>;\n isSecondTry: boolean;\n}\n\nexport const HELIUM_CTA_NAMES = {\n SCHEDULE_CALL: 'schedule_call',\n SUBSCRIBE_BUTTON: 'subscribe_button',\n}\n"]}
|
|
1
|
+
{"version":3,"file":"HeliumPaywallSdk.types.js","sourceRoot":"","sources":["../src/HeliumPaywallSdk.types.ts"],"names":[],"mappings":"AAoGA,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,SAM1C;IACC,OAAO;QACL,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,eAAe,EAAE,SAAS,CAAC,eAAe;QAC1C,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;QAClD,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC7C,CAAC;AACJ,CAAC;AAmJD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;CACrC,CAAA","sourcesContent":["import type { StyleProp, ViewStyle } from 'react-native';\n\nexport type OnLoadEventPayload = {\n url: string;\n};\n\nexport type HeliumPaywallSdkModuleEvents = {\n onHeliumPaywallEvent: (params: HeliumPaywallEvent) => void;\n onDelegateActionEvent: (params: DelegateActionEvent) => void;\n paywallEventHandlers: (params: HeliumPaywallEvent) => void;\n};\nexport type HeliumPaywallEvent = {\n type: 'paywallOpen' | 'paywallClose' | 'paywallDismissed' |\n 'paywallOpenFailed' | 'paywallSkipped' | 'paywallButtonPressed' |\n 'productSelected' | 'purchasePressed' | 'purchaseSucceeded' |\n 'purchaseCancelled' | 'purchaseFailed' | 'purchaseRestored' |\n 'purchaseRestoreFailed' | 'purchasePending' | 'initializeStart' |\n 'paywallsDownloadSuccess' | 'paywallsDownloadError' | 'paywallWebViewRendered' |\n 'customPaywallAction' | 'userAllocated';\n triggerName?: string;\n paywallName?: string;\n /**\n * @deprecated Use `paywallName` instead.\n */\n paywallTemplateName?: string;\n productId?: string;\n /**\n * @deprecated Use `productId` instead.\n */\n productKey?: string;\n buttonName?: string;\n /**\n * @deprecated Use `buttonName` instead.\n */\n ctaName?: string;\n configId?: string;\n numAttempts?: number;\n downloadTimeTakenMS?: number;\n webviewRenderTimeTakenMS?: number;\n imagesDownloadTimeTakenMS?: number;\n fontsDownloadTimeTakenMS?: number;\n bundleDownloadTimeMS?: number;\n dismissAll?: boolean;\n isSecondTry?: boolean;\n error?: string;\n /**\n * @deprecated Use `error` instead.\n */\n errorDescription?: string;\n /**\n * Unix timestamp in seconds\n */\n timestamp?: number;\n paywallUnavailableReason?: string;\n customPaywallActionName?: string;\n customPaywallActionParams?: Record<string, any>;\n};\nexport type DelegateActionEvent = {\n type: 'purchase' | 'restore';\n productId?: string;\n /** Android-specific: Base plan ID for subscriptions */\n basePlanId?: string;\n /** Android-specific: Offer ID for promotional offers */\n offerId?: string;\n};\n\nexport type HeliumPaywallSdkViewProps = {\n url: string;\n onLoad: (event: { nativeEvent: OnLoadEventPayload }) => void;\n style?: StyleProp<ViewStyle>;\n};\n\nexport type HeliumTransactionStatus = 'purchased' | 'failed' | 'cancelled' | 'pending' | 'restored';\nexport type HeliumPurchaseResult = {\n status: HeliumTransactionStatus;\n error?: string; // Optional error message\n};\nexport type HeliumDownloadStatus = 'downloadSuccess' | 'downloadFailure' | 'inProgress' | 'notDownloadedYet';\nexport type HeliumLightDarkMode = 'light' | 'dark' | 'system';\nexport type HeliumEnvironment = 'sandbox' | 'production';\n\n// --- Purchase Configuration Types ---\n\n/** Interface for providing custom purchase handling logic. */\nexport interface HeliumPurchaseConfig {\n /**\n * @deprecated Use makePurchaseIOS / makePurchaseAndroid instead for platform-specific handling.\n * This method will continue to work for backward compatibility but doesn't provide Android subscription parameters.\n */\n makePurchase?: (productId: string) => Promise<HeliumPurchaseResult>;\n\n /** iOS-specific purchase handler. Receives a simple product ID string. */\n makePurchaseIOS?: (productId: string) => Promise<HeliumPurchaseResult>;\n\n /** Android-specific purchase handler. Receives product ID and optional subscription parameters. */\n makePurchaseAndroid?: (productId: string, basePlanId?: string, offerId?: string) => Promise<HeliumPurchaseResult>;\n\n restorePurchases: () => Promise<boolean>;\n}\n\n// Helper function for creating Custom Purchase Config\nexport function createCustomPurchaseConfig(callbacks: {\n /** @deprecated Use makePurchaseIOS or makePurchaseAndroid instead */\n makePurchase?: (productId: string) => Promise<HeliumPurchaseResult>;\n makePurchaseIOS?: (productId: string) => Promise<HeliumPurchaseResult>;\n makePurchaseAndroid?: (productId: string, basePlanId?: string, offerId?: string) => Promise<HeliumPurchaseResult>;\n restorePurchases: () => Promise<boolean>;\n}): HeliumPurchaseConfig {\n return {\n makePurchase: callbacks.makePurchase,\n makePurchaseIOS: callbacks.makePurchaseIOS,\n makePurchaseAndroid: callbacks.makePurchaseAndroid,\n restorePurchases: callbacks.restorePurchases,\n };\n}\n\nexport type TriggerLoadingConfig = {\n /** Whether to show loading state for this trigger. Set to nil to use the global `useLoadingState` setting. */\n useLoadingState?: boolean;\n /** Maximum seconds to show loading for this trigger. Set to nil to use the global `loadingBudget` setting. */\n loadingBudget?: number;\n};\n\nexport type HeliumPaywallLoadingConfig = {\n /**\n * Whether to show a loading state while fetching paywall configuration.\n * When true, shows a loading view for up to `loadingBudget` seconds before falling back.\n * Default: true\n */\n useLoadingState?: boolean;\n /**\n * Maximum time (in seconds) to show the loading state before displaying fallback.\n * After this timeout, the fallback view will be shown even if the paywall is still downloading.\n * Default: 2.0 seconds\n */\n loadingBudget?: number;\n /**\n * Optional per-trigger loading configuration overrides.\n * Use this to customize loading behavior for specific triggers.\n * Keys are trigger names, values are TriggerLoadingConfig instances.\n * Example: Disable loading for \"onboarding\" trigger while keeping it for others.\n */\n perTriggerLoadingConfig?: Record<string, TriggerLoadingConfig>;\n};\n\nexport interface HeliumConfig {\n /** Your Helium API Key */\n apiKey: string;\n /**\n * Configuration for handling purchases. Can be custom functions or a pre-built handler config.\n * If not provided, Helium will handle purchases for you.\n */\n purchaseConfig?: HeliumPurchaseConfig;\n /** Callback for receiving all Helium paywall events. */\n onHeliumPaywallEvent: (event: HeliumPaywallEvent) => void; // Still mandatory\n\n // Optional configurations\n /** Fallback bundle in the rare situation that paywall is not ready to be shown. Highly recommended. See docs at https://docs.tryhelium.com/guides/fallback-bundle#react-native */\n fallbackBundle?: object;\n /** Configure loading behavior for paywalls that are mid-download. */\n paywallLoadingConfig?: HeliumPaywallLoadingConfig;\n /** Environment to use for Android. (iOS auto-detects this.)\n * If not specified, Android environment will be \"sandbox\" if app is a debug build, \"production otherwise\".\n * Recommended to pass in \"sandbox\" for QA builds that behave like a production build but are actually just for testing.\n */\n environment?: HeliumEnvironment;\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n}\n\nexport interface NativeHeliumConfig {\n apiKey: string;\n customUserId?: string;\n customAPIEndpoint?: string;\n customUserTraits?: Record<string, any>;\n revenueCatAppUserId?: string;\n fallbackBundleUrlString?: string;\n fallbackBundleString?: string;\n paywallLoadingConfig?: HeliumPaywallLoadingConfig;\n useDefaultDelegate?: boolean;\n environment?: string;\n}\n\nexport type PresentUpsellParams = {\n triggerName: string;\n /** Optional. This will be called when paywall fails to show due to an unsuccessful paywall download or if an invalid trigger is provided. */\n onFallback?: () => void;\n eventHandlers?: PaywallEventHandlers;\n customPaywallTraits?: Record<string, any>;\n /** Optional. If true, the paywall will not be shown if the user already has an entitlement for a product in the paywall. */\n dontShowIfAlreadyEntitled?: boolean;\n};\n\nexport interface PaywallInfo {\n paywallTemplateName: string;\n shouldShow: boolean;\n}\n\n// Event handler types for per-presentation event handling\nexport interface PaywallEventHandlers {\n onOpen?: (event: PaywallOpenEvent) => void;\n onClose?: (event: PaywallCloseEvent) => void;\n onDismissed?: (event: PaywallDismissedEvent) => void;\n onPurchaseSucceeded?: (event: PurchaseSucceededEvent) => void;\n onOpenFailed?: (event: PaywallOpenFailedEvent) => void;\n onCustomPaywallAction?: (event: CustomPaywallActionEvent) => void;\n /** A handler that will fire for any paywall-related event. */\n onAnyEvent?: (event: HeliumPaywallEvent) => void;\n}\n\n// Typed event interfaces\nexport interface PaywallOpenEvent {\n type: 'paywallOpen';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n viewType?: 'presented' | 'embedded' | 'triggered';\n}\n\nexport interface PaywallCloseEvent {\n type: 'paywallClose';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PaywallDismissedEvent {\n type: 'paywallDismissed';\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PurchaseSucceededEvent {\n type: 'purchaseSucceeded';\n productId: string;\n triggerName: string;\n paywallName: string;\n isSecondTry: boolean;\n}\n\nexport interface PaywallOpenFailedEvent {\n type: 'paywallOpenFailed';\n triggerName: string;\n paywallName: string;\n error: string;\n paywallUnavailableReason?: string;\n isSecondTry: boolean;\n}\n\nexport interface CustomPaywallActionEvent {\n type: 'customPaywallAction';\n triggerName: string;\n paywallName: string;\n actionName: string;\n params: Record<string, any>;\n isSecondTry: boolean;\n}\n\nexport const HELIUM_CTA_NAMES = {\n SCHEDULE_CALL: 'schedule_call',\n SUBSCRIBE_BUTTON: 'subscribe_button',\n}\n"]}
|
|
@@ -20,6 +20,8 @@ export declare class RevenueCatHeliumHandler {
|
|
|
20
20
|
makePurchaseAndroid(productId: string, basePlanId?: string, offerId?: string): Promise<HeliumPurchaseResult>;
|
|
21
21
|
private findAndroidSubscriptionOption;
|
|
22
22
|
private isProductActive;
|
|
23
|
+
private evaluatePurchaseResult;
|
|
24
|
+
private handlePurchasesError;
|
|
23
25
|
restorePurchases(): Promise<boolean>;
|
|
24
26
|
}
|
|
25
27
|
//# sourceMappingURL=revenuecat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revenuecat.d.ts","sourceRoot":"","sources":["../../src/revenuecat/revenuecat.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAIrF,wBAAgB,8BAA8B,CAAC,MAAM,CAAC,EAAE;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,CAOvB;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,yBAAyB,CAAwC;IACzE,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,yBAAyB,CAA6C;gBAElE,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;YAiBtE,wBAAwB;YA4BxB,wBAAwB;IAQhC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"revenuecat.d.ts","sourceRoot":"","sources":["../../src/revenuecat/revenuecat.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAIrF,wBAAgB,8BAA8B,CAAC,MAAM,CAAC,EAAE;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,CAOvB;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,yBAAyB,CAAwC;IACzE,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,yBAAyB,CAA6C;gBAElE,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;YAiBtE,wBAAwB;YA4BxB,wBAAwB;IAQhC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAwCjE,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;YAsDpG,6BAA6B;IAwC3C,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,oBAAoB;IAetB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;CAQ3C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Purchases, { PURCHASES_ERROR_CODE } from 'react-native-purchases';
|
|
1
|
+
import Purchases, { PRODUCT_CATEGORY, PURCHASES_ERROR_CODE } from 'react-native-purchases';
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
3
|
import { setRevenueCatAppUserId } from "../index";
|
|
4
4
|
// Rename the factory function
|
|
@@ -102,31 +102,10 @@ export class RevenueCatHeliumHandler {
|
|
|
102
102
|
else {
|
|
103
103
|
return { status: 'failed', error: `RevenueCat Product/Package not found for ID: ${productId}` };
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
if (isActive) {
|
|
107
|
-
return { status: 'purchased' };
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// This case might occur if the purchase succeeded but the entitlement wasn't immediately active
|
|
111
|
-
// or if a different product became active.
|
|
112
|
-
// Consider if polling/listening might be needed here too, similar to pending.
|
|
113
|
-
// For now, returning failed as the specific product isn't confirmed active.
|
|
114
|
-
return {
|
|
115
|
-
status: 'failed',
|
|
116
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
117
|
-
};
|
|
118
|
-
}
|
|
105
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
119
106
|
}
|
|
120
107
|
catch (error) {
|
|
121
|
-
|
|
122
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
123
|
-
return { status: 'pending' };
|
|
124
|
-
}
|
|
125
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
126
|
-
return { status: 'cancelled' };
|
|
127
|
-
}
|
|
128
|
-
// Handle other errors
|
|
129
|
-
return { status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.' };
|
|
108
|
+
return this.handlePurchasesError(error);
|
|
130
109
|
}
|
|
131
110
|
}
|
|
132
111
|
// Android-specific purchase logic (completely separated from iOS)
|
|
@@ -139,63 +118,41 @@ export class RevenueCatHeliumHandler {
|
|
|
139
118
|
if (subscriptionOption) {
|
|
140
119
|
try {
|
|
141
120
|
const customerInfo = (await Purchases.purchaseSubscriptionOption(subscriptionOption)).customerInfo;
|
|
142
|
-
|
|
143
|
-
if (isActive) {
|
|
144
|
-
return { status: 'purchased' };
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
return {
|
|
148
|
-
status: 'failed',
|
|
149
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
150
|
-
};
|
|
151
|
-
}
|
|
121
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
152
122
|
}
|
|
153
123
|
catch (error) {
|
|
154
|
-
|
|
155
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
156
|
-
return { status: 'pending' };
|
|
157
|
-
}
|
|
158
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
159
|
-
return { status: 'cancelled' };
|
|
160
|
-
}
|
|
161
|
-
return { status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.' };
|
|
124
|
+
return this.handlePurchasesError(error);
|
|
162
125
|
}
|
|
163
126
|
}
|
|
164
127
|
}
|
|
165
128
|
// Handle one-time purchase or subscription that didn't have matching base plan / offer
|
|
166
129
|
let rcProduct;
|
|
167
130
|
try {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
131
|
+
// Try non-subscription (NON_SUBSCRIPTION) product first; most likely not a sub at this point
|
|
132
|
+
let products = await Purchases.getProducts([productId], PRODUCT_CATEGORY.NON_SUBSCRIPTION);
|
|
133
|
+
if (products.length > 0) {
|
|
134
|
+
rcProduct = products[0];
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// Then try subscription product (let RC pick option since we couldn't find a match)
|
|
138
|
+
products = await Purchases.getProducts([productId]);
|
|
139
|
+
if (products.length > 0) {
|
|
140
|
+
rcProduct = products[0];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!rcProduct) {
|
|
144
|
+
return { status: 'failed', error: `[RC] Android product not found: ${productId}` };
|
|
171
145
|
}
|
|
172
|
-
rcProduct = products[0];
|
|
173
146
|
}
|
|
174
147
|
catch {
|
|
175
|
-
return { status: 'failed', error: `Failed to retrieve Android product: ${productId}` };
|
|
148
|
+
return { status: 'failed', error: `[RC] Failed to retrieve Android product: ${productId}` };
|
|
176
149
|
}
|
|
177
150
|
try {
|
|
178
151
|
const customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;
|
|
179
|
-
|
|
180
|
-
if (isActive) {
|
|
181
|
-
return { status: 'purchased' };
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
return {
|
|
185
|
-
status: 'failed',
|
|
186
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
187
|
-
};
|
|
188
|
-
}
|
|
152
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
189
153
|
}
|
|
190
154
|
catch (error) {
|
|
191
|
-
|
|
192
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
193
|
-
return { status: 'pending' };
|
|
194
|
-
}
|
|
195
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
196
|
-
return { status: 'cancelled' };
|
|
197
|
-
}
|
|
198
|
-
return { status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.' };
|
|
155
|
+
return this.handlePurchasesError(error);
|
|
199
156
|
}
|
|
200
157
|
}
|
|
201
158
|
// Android helper: Find subscription option
|
|
@@ -205,18 +162,21 @@ export class RevenueCatHeliumHandler {
|
|
|
205
162
|
if (products.length === 0) {
|
|
206
163
|
return undefined;
|
|
207
164
|
}
|
|
208
|
-
|
|
209
|
-
|
|
165
|
+
// RC will return multiple products if multiple base plans per subscription
|
|
166
|
+
// Collect all subscription options from all products into a flat list
|
|
167
|
+
const allSubscriptionOptions = products.flatMap(product => product.subscriptionOptions ?? []);
|
|
168
|
+
if (allSubscriptionOptions.length === 0) {
|
|
210
169
|
return undefined;
|
|
211
170
|
}
|
|
212
171
|
let subscriptionOption;
|
|
213
172
|
if (offerId && basePlanId) {
|
|
214
173
|
// Look for specific offer: "basePlanId:offerId"
|
|
215
174
|
const targetId = `${basePlanId}:${offerId}`;
|
|
216
|
-
subscriptionOption =
|
|
175
|
+
subscriptionOption = allSubscriptionOptions.find(opt => opt.id === targetId);
|
|
217
176
|
}
|
|
218
|
-
|
|
219
|
-
|
|
177
|
+
if (!subscriptionOption && basePlanId) {
|
|
178
|
+
// Otherwise the RC option id will simply be base plan id
|
|
179
|
+
subscriptionOption = allSubscriptionOptions.find(opt => opt.id === basePlanId);
|
|
220
180
|
}
|
|
221
181
|
return subscriptionOption;
|
|
222
182
|
}
|
|
@@ -230,11 +190,29 @@ export class RevenueCatHeliumHandler {
|
|
|
230
190
|
|| customerInfo.activeSubscriptions.includes(productId)
|
|
231
191
|
|| customerInfo.allPurchasedProductIdentifiers.includes(productId);
|
|
232
192
|
}
|
|
193
|
+
// Helper function to process purchase result
|
|
194
|
+
evaluatePurchaseResult(customerInfo, productId) {
|
|
195
|
+
if (!this.isProductActive(customerInfo, productId)) {
|
|
196
|
+
console.log('Purchase succeeded but product not immediately active in customerInfo:', productId);
|
|
197
|
+
}
|
|
198
|
+
return { status: 'purchased' };
|
|
199
|
+
}
|
|
200
|
+
// Helper function to handle RevenueCat purchase errors
|
|
201
|
+
handlePurchasesError(error) {
|
|
202
|
+
const purchasesError = error;
|
|
203
|
+
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
204
|
+
return { status: 'pending' };
|
|
205
|
+
}
|
|
206
|
+
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
207
|
+
return { status: 'cancelled' };
|
|
208
|
+
}
|
|
209
|
+
const errorDesc = purchasesError?.message || 'purchase failed.';
|
|
210
|
+
return { status: 'failed', error: `[RC] ${errorDesc} code: ${purchasesError?.code}` };
|
|
211
|
+
}
|
|
233
212
|
async restorePurchases() {
|
|
234
213
|
try {
|
|
235
214
|
const customerInfo = await Purchases.restorePurchases();
|
|
236
|
-
|
|
237
|
-
return isActive;
|
|
215
|
+
return Object.keys(customerInfo.entitlements.active).length > 0;
|
|
238
216
|
}
|
|
239
217
|
catch (error) {
|
|
240
218
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revenuecat.js","sourceRoot":"","sources":["../../src/revenuecat/revenuecat.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CustomerInfo,\n PurchasesEntitlementInfo,\n PurchasesError,\n PurchasesPackage,\n SubscriptionOption\n} from 'react-native-purchases';\nimport Purchases, {PURCHASES_ERROR_CODE, PurchasesStoreProduct} from 'react-native-purchases';\nimport {Platform} from 'react-native';\nimport {HeliumPurchaseConfig, HeliumPurchaseResult} from \"../HeliumPaywallSdk.types\";\nimport {setRevenueCatAppUserId} from \"../index\";\n\n// Rename the factory function\nexport function createRevenueCatPurchaseConfig(config?: {\n apiKey?: string;\n apiKeyIOS?: string;\n apiKeyAndroid?: string;\n}): HeliumPurchaseConfig {\n const rcHandler = new RevenueCatHeliumHandler(config);\n return {\n makePurchaseIOS: rcHandler.makePurchaseIOS.bind(rcHandler),\n makePurchaseAndroid: rcHandler.makePurchaseAndroid.bind(rcHandler),\n restorePurchases: rcHandler.restorePurchases.bind(rcHandler),\n };\n}\n\nexport class RevenueCatHeliumHandler {\n private productIdToPackageMapping: Record<string, PurchasesPackage> = {};\n private isMappingInitialized: boolean = false;\n private initializationPromise: Promise<void> | null = null;\n\n private rcProductToPackageMapping: Record<string, PurchasesStoreProduct> = {};\n\n constructor(config?: { apiKey?: string; apiKeyIOS?: string; apiKeyAndroid?: string }) {\n // Determine which API key to use based on platform\n let effectiveApiKey: string | undefined;\n if (Platform.OS === 'ios' && config?.apiKeyIOS) {\n effectiveApiKey = config.apiKeyIOS;\n } else if (Platform.OS === 'android' && config?.apiKeyAndroid) {\n effectiveApiKey = config.apiKeyAndroid;\n } else {\n effectiveApiKey = config?.apiKey;\n }\n\n if (effectiveApiKey) {\n Purchases.configure({apiKey: effectiveApiKey});\n }\n void this.initializePackageMapping();\n }\n\n private async initializePackageMapping(): Promise<void> {\n if (this.initializationPromise) {\n return this.initializationPromise;\n }\n this.initializationPromise = (async () => {\n try {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n const offerings = await Purchases.getOfferings();\n const allOfferings = offerings.all;\n for (const offering of Object.values(allOfferings)) {\n offering.availablePackages.forEach((pkg: PurchasesPackage) => {\n if (pkg.product?.identifier) {\n this.productIdToPackageMapping[pkg.product.identifier] = pkg;\n }\n });\n }\n this.isMappingInitialized = true;\n } catch (error) {\n this.isMappingInitialized = false;\n } finally {\n this.initializationPromise = null;\n }\n })();\n return this.initializationPromise;\n }\n\n private async ensureMappingInitialized(): Promise<void> {\n if (!this.isMappingInitialized && !this.initializationPromise) {\n await this.initializePackageMapping();\n } else if (this.initializationPromise) {\n await this.initializationPromise;\n }\n }\n\n async makePurchaseIOS(productId: string): Promise<HeliumPurchaseResult> {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n await this.ensureMappingInitialized();\n const pkg: PurchasesPackage | undefined = this.productIdToPackageMapping[productId];\n let rcProduct: PurchasesStoreProduct | undefined;\n if (!pkg) {\n // Use cached if available\n rcProduct = this.rcProductToPackageMapping[productId];\n if (!rcProduct) {\n // Try to retrieve now\n try {\n const rcProducts = await Purchases.getProducts([productId]);\n rcProduct = rcProducts.length > 0 ? rcProducts[0] : undefined;\n } catch {\n // 'failed' status will be returned\n }\n if (rcProduct) {\n this.rcProductToPackageMapping[productId] = rcProduct;\n }\n }\n }\n\n try {\n let customerInfo: CustomerInfo;\n if (pkg) {\n customerInfo = (await Purchases.purchasePackage(pkg)).customerInfo;\n } else if (rcProduct) {\n customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;\n } else {\n return {status: 'failed', error: `RevenueCat Product/Package not found for ID: ${productId}`};\n }\n const isActive = this.isProductActive(customerInfo, productId);\n if (isActive) {\n return {status: 'purchased'};\n } else {\n // This case might occur if the purchase succeeded but the entitlement wasn't immediately active\n // or if a different product became active.\n // Consider if polling/listening might be needed here too, similar to pending.\n // For now, returning failed as the specific product isn't confirmed active.\n return {\n status: 'failed',\n error: 'Purchase possibly complete but entitlement/subscription not active for this product.'\n };\n }\n } catch (error) {\n const purchasesError = error as PurchasesError;\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {\n return {status: 'pending'};\n }\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {\n return {status: 'cancelled'};\n }\n\n // Handle other errors\n return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};\n }\n }\n\n // Android-specific purchase logic (completely separated from iOS)\n async makePurchaseAndroid(productId: string, basePlanId?: string, offerId?: string): Promise<HeliumPurchaseResult> {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n // Handle subscription with base plan or offer\n if (basePlanId || offerId) {\n const subscriptionOption = await this.findAndroidSubscriptionOption(\n productId,\n basePlanId,\n offerId\n );\n\n if (subscriptionOption) {\n try {\n const customerInfo = (await Purchases.purchaseSubscriptionOption(subscriptionOption)).customerInfo;\n\n const isActive = this.isProductActive(customerInfo, productId);\n if (isActive) {\n return {status: 'purchased'};\n } else {\n return {\n status: 'failed',\n error: 'Purchase possibly complete but entitlement/subscription not active for this product.'\n };\n }\n } catch (error) {\n const purchasesError = error as PurchasesError;\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {\n return {status: 'pending'};\n }\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {\n return {status: 'cancelled'};\n }\n\n return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};\n }\n }\n }\n\n // Handle one-time purchase or subscription that didn't have matching base plan / offer\n let rcProduct: PurchasesStoreProduct;\n try {\n const products = await Purchases.getProducts([productId]);\n if (products.length === 0) {\n return {status: 'failed', error: `Android product not found: ${productId}`};\n }\n rcProduct = products[0];\n } catch {\n return {status: 'failed', error: `Failed to retrieve Android product: ${productId}`};\n }\n\n try {\n const customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;\n\n const isActive = this.isProductActive(customerInfo, productId);\n if (isActive) {\n return {status: 'purchased'};\n } else {\n return {\n status: 'failed',\n error: 'Purchase possibly complete but entitlement/subscription not active for this product.'\n };\n }\n } catch (error) {\n const purchasesError = error as PurchasesError;\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {\n return {status: 'pending'};\n }\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {\n return {status: 'cancelled'};\n }\n\n return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};\n }\n }\n\n // Android helper: Find subscription option\n private async findAndroidSubscriptionOption(\n productId: string,\n basePlanId?: string,\n offerId?: string\n ): Promise<SubscriptionOption | undefined> {\n try {\n const products = await Purchases.getProducts([productId]);\n if (products.length === 0) {\n return undefined;\n }\n\n const product = products[0];\n\n if (!product.subscriptionOptions || product.subscriptionOptions.length === 0) {\n return undefined;\n }\n\n let subscriptionOption: SubscriptionOption | undefined;\n\n if (offerId && basePlanId) {\n // Look for specific offer: \"basePlanId:offerId\"\n const targetId = `${basePlanId}:${offerId}`;\n subscriptionOption = product.subscriptionOptions.find(opt => opt.id === targetId);\n } else if (basePlanId) {\n subscriptionOption = product.subscriptionOptions.find(\n opt => opt.id === basePlanId && opt.isBasePlan\n );\n }\n\n return subscriptionOption;\n } catch (error) {\n return undefined;\n }\n }\n\n // Helper function to check if a product is active in CustomerInfo\n private isProductActive(customerInfo: CustomerInfo, productId: string): boolean {\n return Object.values(customerInfo.entitlements.active).some((entitlement: PurchasesEntitlementInfo) => entitlement.productIdentifier === productId)\n || customerInfo.activeSubscriptions.includes(productId)\n || customerInfo.allPurchasedProductIdentifiers.includes(productId);\n }\n\n async restorePurchases(): Promise<boolean> {\n try {\n const customerInfo = await Purchases.restorePurchases();\n const isActive = Object.keys(customerInfo.entitlements.active).length > 0;\n return isActive;\n } catch (error) {\n return false;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"revenuecat.js","sourceRoot":"","sources":["../../src/revenuecat/revenuecat.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CustomerInfo,\n PurchasesEntitlementInfo,\n PurchasesError,\n PurchasesPackage,\n SubscriptionOption\n} from 'react-native-purchases';\nimport Purchases, {PRODUCT_CATEGORY, PURCHASES_ERROR_CODE, PurchasesStoreProduct} from 'react-native-purchases';\nimport {Platform} from 'react-native';\nimport {HeliumPurchaseConfig, HeliumPurchaseResult} from \"../HeliumPaywallSdk.types\";\nimport {setRevenueCatAppUserId} from \"../index\";\n\n// Rename the factory function\nexport function createRevenueCatPurchaseConfig(config?: {\n apiKey?: string;\n apiKeyIOS?: string;\n apiKeyAndroid?: string;\n}): HeliumPurchaseConfig {\n const rcHandler = new RevenueCatHeliumHandler(config);\n return {\n makePurchaseIOS: rcHandler.makePurchaseIOS.bind(rcHandler),\n makePurchaseAndroid: rcHandler.makePurchaseAndroid.bind(rcHandler),\n restorePurchases: rcHandler.restorePurchases.bind(rcHandler),\n };\n}\n\nexport class RevenueCatHeliumHandler {\n private productIdToPackageMapping: Record<string, PurchasesPackage> = {};\n private isMappingInitialized: boolean = false;\n private initializationPromise: Promise<void> | null = null;\n\n private rcProductToPackageMapping: Record<string, PurchasesStoreProduct> = {};\n\n constructor(config?: { apiKey?: string; apiKeyIOS?: string; apiKeyAndroid?: string }) {\n // Determine which API key to use based on platform\n let effectiveApiKey: string | undefined;\n if (Platform.OS === 'ios' && config?.apiKeyIOS) {\n effectiveApiKey = config.apiKeyIOS;\n } else if (Platform.OS === 'android' && config?.apiKeyAndroid) {\n effectiveApiKey = config.apiKeyAndroid;\n } else {\n effectiveApiKey = config?.apiKey;\n }\n\n if (effectiveApiKey) {\n Purchases.configure({apiKey: effectiveApiKey});\n }\n void this.initializePackageMapping();\n }\n\n private async initializePackageMapping(): Promise<void> {\n if (this.initializationPromise) {\n return this.initializationPromise;\n }\n this.initializationPromise = (async () => {\n try {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n const offerings = await Purchases.getOfferings();\n const allOfferings = offerings.all;\n for (const offering of Object.values(allOfferings)) {\n offering.availablePackages.forEach((pkg: PurchasesPackage) => {\n if (pkg.product?.identifier) {\n this.productIdToPackageMapping[pkg.product.identifier] = pkg;\n }\n });\n }\n this.isMappingInitialized = true;\n } catch (error) {\n this.isMappingInitialized = false;\n } finally {\n this.initializationPromise = null;\n }\n })();\n return this.initializationPromise;\n }\n\n private async ensureMappingInitialized(): Promise<void> {\n if (!this.isMappingInitialized && !this.initializationPromise) {\n await this.initializePackageMapping();\n } else if (this.initializationPromise) {\n await this.initializationPromise;\n }\n }\n\n async makePurchaseIOS(productId: string): Promise<HeliumPurchaseResult> {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n await this.ensureMappingInitialized();\n const pkg: PurchasesPackage | undefined = this.productIdToPackageMapping[productId];\n let rcProduct: PurchasesStoreProduct | undefined;\n if (!pkg) {\n // Use cached if available\n rcProduct = this.rcProductToPackageMapping[productId];\n if (!rcProduct) {\n // Try to retrieve now\n try {\n const rcProducts = await Purchases.getProducts([productId]);\n rcProduct = rcProducts.length > 0 ? rcProducts[0] : undefined;\n } catch {\n // 'failed' status will be returned\n }\n if (rcProduct) {\n this.rcProductToPackageMapping[productId] = rcProduct;\n }\n }\n }\n\n try {\n let customerInfo: CustomerInfo;\n if (pkg) {\n customerInfo = (await Purchases.purchasePackage(pkg)).customerInfo;\n } else if (rcProduct) {\n customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;\n } else {\n return {status: 'failed', error: `RevenueCat Product/Package not found for ID: ${productId}`};\n }\n return this.evaluatePurchaseResult(customerInfo, productId);\n } catch (error) {\n return this.handlePurchasesError(error);\n }\n }\n\n // Android-specific purchase logic (completely separated from iOS)\n async makePurchaseAndroid(productId: string, basePlanId?: string, offerId?: string): Promise<HeliumPurchaseResult> {\n // Keep this value as up-to-date as possible\n setRevenueCatAppUserId(await Purchases.getAppUserID());\n\n // Handle subscription with base plan or offer\n if (basePlanId || offerId) {\n const subscriptionOption = await this.findAndroidSubscriptionOption(\n productId,\n basePlanId,\n offerId\n );\n\n if (subscriptionOption) {\n try {\n const customerInfo = (await Purchases.purchaseSubscriptionOption(subscriptionOption)).customerInfo;\n\n return this.evaluatePurchaseResult(customerInfo, productId);\n } catch (error) {\n return this.handlePurchasesError(error);\n }\n }\n }\n\n // Handle one-time purchase or subscription that didn't have matching base plan / offer\n let rcProduct: PurchasesStoreProduct | undefined;\n try {\n // Try non-subscription (NON_SUBSCRIPTION) product first; most likely not a sub at this point\n let products = await Purchases.getProducts([productId], PRODUCT_CATEGORY.NON_SUBSCRIPTION);\n if (products.length > 0) {\n rcProduct = products[0];\n } else {\n // Then try subscription product (let RC pick option since we couldn't find a match)\n products = await Purchases.getProducts([productId]);\n if (products.length > 0) {\n rcProduct = products[0];\n }\n }\n if (!rcProduct) {\n return {status: 'failed', error: `[RC] Android product not found: ${productId}`};\n }\n } catch {\n return {status: 'failed', error: `[RC] Failed to retrieve Android product: ${productId}`};\n }\n\n try {\n const customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;\n\n return this.evaluatePurchaseResult(customerInfo, productId);\n } catch (error) {\n return this.handlePurchasesError(error);\n }\n }\n\n // Android helper: Find subscription option\n private async findAndroidSubscriptionOption(\n productId: string,\n basePlanId?: string,\n offerId?: string\n ): Promise<SubscriptionOption | undefined> {\n try {\n const products = await Purchases.getProducts([productId]);\n if (products.length === 0) {\n return undefined;\n }\n\n // RC will return multiple products if multiple base plans per subscription\n // Collect all subscription options from all products into a flat list\n const allSubscriptionOptions = products.flatMap(\n product => product.subscriptionOptions ?? []\n );\n\n if (allSubscriptionOptions.length === 0) {\n return undefined;\n }\n\n let subscriptionOption: SubscriptionOption | undefined;\n\n if (offerId && basePlanId) {\n // Look for specific offer: \"basePlanId:offerId\"\n const targetId = `${basePlanId}:${offerId}`;\n subscriptionOption = allSubscriptionOptions.find(opt => opt.id === targetId);\n }\n if (!subscriptionOption && basePlanId) {\n // Otherwise the RC option id will simply be base plan id\n subscriptionOption = allSubscriptionOptions.find(opt => opt.id === basePlanId);\n }\n\n return subscriptionOption;\n } catch (error) {\n return undefined;\n }\n }\n\n // Helper function to check if a product is active in CustomerInfo\n private isProductActive(customerInfo: CustomerInfo, productId: string): boolean {\n return Object.values(customerInfo.entitlements.active).some((entitlement: PurchasesEntitlementInfo) => entitlement.productIdentifier === productId)\n || customerInfo.activeSubscriptions.includes(productId)\n || customerInfo.allPurchasedProductIdentifiers.includes(productId);\n }\n\n // Helper function to process purchase result\n private evaluatePurchaseResult(customerInfo: CustomerInfo, productId: string): HeliumPurchaseResult {\n if (!this.isProductActive(customerInfo, productId)) {\n console.log('Purchase succeeded but product not immediately active in customerInfo:', productId);\n }\n\n return {status: 'purchased'};\n }\n\n // Helper function to handle RevenueCat purchase errors\n private handlePurchasesError(error: unknown): HeliumPurchaseResult {\n const purchasesError = error as PurchasesError;\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {\n return {status: 'pending'};\n }\n\n if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {\n return {status: 'cancelled'};\n }\n\n const errorDesc = purchasesError?.message || 'purchase failed.';\n return {status: 'failed', error: `[RC] ${errorDesc} code: ${purchasesError?.code}`};\n }\n\n async restorePurchases(): Promise<boolean> {\n try {\n const customerInfo = await Purchases.restorePurchases();\n return Object.keys(customerInfo.entitlements.active).length > 0;\n } catch (error) {\n return false;\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -113,7 +113,6 @@ export function createCustomPurchaseConfig(callbacks: {
|
|
|
113
113
|
restorePurchases: callbacks.restorePurchases,
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
|
-
//wtf do we even have createCustomPurchaseConfig...
|
|
117
116
|
|
|
118
117
|
export type TriggerLoadingConfig = {
|
|
119
118
|
/** Whether to show loading state for this trigger. Set to nil to use the global `useLoadingState` setting. */
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
PurchasesPackage,
|
|
6
6
|
SubscriptionOption
|
|
7
7
|
} from 'react-native-purchases';
|
|
8
|
-
import Purchases, {PURCHASES_ERROR_CODE, PurchasesStoreProduct} from 'react-native-purchases';
|
|
8
|
+
import Purchases, {PRODUCT_CATEGORY, PURCHASES_ERROR_CODE, PurchasesStoreProduct} from 'react-native-purchases';
|
|
9
9
|
import {Platform} from 'react-native';
|
|
10
10
|
import {HeliumPurchaseConfig, HeliumPurchaseResult} from "../HeliumPaywallSdk.types";
|
|
11
11
|
import {setRevenueCatAppUserId} from "../index";
|
|
@@ -117,32 +117,9 @@ export class RevenueCatHeliumHandler {
|
|
|
117
117
|
} else {
|
|
118
118
|
return {status: 'failed', error: `RevenueCat Product/Package not found for ID: ${productId}`};
|
|
119
119
|
}
|
|
120
|
-
|
|
121
|
-
if (isActive) {
|
|
122
|
-
return {status: 'purchased'};
|
|
123
|
-
} else {
|
|
124
|
-
// This case might occur if the purchase succeeded but the entitlement wasn't immediately active
|
|
125
|
-
// or if a different product became active.
|
|
126
|
-
// Consider if polling/listening might be needed here too, similar to pending.
|
|
127
|
-
// For now, returning failed as the specific product isn't confirmed active.
|
|
128
|
-
return {
|
|
129
|
-
status: 'failed',
|
|
130
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
131
|
-
};
|
|
132
|
-
}
|
|
120
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
133
121
|
} catch (error) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
137
|
-
return {status: 'pending'};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
141
|
-
return {status: 'cancelled'};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Handle other errors
|
|
145
|
-
return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};
|
|
122
|
+
return this.handlePurchasesError(error);
|
|
146
123
|
}
|
|
147
124
|
}
|
|
148
125
|
|
|
@@ -163,67 +140,40 @@ export class RevenueCatHeliumHandler {
|
|
|
163
140
|
try {
|
|
164
141
|
const customerInfo = (await Purchases.purchaseSubscriptionOption(subscriptionOption)).customerInfo;
|
|
165
142
|
|
|
166
|
-
|
|
167
|
-
if (isActive) {
|
|
168
|
-
return {status: 'purchased'};
|
|
169
|
-
} else {
|
|
170
|
-
return {
|
|
171
|
-
status: 'failed',
|
|
172
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
173
|
-
};
|
|
174
|
-
}
|
|
143
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
175
144
|
} catch (error) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
179
|
-
return {status: 'pending'};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
183
|
-
return {status: 'cancelled'};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};
|
|
145
|
+
return this.handlePurchasesError(error);
|
|
187
146
|
}
|
|
188
147
|
}
|
|
189
148
|
}
|
|
190
149
|
|
|
191
150
|
// Handle one-time purchase or subscription that didn't have matching base plan / offer
|
|
192
|
-
let rcProduct: PurchasesStoreProduct;
|
|
151
|
+
let rcProduct: PurchasesStoreProduct | undefined;
|
|
193
152
|
try {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
153
|
+
// Try non-subscription (NON_SUBSCRIPTION) product first; most likely not a sub at this point
|
|
154
|
+
let products = await Purchases.getProducts([productId], PRODUCT_CATEGORY.NON_SUBSCRIPTION);
|
|
155
|
+
if (products.length > 0) {
|
|
156
|
+
rcProduct = products[0];
|
|
157
|
+
} else {
|
|
158
|
+
// Then try subscription product (let RC pick option since we couldn't find a match)
|
|
159
|
+
products = await Purchases.getProducts([productId]);
|
|
160
|
+
if (products.length > 0) {
|
|
161
|
+
rcProduct = products[0];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (!rcProduct) {
|
|
165
|
+
return {status: 'failed', error: `[RC] Android product not found: ${productId}`};
|
|
197
166
|
}
|
|
198
|
-
rcProduct = products[0];
|
|
199
167
|
} catch {
|
|
200
|
-
return {status: 'failed', error: `Failed to retrieve Android product: ${productId}`};
|
|
168
|
+
return {status: 'failed', error: `[RC] Failed to retrieve Android product: ${productId}`};
|
|
201
169
|
}
|
|
202
170
|
|
|
203
171
|
try {
|
|
204
172
|
const customerInfo = (await Purchases.purchaseStoreProduct(rcProduct)).customerInfo;
|
|
205
173
|
|
|
206
|
-
|
|
207
|
-
if (isActive) {
|
|
208
|
-
return {status: 'purchased'};
|
|
209
|
-
} else {
|
|
210
|
-
return {
|
|
211
|
-
status: 'failed',
|
|
212
|
-
error: 'Purchase possibly complete but entitlement/subscription not active for this product.'
|
|
213
|
-
};
|
|
214
|
-
}
|
|
174
|
+
return this.evaluatePurchaseResult(customerInfo, productId);
|
|
215
175
|
} catch (error) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
219
|
-
return {status: 'pending'};
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
223
|
-
return {status: 'cancelled'};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return {status: 'failed', error: purchasesError?.message || 'RevenueCat purchase failed.'};
|
|
176
|
+
return this.handlePurchasesError(error);
|
|
227
177
|
}
|
|
228
178
|
}
|
|
229
179
|
|
|
@@ -239,9 +189,13 @@ export class RevenueCatHeliumHandler {
|
|
|
239
189
|
return undefined;
|
|
240
190
|
}
|
|
241
191
|
|
|
242
|
-
|
|
192
|
+
// RC will return multiple products if multiple base plans per subscription
|
|
193
|
+
// Collect all subscription options from all products into a flat list
|
|
194
|
+
const allSubscriptionOptions = products.flatMap(
|
|
195
|
+
product => product.subscriptionOptions ?? []
|
|
196
|
+
);
|
|
243
197
|
|
|
244
|
-
if (
|
|
198
|
+
if (allSubscriptionOptions.length === 0) {
|
|
245
199
|
return undefined;
|
|
246
200
|
}
|
|
247
201
|
|
|
@@ -250,11 +204,11 @@ export class RevenueCatHeliumHandler {
|
|
|
250
204
|
if (offerId && basePlanId) {
|
|
251
205
|
// Look for specific offer: "basePlanId:offerId"
|
|
252
206
|
const targetId = `${basePlanId}:${offerId}`;
|
|
253
|
-
subscriptionOption =
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
);
|
|
207
|
+
subscriptionOption = allSubscriptionOptions.find(opt => opt.id === targetId);
|
|
208
|
+
}
|
|
209
|
+
if (!subscriptionOption && basePlanId) {
|
|
210
|
+
// Otherwise the RC option id will simply be base plan id
|
|
211
|
+
subscriptionOption = allSubscriptionOptions.find(opt => opt.id === basePlanId);
|
|
258
212
|
}
|
|
259
213
|
|
|
260
214
|
return subscriptionOption;
|
|
@@ -270,11 +224,35 @@ export class RevenueCatHeliumHandler {
|
|
|
270
224
|
|| customerInfo.allPurchasedProductIdentifiers.includes(productId);
|
|
271
225
|
}
|
|
272
226
|
|
|
227
|
+
// Helper function to process purchase result
|
|
228
|
+
private evaluatePurchaseResult(customerInfo: CustomerInfo, productId: string): HeliumPurchaseResult {
|
|
229
|
+
if (!this.isProductActive(customerInfo, productId)) {
|
|
230
|
+
console.log('Purchase succeeded but product not immediately active in customerInfo:', productId);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return {status: 'purchased'};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Helper function to handle RevenueCat purchase errors
|
|
237
|
+
private handlePurchasesError(error: unknown): HeliumPurchaseResult {
|
|
238
|
+
const purchasesError = error as PurchasesError;
|
|
239
|
+
|
|
240
|
+
if (purchasesError?.code === PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
|
|
241
|
+
return {status: 'pending'};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (purchasesError?.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
|
245
|
+
return {status: 'cancelled'};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const errorDesc = purchasesError?.message || 'purchase failed.';
|
|
249
|
+
return {status: 'failed', error: `[RC] ${errorDesc} code: ${purchasesError?.code}`};
|
|
250
|
+
}
|
|
251
|
+
|
|
273
252
|
async restorePurchases(): Promise<boolean> {
|
|
274
253
|
try {
|
|
275
254
|
const customerInfo = await Purchases.restorePurchases();
|
|
276
|
-
|
|
277
|
-
return isActive;
|
|
255
|
+
return Object.keys(customerInfo.entitlements.active).length > 0;
|
|
278
256
|
} catch (error) {
|
|
279
257
|
return false;
|
|
280
258
|
}
|