@umituz/react-native-subscription 2.14.97 → 2.14.98

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +462 -0
  3. package/package.json +1 -3
  4. package/src/application/README.md +229 -0
  5. package/src/application/ports/README.md +103 -0
  6. package/src/domain/README.md +402 -0
  7. package/src/domain/constants/README.md +80 -0
  8. package/src/domain/entities/README.md +176 -0
  9. package/src/domain/errors/README.md +307 -0
  10. package/src/domain/value-objects/README.md +186 -0
  11. package/src/domains/config/README.md +390 -0
  12. package/src/domains/paywall/README.md +371 -0
  13. package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
  14. package/src/domains/paywall/components/README.md +185 -0
  15. package/src/domains/paywall/entities/README.md +199 -0
  16. package/src/domains/paywall/hooks/README.md +129 -0
  17. package/src/domains/wallet/README.md +292 -0
  18. package/src/domains/wallet/domain/README.md +108 -0
  19. package/src/domains/wallet/domain/entities/README.md +122 -0
  20. package/src/domains/wallet/domain/errors/README.md +157 -0
  21. package/src/domains/wallet/infrastructure/README.md +96 -0
  22. package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
  23. package/src/domains/wallet/presentation/components/README.md +231 -0
  24. package/src/domains/wallet/presentation/hooks/README.md +255 -0
  25. package/src/infrastructure/README.md +514 -0
  26. package/src/infrastructure/mappers/README.md +34 -0
  27. package/src/infrastructure/models/README.md +26 -0
  28. package/src/infrastructure/repositories/README.md +385 -0
  29. package/src/infrastructure/services/README.md +374 -0
  30. package/src/presentation/README.md +410 -0
  31. package/src/presentation/components/README.md +183 -0
  32. package/src/presentation/components/details/CreditRow.md +337 -0
  33. package/src/presentation/components/details/DetailRow.md +283 -0
  34. package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
  35. package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
  36. package/src/presentation/components/details/README.md +449 -0
  37. package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
  38. package/src/presentation/components/feedback/README.md +447 -0
  39. package/src/presentation/components/paywall/PaywallModal.md +444 -0
  40. package/src/presentation/components/paywall/README.md +190 -0
  41. package/src/presentation/components/sections/README.md +468 -0
  42. package/src/presentation/components/sections/SubscriptionSection.md +246 -0
  43. package/src/presentation/hooks/README.md +743 -0
  44. package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
  45. package/src/presentation/hooks/useAuthGate.md +403 -0
  46. package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
  47. package/src/presentation/hooks/useCreditChecker.md +407 -0
  48. package/src/presentation/hooks/useCredits.md +342 -0
  49. package/src/presentation/hooks/useCreditsGate.md +346 -0
  50. package/src/presentation/hooks/useDeductCredit.md +160 -0
  51. package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
  52. package/src/presentation/hooks/useFeatureGate.md +157 -0
  53. package/src/presentation/hooks/useInitializeCredits.md +458 -0
  54. package/src/presentation/hooks/usePaywall.md +334 -0
  55. package/src/presentation/hooks/usePaywallOperations.md +486 -0
  56. package/src/presentation/hooks/usePaywallVisibility.md +344 -0
  57. package/src/presentation/hooks/usePremium.md +230 -0
  58. package/src/presentation/hooks/usePremiumGate.md +423 -0
  59. package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
  60. package/src/presentation/hooks/useSubscription.md +450 -0
  61. package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
  62. package/src/presentation/hooks/useSubscriptionGate.md +168 -0
  63. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
  64. package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
  65. package/src/presentation/hooks/useUserTier.md +356 -0
  66. package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
  67. package/src/presentation/screens/README.md +194 -0
  68. package/src/presentation/types/README.md +38 -0
  69. package/src/presentation/utils/README.md +52 -0
  70. package/src/revenuecat/README.md +523 -0
  71. package/src/revenuecat/domain/README.md +147 -0
  72. package/src/revenuecat/domain/errors/README.md +197 -0
  73. package/src/revenuecat/infrastructure/config/README.md +40 -0
  74. package/src/revenuecat/infrastructure/managers/README.md +49 -0
  75. package/src/revenuecat/presentation/hooks/README.md +56 -0
  76. package/src/utils/README.md +529 -0
@@ -0,0 +1,359 @@
1
+ # useAuthAwarePurchase Hook
2
+
3
+ Security-focused purchase hook that requires authentication before any transaction.
4
+
5
+ ## Import
6
+
7
+ ```typescript
8
+ import {
9
+ useAuthAwarePurchase,
10
+ configureAuthProvider
11
+ } from '@umituz/react-native-subscription';
12
+ ```
13
+
14
+ ## Configuration
15
+
16
+ **IMPORTANT**: You must configure the auth provider once at app initialization:
17
+
18
+ ```typescript
19
+ import { configureAuthProvider } from '@umituz/react-native-subscription';
20
+
21
+ // Configure once at app startup
22
+ configureAuthProvider({
23
+ isAuthenticated: () => {
24
+ // Return true if user is authenticated
25
+ return auth.currentUser != null;
26
+ },
27
+ showAuthModal: () => {
28
+ // Show your authentication modal/screen
29
+ navigation.navigate('Auth');
30
+ },
31
+ });
32
+ ```
33
+
34
+ ## Signature
35
+
36
+ ```typescript
37
+ function useAuthAwarePurchase(): {
38
+ handlePurchase: (pkg: PurchasesPackage) => Promise<boolean>;
39
+ handleRestore: () => Promise<boolean>;
40
+ }
41
+ ```
42
+
43
+ ## Returns
44
+
45
+ | Property | Type | Description |
46
+ |----------|------|-------------|
47
+ | `handlePurchase` | `(pkg) => Promise<boolean>` | Purchase with auth check |
48
+ | `handleRestore` | `() => Promise<boolean>` | Restore with auth check |
49
+
50
+ ## Basic Usage
51
+
52
+ ```typescript
53
+ function PaywallScreen() {
54
+ const { handlePurchase, handleRestore } = useAuthAwarePurchase();
55
+
56
+ const onPurchasePress = async (package: PurchasesPackage) => {
57
+ const success = await handlePurchase(package);
58
+ if (success) {
59
+ console.log('Purchase successful');
60
+ }
61
+ };
62
+
63
+ const onRestorePress = async () => {
64
+ const success = await handleRestore();
65
+ if (success) {
66
+ console.log('Restore successful');
67
+ }
68
+ };
69
+
70
+ return (
71
+ <View>
72
+ <PackageList onSelectPackage={onPurchasePress} />
73
+ <Button onPress={onRestorePress} title="Restore Purchases" />
74
+ </View>
75
+ );
76
+ }
77
+ ```
78
+
79
+ ## Advanced Usage
80
+
81
+ ### With Auth Provider Setup
82
+
83
+ ```typescript
84
+ // App.tsx - Configure at app start
85
+ import { configureAuthProvider } from '@umituz/react-native-subscription';
86
+ import { auth } from './firebase/config';
87
+
88
+ export default function App() {
89
+ useEffect(() => {
90
+ configureAuthProvider({
91
+ isAuthenticated: () => {
92
+ return auth.currentUser !== null;
93
+ },
94
+ showAuthModal: () => {
95
+ // Navigate to auth screen or show modal
96
+ navigationRef.current?.navigate('AuthModal', {
97
+ onAuthSuccess: () => {
98
+ // Paywall will be shown again after auth
99
+ },
100
+ });
101
+ },
102
+ });
103
+ }, []);
104
+
105
+ return <YourAppNavigation />;
106
+ }
107
+ ```
108
+
109
+ ### With Custom Auth Logic
110
+
111
+ ```typescript
112
+ // With your auth library
113
+ import { configureAuthProvider } from '@umituz/react-native-subscription';
114
+ import { useAuth } from '@umituz/react-native-auth';
115
+
116
+ export default function App() {
117
+ const { user, showAuthModal } = useAuth();
118
+
119
+ useEffect(() => {
120
+ configureAuthProvider({
121
+ isAuthenticated: () => !!user,
122
+ showAuthModal: () => {
123
+ showAuthModal({
124
+ purpose: 'purchase',
125
+ message: 'Sign in to complete your purchase',
126
+ });
127
+ },
128
+ });
129
+ }, [user, showAuthModal]);
130
+
131
+ return <YourApp />;
132
+ }
133
+ ```
134
+
135
+ ### With Pending Purchase After Auth
136
+
137
+ ```typescript
138
+ function PaywallWithPendingPurchase() {
139
+ const { handlePurchase } = useAuthAwarePurchase();
140
+ const [pendingPackage, setPendingPackage] = useState<PurchasesPackage | null>(null);
141
+
142
+ useEffect(() => {
143
+ // If user was not authenticated, purchase is intercepted
144
+ // After authentication, you can retry the purchase
145
+ if (user && pendingPackage) {
146
+ handlePurchase(pendingPackage).then((success) => {
147
+ if (success) {
148
+ setPendingPackage(null);
149
+ }
150
+ });
151
+ }
152
+ }, [user, pendingPackage]);
153
+
154
+ const onPurchasePress = async (pkg: PurchasesPackage) => {
155
+ const success = await handlePurchase(pkg);
156
+ if (!success && !user) {
157
+ // User needs to authenticate first
158
+ setPendingPackage(pkg);
159
+ }
160
+ };
161
+
162
+ return <PackageList onSelectPackage={onPurchasePress} />;
163
+ }
164
+ ```
165
+
166
+ ### With Error Handling
167
+
168
+ ```typescript
169
+ function SecurePaywall() {
170
+ const { handlePurchase, handleRestore } = useAuthAwarePurchase();
171
+
172
+ const onPurchasePress = async (pkg: PurchasesPackage) => {
173
+ try {
174
+ const success = await handlePurchase(pkg);
175
+
176
+ if (!success) {
177
+ // Check if auth was the issue
178
+ if (!auth.currentUser) {
179
+ console.log('Purchase blocked - user not authenticated');
180
+ } else {
181
+ console.log('Purchase failed for other reasons');
182
+ }
183
+ }
184
+ } catch (error) {
185
+ console.error('Purchase error:', error);
186
+ Alert.alert('Error', 'Failed to complete purchase');
187
+ }
188
+ };
189
+
190
+ return (
191
+ <PaywallModal>
192
+ <PackageList onSelectPackage={onPurchasePress} />
193
+ </PaywallModal>
194
+ );
195
+ }
196
+ ```
197
+
198
+ ## Security Features
199
+
200
+ ### Auth Provider Required
201
+
202
+ The hook will **block all purchases** if auth provider is not configured:
203
+
204
+ ```typescript
205
+ // Development mode error
206
+ [useAuthAwarePurchase] CRITICAL: Auth provider not configured.
207
+ Call configureAuthProvider() at app start. Purchase blocked for security.
208
+ ```
209
+
210
+ ### Anonymous User Blocking
211
+
212
+ Purchases are automatically blocked for anonymous/guest users:
213
+
214
+ ```typescript
215
+ // Development mode log
216
+ [useAuthAwarePurchase] User not authenticated, opening auth modal
217
+ ```
218
+
219
+ ### Automatic Auth Flow
220
+
221
+ When an unauthenticated user tries to purchase:
222
+
223
+ 1. Purchase is blocked
224
+ 2. Auth modal is shown
225
+ 3. User can authenticate
226
+ 4. After auth, purchase can be retried
227
+
228
+ ## Examples
229
+
230
+ ### Complete Paywall Implementation
231
+
232
+ ```typescript
233
+ function PaywallScreen() {
234
+ const { handlePurchase, handleRestore } = useAuthAwarePurchase();
235
+ const { packages } = useSubscriptionPackages();
236
+
237
+ const [selectedPackage, setSelectedPackage] = useState<PurchasesPackage | null>(null);
238
+ const [isPurchasing, setIsPurchasing] = useState(false);
239
+
240
+ const handlePackageSelect = async (pkg: PurchasesPackage) => {
241
+ setSelectedPackage(pkg);
242
+ setIsPurchasing(true);
243
+
244
+ try {
245
+ const success = await handlePurchase(pkg);
246
+
247
+ if (success) {
248
+ Alert.alert('Success', 'You are now a Premium member!');
249
+ }
250
+ } catch (error) {
251
+ Alert.alert('Error', 'Purchase failed. Please try again.');
252
+ } finally {
253
+ setIsPurchasing(false);
254
+ setSelectedPackage(null);
255
+ }
256
+ };
257
+
258
+ const handleRestorePress = async () => {
259
+ const success = await handleRestore();
260
+ Alert.alert(
261
+ success ? 'Success' : 'Failed',
262
+ success ? 'Purchases restored' : 'No purchases found'
263
+ );
264
+ };
265
+
266
+ return (
267
+ <ScrollView>
268
+ <PaywallHeader />
269
+
270
+ {packages.map((pkg) => (
271
+ <PackageCard
272
+ key={pkg.identifier}
273
+ package={pkg}
274
+ onSelect={handlePackageSelect}
275
+ disabled={isPurchasing}
276
+ selected={selectedPackage?.identifier === pkg.identifier}
277
+ />
278
+ ))}
279
+
280
+ <Button onPress={handleRestorePress} title="Restore Purchases" />
281
+
282
+ <TermsAndConditions />
283
+ </ScrollView>
284
+ );
285
+ }
286
+ ```
287
+
288
+ ### In-App Purchase Button
289
+
290
+ ```typescript
291
+ function InAppPurchaseButton({ productIdentifier }) {
292
+ const { handlePurchase } = useAuthAwarePurchase();
293
+ const { packages } = useSubscriptionPackages();
294
+
295
+ const pkg = packages.find((p) => p.identifier === productIdentifier);
296
+
297
+ const onPress = async () => {
298
+ if (!pkg) return;
299
+
300
+ const success = await handlePurchase(pkg);
301
+
302
+ if (success) {
303
+ onPurchaseSuccess?.();
304
+ }
305
+ };
306
+
307
+ return (
308
+ <Button
309
+ onPress={onPress}
310
+ title="Get Premium"
311
+ disabled={!pkg}
312
+ />
313
+ );
314
+ }
315
+ ```
316
+
317
+ ## Best Practices
318
+
319
+ 1. **Configure early** - Set up auth provider at app initialization
320
+ 2. **Test auth flow** - Verify purchases work for authenticated users
321
+ 3. **Test guest flow** - Verify guests are prompted to sign in
322
+ 4. **Handle failures** - Show user-friendly error messages
323
+ 5. **Clear pending** - Reset pending purchase state after completion
324
+ 6. **Security first** - Never bypass auth checks
325
+ 7. **Development testing** - Use dev logs to verify auth checks work
326
+
327
+ ## Security Considerations
328
+
329
+ ### Why Auth Provider is Required
330
+
331
+ This hook implements a security-first approach to prevent:
332
+
333
+ 1. **Anonymous purchases** - Guest users cannot make purchases
334
+ 2. **Unauthorized transactions** - Only authenticated users can buy
335
+ 3. **Payment fraud** - Reduces risk of fraudulent purchases
336
+ 4. **Compliance** - Meets app store requirements for user identification
337
+
338
+ ### Configuration Checklist
339
+
340
+ - [ ] Call `configureAuthProvider()` once at app startup
341
+ - [ ] Provide `isAuthenticated()` function
342
+ - [ ] Provide `showAuthModal()` function
343
+ - [ ] Test purchase flow with authenticated user
344
+ - [ ] Test purchase flow with unauthenticated user
345
+ - [ ] Verify development logs show auth checks
346
+ - [ ] Verify purchases are blocked without auth provider
347
+
348
+ ## Related Hooks
349
+
350
+ - **usePremium** - For purchase and restore operations
351
+ - **usePaywallOperations** - For complete paywall purchase handling
352
+ - **useAuthGate** - For authentication gating
353
+ - **useAuthSubscriptionSync** - For syncing auth with subscription
354
+
355
+ ## See Also
356
+
357
+ - [Auth Integration](../../hooks/useAuthSubscriptionSync.md)
358
+ - [Paywall Screen](../screens/README.md)
359
+ - [Security Best Practices](../../../docs/SECURITY.md)