@umituz/react-native-subscription 2.14.99 → 2.14.100

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 (92) hide show
  1. package/README.md +211 -394
  2. package/package.json +1 -1
  3. package/src/application/README.md +46 -225
  4. package/src/application/ports/README.md +42 -97
  5. package/src/domain/README.md +36 -384
  6. package/src/domain/constants/README.md +0 -56
  7. package/src/domain/entities/README.md +43 -169
  8. package/src/domain/errors/README.md +33 -287
  9. package/src/domain/value-objects/README.md +43 -179
  10. package/src/domains/README.md +50 -238
  11. package/src/domains/README.md.bak +274 -0
  12. package/src/domains/config/README.md +93 -383
  13. package/src/domains/config/domain/README.md +23 -376
  14. package/src/domains/config/domain/entities/README.md +34 -343
  15. package/src/domains/paywall/README.md +99 -369
  16. package/src/domains/paywall/components/README.md +34 -178
  17. package/src/domains/paywall/entities/README.md +34 -193
  18. package/src/domains/paywall/hooks/README.md +34 -122
  19. package/src/domains/wallet/README.md +34 -275
  20. package/src/domains/wallet/README.md.bak +209 -0
  21. package/src/domains/wallet/domain/README.md +34 -101
  22. package/src/domains/wallet/domain/entities/README.md +34 -115
  23. package/src/domains/wallet/domain/errors/README.md +34 -151
  24. package/src/domains/wallet/infrastructure/README.md +34 -89
  25. package/src/domains/wallet/presentation/components/README.md +34 -224
  26. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  27. package/src/infrastructure/README.md +37 -496
  28. package/src/infrastructure/mappers/README.md +0 -13
  29. package/src/infrastructure/repositories/README.md +74 -360
  30. package/src/infrastructure/services/README.md +95 -370
  31. package/src/presentation/README.md +123 -408
  32. package/src/presentation/README.md.bak +172 -0
  33. package/src/presentation/components/README.md +151 -179
  34. package/src/presentation/components/README.md.bak +217 -0
  35. package/src/presentation/components/details/CreditRow.md +65 -310
  36. package/src/presentation/components/details/DetailRow.md +63 -255
  37. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  38. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  39. package/src/presentation/components/details/README.md +97 -447
  40. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  41. package/src/presentation/components/feedback/README.md +97 -445
  42. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  43. package/src/presentation/components/paywall/README.md +50 -186
  44. package/src/presentation/components/sections/README.md +97 -466
  45. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  46. package/src/presentation/hooks/README.md +154 -741
  47. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  48. package/src/presentation/hooks/useAuthGate.md +61 -375
  49. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  50. package/src/presentation/hooks/useCreditChecker.md +73 -378
  51. package/src/presentation/hooks/useCredits.md +74 -313
  52. package/src/presentation/hooks/useCredits.md.bak +231 -0
  53. package/src/presentation/hooks/useCreditsGate.md +66 -318
  54. package/src/presentation/hooks/useDeductCredit.md +0 -76
  55. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  56. package/src/presentation/hooks/useFeatureGate.md +105 -150
  57. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  58. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  59. package/src/presentation/hooks/usePaywall.md +61 -306
  60. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  61. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  62. package/src/presentation/hooks/usePremium.md +84 -226
  63. package/src/presentation/hooks/usePremiumGate.md +60 -395
  64. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  65. package/src/presentation/hooks/useSubscription.md +66 -422
  66. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  67. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  68. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  69. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  70. package/src/presentation/hooks/useUserTier.md +63 -328
  71. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  72. package/src/presentation/screens/README.md +48 -190
  73. package/src/presentation/types/README.md +0 -16
  74. package/src/presentation/utils/README.md +0 -21
  75. package/src/revenuecat/README.md +99 -518
  76. package/src/revenuecat/application/README.md +35 -150
  77. package/src/revenuecat/application/ports/README.md +34 -162
  78. package/src/revenuecat/domain/README.md +42 -141
  79. package/src/revenuecat/domain/constants/README.md +34 -176
  80. package/src/revenuecat/domain/entities/README.md +34 -374
  81. package/src/revenuecat/domain/errors/README.md +47 -191
  82. package/src/revenuecat/domain/types/README.md +34 -366
  83. package/src/revenuecat/domain/value-objects/README.md +34 -434
  84. package/src/revenuecat/infrastructure/README.md +34 -43
  85. package/src/revenuecat/infrastructure/config/README.md +32 -23
  86. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  87. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  88. package/src/revenuecat/infrastructure/services/README.md +35 -318
  89. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  90. package/src/revenuecat/presentation/README.md +34 -176
  91. package/src/revenuecat/presentation/hooks/README.md +29 -35
  92. package/src/utils/README.md +38 -525
@@ -2,485 +2,91 @@
2
2
 
3
3
  Complete paywall purchase operations with authentication handling.
4
4
 
5
- ## Import
5
+ ## Location
6
6
 
7
- ```typescript
8
- import { usePaywallOperations } from '@umituz/react-native-subscription';
9
- ```
7
+ **Import Path**: `@umituz/react-native-subscription`
10
8
 
11
- ## Signature
9
+ **File**: `src/presentation/hooks/usePaywallOperations.ts`
12
10
 
13
- ```typescript
14
- function usePaywallOperations(params: {
15
- userId: string | undefined;
16
- isAnonymous: boolean;
17
- onPaywallClose?: () => void;
18
- onPurchaseSuccess?: () => void;
19
- onAuthRequired?: () => void;
20
- }): {
21
- pendingPackage: PurchasesPackage | null;
22
- handlePurchase: (pkg: PurchasesPackage) => Promise<boolean>;
23
- handleRestore: () => Promise<boolean>;
24
- handleInAppPurchase: (pkg: PurchasesPackage) => Promise<boolean>;
25
- handleInAppRestore: () => Promise<boolean>;
26
- completePendingPurchase: () => Promise<boolean>;
27
- clearPendingPackage: () => void;
28
- }
29
- ```
11
+ **Type**: Hook
30
12
 
31
- ## Parameters
13
+ ## Strategy
32
14
 
33
- | Parameter | Type | Default | Description |
34
- |-----------|------|---------|-------------|
35
- | `userId` | `string \| undefined` | **Required** | Current user ID |
36
- | `isAnonymous` | `boolean` | **Required** | Whether user is anonymous/guest |
37
- | `onPaywallClose` | `() => void` | `undefined` | Callback when paywall closes |
38
- | `onPurchaseSuccess` | `() => void` | `undefined` | Callback after successful purchase |
39
- | `onAuthRequired` | `() => void` | `undefined` | Callback when auth is required |
15
+ ### Paywall Purchase Flow with Auth
40
16
 
41
- ## Returns
17
+ 1. **Auth Check**: Verify if user is authenticated before purchase
18
+ 2. **Pending Package Management**: Store package when auth is required
19
+ 3. **Auth Flow Trigger**: Show auth modal for unauthenticated users
20
+ 4. **Purchase Execution**: Complete purchase after authentication
21
+ 5. **Restore Support**: Handle purchase restoration with auth check
22
+ 6. **Callback Handling**: Execute appropriate callbacks at each stage
42
23
 
43
- | Property | Type | Description |
44
- |----------|------|-------------|
45
- | `pendingPackage` | `PurchasesPackage \| null` | Package waiting for auth |
46
- | `handlePurchase` | `(pkg) => Promise<boolean>` | Handle purchase (post-auth) |
47
- | `handleRestore` | `() => Promise<boolean>` | Handle restore (post-auth) |
48
- | `handleInAppPurchase` | `(pkg) => Promise<boolean>` | Handle purchase (in-app) |
49
- | `handleInAppRestore` | `() => Promise<boolean>` | Handle restore (in-app) |
50
- | `completePendingPurchase` | `() => Promise<boolean>` | Complete purchase after auth |
51
- | `clearPendingPackage` | `() => void` | Clear pending package |
24
+ ### Integration Points
52
25
 
53
- ## Basic Usage
26
+ - **usePremium**: For purchase and restore operations
27
+ - **Auth Context**: User authentication state
28
+ - **Paywall Domain**: For paywall display and management
29
+ - **Auth UI**: For authentication modal
30
+ - **RevenueCat**: For purchase transactions
54
31
 
55
- ```typescript
56
- function PaywallScreen() {
57
- const { user } = useAuth();
58
- const { isAnonymous } = useAuth();
32
+ ## Restrictions
59
33
 
60
- const {
61
- handlePurchase,
62
- handleRestore,
63
- } = usePaywallOperations({
64
- userId: user?.uid,
65
- isAnonymous,
66
- onPurchaseSuccess: () => {
67
- navigation.goBack();
68
- },
69
- onAuthRequired: () => {
70
- showAuthModal();
71
- },
72
- });
34
+ ### REQUIRED
73
35
 
74
- const onPackagePress = async (pkg: PurchasesPackage) => {
75
- const success = await handlePurchase(pkg);
76
- if (success) {
77
- console.log('Purchase successful');
78
- }
79
- };
36
+ - **User ID**: MUST provide valid userId parameter
37
+ - **Anonymous Check**: MUST provide isAnonymous parameter
38
+ - **Auth Required Callback**: MUST implement onAuthRequired callback
39
+ - **Error Handling**: MUST handle purchase failures
80
40
 
81
- const onRestorePress = async () => {
82
- const success = await handleRestore();
83
- if (success) {
84
- console.log('Restore successful');
85
- }
86
- };
41
+ ### PROHIBITED
87
42
 
88
- return (
89
- <View>
90
- <PackageList onSelectPackage={onPackagePress} />
91
- <Button onPress={onRestorePress} title="Restore Purchases" />
92
- </View>
93
- );
94
- }
95
- ```
43
+ - **NEVER** call without valid userId
44
+ - **NEVER** call without isAnonymous parameter
45
+ - **DO NOT** proceed with purchase without auth check
46
+ - **DO NOT** ignore pending package state
96
47
 
97
- ## Advanced Usage
48
+ ### CRITICAL SAFETY
98
49
 
99
- ### With Pending Purchase Flow
50
+ - **ALWAYS** check authentication status before purchase
51
+ - **MUST** handle pending package after auth
52
+ - **ALWAYS** provide clear auth flow for users
53
+ - **NEVER** allow anonymous purchases without auth
100
54
 
101
- ```typescript
102
- function PaywallWithPendingFlow() {
103
- const { user } = useAuth();
104
- const { isAnonymous } = useAuth();
55
+ ## AI Agent Guidelines
105
56
 
106
- const {
107
- pendingPackage,
108
- handlePurchase,
109
- completePendingPurchase,
110
- clearPendingPackage,
111
- } = usePaywallOperations({
112
- userId: user?.uid,
113
- isAnonymous,
114
- onAuthRequired: () => {
115
- navigation.navigate('AuthModal', {
116
- purpose: 'purchase',
117
- onAuthSuccess: () => {
118
- // Complete purchase after auth
119
- completePendingPurchase();
120
- },
121
- });
122
- },
123
- });
57
+ ### When Implementing Paywall Operations
124
58
 
125
- // Show pending package indicator
126
- useEffect(() => {
127
- if (pendingPackage && !user) {
128
- console.log('Package pending authentication:', pendingPackage.identifier);
129
- }
130
- }, [pendingPackage, user]);
59
+ 1. **Always** provide valid userId
60
+ 2. **Always** provide isAnonymous status
61
+ 3. **Always** implement onAuthRequired with pending package handling
62
+ 4. **Always** implement onPurchaseSuccess callback
63
+ 5. **Always** handle purchase and restore failures
131
64
 
132
- const handleCancelAuth = () => {
133
- clearPendingPackage();
134
- navigation.goBack();
135
- };
65
+ ### Integration Checklist
136
66
 
137
- return (
138
- <View>
139
- {pendingPackage && !user && (
140
- <Banner>
141
- <Text>Complete your purchase after signing in</Text>
142
- <Button onPress={handleCancelAuth} title="Cancel" />
143
- </Banner>
144
- )}
67
+ - [ ] Import from correct path: `@umituz/react-native-subscription`
68
+ - [ ] Provide valid userId
69
+ - [ ] Provide isAnonymous status
70
+ - [ ] Implement onAuthRequired callback
71
+ - [ ] Implement onPurchaseSuccess callback
72
+ - [ ] Implement onPaywallClose callback
73
+ - [ ] Handle pending package state
74
+ - [ ] Test purchase with authenticated user
75
+ - [ ] Test purchase with anonymous user
76
+ - [ ] Test purchase flow after authentication
145
77
 
146
- <PackageList onSelectPackage={handlePurchase} />
147
- </View>
148
- );
149
- }
150
- ```
78
+ ### Common Patterns
151
79
 
152
- ### With In-App Purchases
80
+ 1. **Pending Purchase Flow**: Store package, show auth, complete purchase
81
+ 2. **In-App Purchases**: Use handleInAppPurchase for modal paywalls
82
+ 3. **Purchase Analytics**: Track purchase attempts and completions
83
+ 4. **Error Recovery**: Handle failures and provide retry options
84
+ 5. **Post-Onboarding**: Handle purchases after onboarding flow
153
85
 
154
- ```typescript
155
- function InAppPaywall() {
156
- const { user } = useAuth();
157
- const { isAnonymous } = useAuth();
86
+ ## Related Documentation
158
87
 
159
- const {
160
- handleInAppPurchase,
161
- handleInAppRestore,
162
- } = usePaywallOperations({
163
- userId: user?.uid,
164
- isAnonymous,
165
- onPaywallClose: () => {
166
- navigation.goBack();
167
- },
168
- onPurchaseSuccess: () => {
169
- navigation.goBack();
170
- },
171
- onAuthRequired: () => {
172
- showAuthModal();
173
- },
174
- });
175
-
176
- return (
177
- <Modal>
178
- <PaywallContent>
179
- <PackageList onSelectPackage={handleInAppPurchase} />
180
- <RestoreButton onPress={handleInAppRestore} />
181
- <CloseButton onPress={() => navigation.goBack()} />
182
- </PaywallContent>
183
- </Modal>
184
- );
185
- }
186
- ```
187
-
188
- ### With Purchase Analytics
189
-
190
- ```typescript
191
- function TrackedPaywall() {
192
- const { user } = useAuth();
193
- const { isAnonymous } = useAuth();
194
-
195
- const {
196
- handlePurchase,
197
- handleRestore,
198
- pendingPackage,
199
- } = usePaywallOperations({
200
- userId: user?.uid,
201
- isAnonymous,
202
- onPurchaseSuccess: () => {
203
- analytics.track('purchase_completed', {
204
- userId: user?.uid,
205
- packageIdentifier: pendingPackage?.identifier,
206
- });
207
- },
208
- onAuthRequired: () => {
209
- analytics.track('auth_required_for_purchase');
210
- showAuthModal();
211
- },
212
- });
213
-
214
- const onPackageSelect = async (pkg: PurchasesPackage) => {
215
- analytics.track('purchase_attempted', {
216
- packageIdentifier: pkg.identifier,
217
- price: pkg.product.price,
218
- });
219
-
220
- const success = await handlePurchase(pkg);
221
-
222
- if (!success) {
223
- analytics.track('purchase_failed', {
224
- packageIdentifier: pkg.identifier,
225
- });
226
- }
227
- };
228
-
229
- return <PackageList onSelectPackage={onPackageSelect} />;
230
- }
231
- ```
232
-
233
- ### With Error Handling
234
-
235
- ```typescript
236
- function RobustPaywall() {
237
- const { user } = useAuth();
238
- const { isAnonymous } = useAuth();
239
-
240
- const {
241
- handlePurchase,
242
- handleRestore,
243
- completePendingPurchase,
244
- clearPendingPackage,
245
- } = usePaywallOperations({
246
- userId: user?.uid,
247
- isAnonymous,
248
- onAuthRequired: () => {
249
- showAuthModal({
250
- onAuthSuccess: async () => {
251
- const success = await completePendingPurchase();
252
- if (!success) {
253
- Alert.alert('Error', 'Could not complete purchase');
254
- clearPendingPackage();
255
- }
256
- },
257
- onAuthCancelled: () => {
258
- clearPendingPackage();
259
- },
260
- });
261
- },
262
- });
263
-
264
- const handlePackagePress = async (pkg: PurchasesPackage) => {
265
- try {
266
- const success = await handlePurchase(pkg);
267
-
268
- if (!success) {
269
- if (!user) {
270
- // Auth required - handled by onAuthRequired
271
- return;
272
- }
273
- // Other failure
274
- Alert.alert('Purchase Failed', 'Could not complete purchase. Please try again.');
275
- }
276
- } catch (error) {
277
- console.error('Purchase error:', error);
278
- Alert.alert('Error', 'An unexpected error occurred');
279
- }
280
- };
281
-
282
- return <PackageList onSelectPackage={handlePackagePress} />;
283
- }
284
- ```
285
-
286
- ## Examples
287
-
288
- ### Complete Paywall Implementation
289
-
290
- ```typescript
291
- function PaywallScreen() {
292
- const { user } = useAuth();
293
- const { isAnonymous } = useAuth();
294
- const navigation = useNavigation();
295
-
296
- const {
297
- pendingPackage,
298
- handlePurchase,
299
- handleRestore,
300
- completePendingPurchase,
301
- clearPendingPackage,
302
- } = usePaywallOperations({
303
- userId: user?.uid,
304
- isAnonymous,
305
- onPaywallClose: () => {
306
- navigation.goBack();
307
- },
308
- onPurchaseSuccess: () => {
309
- // Refresh user data
310
- queryClient.invalidateQueries(['subscription']);
311
- navigation.goBack();
312
- },
313
- onAuthRequired: () => {
314
- // Show auth modal with pending purchase context
315
- navigation.push('AuthModal', {
316
- purpose: 'purchase',
317
- message: 'Sign in to complete your purchase',
318
- onAuthSuccess: async () => {
319
- const success = await completePendingPurchase();
320
- if (success) {
321
- navigation.goBack();
322
- }
323
- },
324
- onAuthCancelled: () => {
325
- clearPendingPackage();
326
- },
327
- });
328
- },
329
- });
330
-
331
- const [selectedPackage, setSelectedPackage] = useState<PurchasesPackage | null>(null);
332
-
333
- const onPackagePress = async (pkg: PurchasesPackage) => {
334
- setSelectedPackage(pkg);
335
- const success = await handlePurchase(pkg);
336
- setSelectedPackage(null);
337
- };
338
-
339
- const onRestorePress = async () => {
340
- const success = await handleRestore();
341
- Alert.alert(
342
- success ? 'Success' : 'No Purchases Found',
343
- success
344
- ? 'Your purchases have been restored'
345
- : 'No previous purchases found for this account'
346
- );
347
- };
348
-
349
- return (
350
- <ScrollView style={styles.container}>
351
- <PaywallHeader />
352
-
353
- {pendingPackage && !user && (
354
- <Banner style={styles.pendingBanner}>
355
- <Text>Complete your purchase after signing in</Text>
356
- </Banner>
357
- )}
358
-
359
- <PackageList
360
- packages={packages}
361
- selectedPackage={selectedPackage}
362
- onSelectPackage={onPackagePress}
363
- />
364
-
365
- <View style={styles.restoreSection}>
366
- <Button
367
- onPress={onRestorePress}
368
- variant="outline"
369
- title="Restore Purchases"
370
- />
371
- </View>
372
-
373
- <TermsAndConditions />
374
- </ScrollView>
375
- );
376
- }
377
- ```
378
-
379
- ### Post-Onboarding Purchase
380
-
381
- ```typescript
382
- function PostOnboardingPaywall() {
383
- const { user } = useAuth();
384
- const { isAnonymous } = useAuth();
385
-
386
- const {
387
- handlePurchase,
388
- completePendingPurchase,
389
- } = usePaywallOperations({
390
- userId: user?.uid,
391
- isAnonymous,
392
- onPurchaseSuccess: () => {
393
- // Navigate to onboarding completion
394
- navigation.reset({
395
- index: 0,
396
- routes: [{ name: 'Home' }],
397
- });
398
- },
399
- onAuthRequired: () => {
400
- navigation.navigate('Auth', {
401
- screen: 'SignUp',
402
- params: {
403
- onAuthSuccess: async () => {
404
- await completePendingPurchase();
405
- },
406
- },
407
- });
408
- },
409
- });
410
-
411
- return (
412
- <View>
413
- <OnboardingPaywallContent />
414
- <PackageList onSelectPackage={handlePurchase} />
415
- </View>
416
- );
417
- }
418
- ```
419
-
420
- ## Purchase Flow
421
-
422
- ### Authenticated User
423
-
424
- ```typescript
425
- user = { uid: 'user-123' }
426
- isAnonymous = false
427
-
428
- handlePurchase(package)
429
- → Purchase proceeds immediately ✅
430
- → onPurchaseSuccess() called ✅
431
- ```
432
-
433
- ### Anonymous User
434
-
435
- ```typescript
436
- user = null
437
- isAnonymous = true
438
-
439
- handlePurchase(package)
440
- → Purchase blocked 🚫
441
- → pendingPackage = package 📦
442
- → onAuthRequired() called 🔐
443
- → User completes auth...
444
- → completePendingPurchase()
445
- → Purchase proceeds ✅
446
- ```
447
-
448
- ### Pending Package Management
449
-
450
- ```typescript
451
- // User selects package while not authenticated
452
- handlePurchase(monthlyPackage)
453
- → pendingPackage = monthlyPackage
454
- → onAuthRequired() triggered
455
-
456
- // User cancels auth
457
- clearPendingPackage()
458
- → pendingPackage = null
459
-
460
- // Or user completes auth
461
- completePendingPurchase()
462
- → Purchases monthlyPackage
463
- → pendingPackage = null
464
- ```
465
-
466
- ## Best Practices
467
-
468
- 1. **Handle auth flow** - Implement onAuthRequired callback
469
- 2. **Show pending state** - Display indicator when package is pending
470
- 3. **Clear pending** - Reset pending when user cancels auth
471
- 4. **Track events** - Monitor purchase attempts and completions
472
- 5. **Handle errors** - Show user-friendly error messages
473
- 6. **Test both flows** - Authenticated and anonymous users
474
- 7. **Provide restore** - Always offer restore purchases option
475
-
476
- ## Related Hooks
477
-
478
- - **usePremium** - For purchase and restore operations
479
- - **useAuthAwarePurchase** - For auth-gated purchases
480
- - **usePaywallVisibility** - For paywall visibility control
481
-
482
- ## See Also
483
-
484
- - [Paywall Screen](../screens/README.md)
485
- - [Purchase Flow](../../../docs/PURCHASE_FLOW.md)
486
- - [Auth Integration](./useAuthSubscriptionSync.md)
88
+ - **usePremium**: For purchase and restore operations
89
+ - **useAuthAwarePurchase**: For auth-gated purchases
90
+ - **usePaywallVisibility**: For paywall visibility control
91
+ - **Paywall Screen**: `src/presentation/screens/README.md`
92
+ - **Purchase Flow**: `src/docs/PURCHASE_FLOW.md`