@umituz/react-native-subscription 2.14.74 → 2.14.76

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.14.74",
3
+ "version": "2.14.76",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -33,8 +33,14 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
33
33
  onPurchaseSuccess,
34
34
  onPurchaseError,
35
35
  onAuthRequired,
36
+ visible,
37
+ onClose,
36
38
  }) => {
37
- const { showPaywall, closePaywall } = usePaywallVisibility();
39
+ const { showPaywall: globalShowPaywall, closePaywall: globalClosePaywall } = usePaywallVisibility();
40
+
41
+ const isVisible = visible !== undefined ? visible : globalShowPaywall;
42
+ const handleClose = onClose !== undefined ? onClose : globalClosePaywall;
43
+
38
44
  const { data: allPackages = [], isLoading, isFetching, status, error } = useSubscriptionPackages(userId ?? undefined);
39
45
  const { mutateAsync: purchasePackage } = usePurchasePackage(userId ?? undefined);
40
46
  const { mutateAsync: restorePurchases } = useRestorePurchase(userId ?? undefined);
@@ -53,7 +59,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
53
59
  }, [allPackages, mode, packageFilterConfig, creditAmounts]);
54
60
 
55
61
  useEffect(() => {
56
- if (__DEV__ && showPaywall) {
62
+ if (__DEV__ && isVisible) {
57
63
  console.log("[PaywallContainer] Paywall opened:", {
58
64
  userId,
59
65
  isAnonymous,
@@ -69,7 +75,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
69
75
  error: error?.message ?? null,
70
76
  });
71
77
  }
72
- }, [showPaywall, userId, isAnonymous, mode, allPackages.length, filteredPackages.length, isLoading, isFetching, status, error]);
78
+ }, [isVisible, userId, isAnonymous, mode, allPackages.length, filteredPackages.length, isLoading, isFetching, status, error]);
73
79
 
74
80
  // Auto-purchase when user authenticates after selecting a package
75
81
  useEffect(() => {
@@ -91,7 +97,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
91
97
  console.log("[PaywallContainer] Auto-purchase successful");
92
98
  }
93
99
  onPurchaseSuccess?.();
94
- closePaywall();
100
+ handleClose();
95
101
  }
96
102
  } catch (err) {
97
103
  const message = err instanceof Error ? err.message : String(err);
@@ -104,7 +110,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
104
110
  }
105
111
  })();
106
112
  }
107
- }, [isAnonymous, userId, pendingPackage, purchasePackage, onPurchaseSuccess, onPurchaseError, closePaywall]);
113
+ }, [isAnonymous, userId, pendingPackage, purchasePackage, onPurchaseSuccess, onPurchaseError, handleClose]);
108
114
 
109
115
  const handlePurchase = useCallback(
110
116
  async (pkg: PurchasesPackage) => {
@@ -131,7 +137,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
131
137
  console.log("[PaywallContainer] Purchase successful");
132
138
  }
133
139
  onPurchaseSuccess?.();
134
- closePaywall();
140
+ handleClose();
135
141
  }
136
142
  } catch (err) {
137
143
  const message = err instanceof Error ? err.message : String(err);
@@ -141,7 +147,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
141
147
  onPurchaseError?.(message);
142
148
  }
143
149
  },
144
- [isAnonymous, purchasePackage, closePaywall, onPurchaseSuccess, onPurchaseError, onAuthRequired, setPendingPackage]
150
+ [isAnonymous, purchasePackage, handleClose, onPurchaseSuccess, onPurchaseError, onAuthRequired, setPendingPackage]
145
151
  );
146
152
 
147
153
  const handleRestore = useCallback(async () => {
@@ -155,7 +161,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
155
161
  console.log("[PaywallContainer] Restore successful");
156
162
  }
157
163
  onPurchaseSuccess?.();
158
- closePaywall();
164
+ handleClose();
159
165
  }
160
166
  } catch (err) {
161
167
  const message = err instanceof Error ? err.message : String(err);
@@ -164,16 +170,16 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
164
170
  }
165
171
  onPurchaseError?.(message);
166
172
  }
167
- }, [restorePurchases, closePaywall, onPurchaseSuccess, onPurchaseError]);
173
+ }, [restorePurchases, handleClose, onPurchaseSuccess, onPurchaseError]);
168
174
 
169
- if (!showPaywall) {
175
+ if (!isVisible) {
170
176
  return null;
171
177
  }
172
178
 
173
179
  return (
174
180
  <PaywallModal
175
- visible={showPaywall}
176
- onClose={closePaywall}
181
+ visible={isVisible}
182
+ onClose={handleClose}
177
183
  translations={translations}
178
184
  packages={filteredPackages}
179
185
  isLoading={isLoading}
@@ -36,5 +36,9 @@ export interface PaywallContainerProps {
36
36
  readonly onPurchaseError?: (error: string) => void;
37
37
  /** Callback when auth is required (for anonymous users) */
38
38
  readonly onAuthRequired?: () => void;
39
+ /** Visibility override */
40
+ readonly visible?: boolean;
41
+ /** Callback when paywall is closed */
42
+ readonly onClose?: () => void;
39
43
  }
40
44
 
@@ -4,6 +4,7 @@
4
4
  * Apps just call initializeSubscription with config
5
5
  */
6
6
 
7
+ import { Platform } from "react-native";
7
8
  import type { CustomerInfo } from "react-native-purchases";
8
9
  import type { CreditsConfig } from "../../domain/entities/Credits";
9
10
  import { configureCreditsRepository, getCreditsRepository } from "../repositories/CreditsRepositoryProvider";
@@ -23,7 +24,12 @@ export interface CreditPackageConfig {
23
24
  }
24
25
 
25
26
  export interface SubscriptionInitConfig {
26
- apiKey: string;
27
+ /** API key for RevenueCat (can provide single key or platform-specific keys) */
28
+ apiKey?: string;
29
+ /** iOS-specific API key (overrides apiKey if provided on iOS) */
30
+ apiKeyIos?: string;
31
+ /** Android-specific API key (overrides apiKey if provided on Android) */
32
+ apiKeyAndroid?: string;
27
33
  testStoreKey?: string;
28
34
  entitlementId: string;
29
35
  credits: CreditsConfig;
@@ -83,6 +89,8 @@ export const initializeSubscription = async (
83
89
  ): Promise<void> => {
84
90
  const {
85
91
  apiKey,
92
+ apiKeyIos,
93
+ apiKeyAndroid,
86
94
  testStoreKey,
87
95
  entitlementId,
88
96
  credits,
@@ -95,7 +103,12 @@ export const initializeSubscription = async (
95
103
  authStateTimeoutMs = 2000,
96
104
  } = config;
97
105
 
98
- if (!apiKey) {
106
+ // Resolve API key based on platform
107
+ const resolvedApiKey = Platform.OS === "ios"
108
+ ? (apiKeyIos || apiKey || "")
109
+ : (apiKeyAndroid || apiKey || "");
110
+
111
+ if (!resolvedApiKey) {
99
112
  throw new Error("RevenueCat API key is required");
100
113
  }
101
114
 
@@ -180,7 +193,7 @@ export const initializeSubscription = async (
180
193
 
181
194
  SubscriptionManager.configure({
182
195
  config: {
183
- apiKey,
196
+ apiKey: resolvedApiKey,
184
197
  testStoreKey,
185
198
  entitlementIdentifier: entitlementId,
186
199
  consumableProductIdentifiers: consumableIdentifiers,
@@ -188,7 +201,7 @@ export const initializeSubscription = async (
188
201
  onCreditsUpdated,
189
202
  onPurchaseCompleted: handlePurchaseCompleted,
190
203
  },
191
- apiKey,
204
+ apiKey: resolvedApiKey,
192
205
  getAnonymousUserId,
193
206
  });
194
207