@umituz/react-native-subscription 2.14.98 → 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.
- package/README.md +211 -395
- package/package.json +1 -1
- package/src/application/README.md +46 -225
- package/src/application/ports/README.md +42 -97
- package/src/domain/README.md +36 -384
- package/src/domain/constants/README.md +0 -56
- package/src/domain/entities/README.md +43 -169
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +52 -0
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +37 -0
- package/src/domains/config/domain/entities/README.md +41 -0
- package/src/domains/paywall/README.md +99 -369
- package/src/domains/paywall/components/README.md +34 -178
- package/src/domains/paywall/entities/README.md +34 -193
- package/src/domains/paywall/hooks/README.md +34 -122
- package/src/domains/wallet/README.md +34 -275
- package/src/domains/wallet/README.md.bak +209 -0
- package/src/domains/wallet/domain/README.md +34 -101
- package/src/domains/wallet/domain/entities/README.md +34 -115
- package/src/domains/wallet/domain/errors/README.md +34 -151
- package/src/domains/wallet/infrastructure/README.md +34 -89
- package/src/domains/wallet/presentation/components/README.md +34 -224
- package/src/domains/wallet/presentation/hooks/README.md +34 -248
- package/src/infrastructure/README.md +37 -496
- package/src/infrastructure/mappers/README.md +0 -13
- package/src/infrastructure/repositories/README.md +74 -360
- package/src/infrastructure/services/README.md +95 -370
- package/src/presentation/README.md +123 -408
- package/src/presentation/README.md.bak +172 -0
- package/src/presentation/components/README.md +151 -179
- package/src/presentation/components/README.md.bak +217 -0
- package/src/presentation/components/details/CreditRow.md +65 -310
- package/src/presentation/components/details/DetailRow.md +63 -255
- package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
- package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
- package/src/presentation/components/details/README.md +97 -447
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
- package/src/presentation/components/feedback/README.md +97 -445
- package/src/presentation/components/paywall/PaywallModal.md +66 -416
- package/src/presentation/components/paywall/README.md +50 -186
- package/src/presentation/components/sections/README.md +97 -466
- package/src/presentation/components/sections/SubscriptionSection.md +92 -244
- package/src/presentation/hooks/README.md +154 -741
- package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
- package/src/presentation/hooks/useAuthGate.md +61 -375
- package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
- package/src/presentation/hooks/useCreditChecker.md +73 -378
- package/src/presentation/hooks/useCredits.md +74 -313
- package/src/presentation/hooks/useCredits.md.bak +231 -0
- package/src/presentation/hooks/useCreditsGate.md +66 -318
- package/src/presentation/hooks/useDeductCredit.md +96 -156
- package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
- package/src/presentation/hooks/useFeatureGate.md +105 -150
- package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
- package/src/presentation/hooks/useInitializeCredits.md +64 -430
- package/src/presentation/hooks/usePaywall.md +61 -306
- package/src/presentation/hooks/usePaywallOperations.md +64 -458
- package/src/presentation/hooks/usePaywallVisibility.md +67 -316
- package/src/presentation/hooks/usePremium.md +84 -226
- package/src/presentation/hooks/usePremiumGate.md +60 -395
- package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
- package/src/presentation/hooks/useSubscription.md +66 -422
- package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
- package/src/presentation/hooks/useSubscriptionGate.md +80 -164
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
- package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
- package/src/presentation/hooks/useUserTier.md +63 -328
- package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
- package/src/presentation/screens/README.md +48 -190
- package/src/presentation/types/README.md +0 -16
- package/src/presentation/utils/README.md +0 -21
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +43 -0
- package/src/revenuecat/application/ports/README.md +41 -0
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +41 -0
- package/src/revenuecat/domain/entities/README.md +42 -0
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +41 -0
- package/src/revenuecat/domain/value-objects/README.md +41 -0
- package/src/revenuecat/infrastructure/README.md +41 -0
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +41 -0
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +42 -0
- package/src/revenuecat/infrastructure/utils/README.md +41 -0
- package/src/revenuecat/presentation/README.md +42 -0
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
package/src/revenuecat/README.md
CHANGED
|
@@ -1,523 +1,104 @@
|
|
|
1
1
|
# RevenueCat Integration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Comprehensive integration and API wrapper for subscription management with RevenueCat.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Location
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **Customer Info**: Kullanıcı abonelik bilgilerini takip
|
|
12
|
-
- **Error Handling**: RevenueCat hatalarını yönetme
|
|
7
|
+
- **Base Path**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/revenuecat/`
|
|
8
|
+
- **Domain**: `src/revenuecat/domain/`
|
|
9
|
+
- **Infrastructure**: `src/revenuecat/infrastructure/`
|
|
10
|
+
- **Presentation**: `src/revenuecat/presentation/`
|
|
13
11
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
###
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<View>
|
|
109
|
-
<Text>
|
|
110
|
-
Status: {entitlement ? 'Premium' : 'Free'}
|
|
111
|
-
</Text>
|
|
112
|
-
{entitlement && (
|
|
113
|
-
<Text>
|
|
114
|
-
Expires: {new Date(entitlement.expirationDate).toLocaleDateString()}
|
|
115
|
-
</Text>
|
|
116
|
-
)}
|
|
117
|
-
<Button onPress={refetch} title="Refresh" />
|
|
118
|
-
</View>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### useInitializeSubscription
|
|
124
|
-
|
|
125
|
-
Başlatma durumu kontrolü için:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { useInitializeSubscription } from '@umituz/react-native-subscription';
|
|
129
|
-
|
|
130
|
-
function InitCheck() {
|
|
131
|
-
const {
|
|
132
|
-
isInitialized,
|
|
133
|
-
isInitializing,
|
|
134
|
-
error,
|
|
135
|
-
initialize,
|
|
136
|
-
} = useInitializeSubscription();
|
|
137
|
-
|
|
138
|
-
useEffect(() => {
|
|
139
|
-
if (!isInitialized && !isInitializing) {
|
|
140
|
-
initialize();
|
|
141
|
-
}
|
|
142
|
-
}, []);
|
|
143
|
-
|
|
144
|
-
if (isInitializing) {
|
|
145
|
-
return <Text>Initializing...</Text>;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (error) {
|
|
149
|
-
return <Text>Error: {error.message}</Text>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return <Text>Ready!</Text>;
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### useSubscriptionPackages
|
|
157
|
-
|
|
158
|
-
Mevcut abonelik paketleri için:
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
import { useSubscriptionPackages } from '@umituz/react-native-subscription';
|
|
162
|
-
|
|
163
|
-
function PackageList() {
|
|
164
|
-
const {
|
|
165
|
-
packages,
|
|
166
|
-
offerings,
|
|
167
|
-
isLoading,
|
|
168
|
-
error,
|
|
169
|
-
} = useSubscriptionPackages({
|
|
170
|
-
offeringId: 'default',
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
if (isLoading) return <ActivityIndicator />;
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<ScrollView>
|
|
177
|
-
{packages.map((pkg) => (
|
|
178
|
-
<PackageCard
|
|
179
|
-
key={pkg.identifier}
|
|
180
|
-
package={pkg}
|
|
181
|
-
onPress={() => handlePurchase(pkg)}
|
|
182
|
-
/>
|
|
183
|
-
))}
|
|
184
|
-
</ScrollView>
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### usePaywallFlow
|
|
190
|
-
|
|
191
|
-
Tam paywall flow'u için:
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
import { usePaywallFlow } from '@umituz/react-native-subscription';
|
|
195
|
-
|
|
196
|
-
function Paywall() {
|
|
197
|
-
const {
|
|
198
|
-
packages,
|
|
199
|
-
selectedPackage,
|
|
200
|
-
isLoading,
|
|
201
|
-
error,
|
|
202
|
-
selectPackage,
|
|
203
|
-
purchaseSelectedPackage,
|
|
204
|
-
restorePurchases,
|
|
205
|
-
} = usePaywallFlow();
|
|
206
|
-
|
|
207
|
-
const handlePurchase = async () => {
|
|
208
|
-
try {
|
|
209
|
-
const result = await purchaseSelectedPackage();
|
|
210
|
-
|
|
211
|
-
if (result.success) {
|
|
212
|
-
Alert.alert('Success', 'You are now a premium user!');
|
|
213
|
-
} else {
|
|
214
|
-
Alert.alert('Error', result.error?.message);
|
|
215
|
-
}
|
|
216
|
-
} catch (err) {
|
|
217
|
-
Alert.alert('Error', 'Purchase failed');
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
return (
|
|
222
|
-
<View>
|
|
223
|
-
{packages.map((pkg) => (
|
|
224
|
-
<TouchableOpacity
|
|
225
|
-
key={pkg.identifier}
|
|
226
|
-
onPress={() => selectPackage(pkg)}
|
|
227
|
-
style={selectedPackage?.identifier === pkg.identifier &&
|
|
228
|
-
styles.selected
|
|
229
|
-
}
|
|
230
|
-
>
|
|
231
|
-
<Text>{pkg.product.title}</Text>
|
|
232
|
-
<Text>{pkg.product.priceString}</Text>
|
|
233
|
-
</TouchableOpacity>
|
|
234
|
-
))}
|
|
235
|
-
|
|
236
|
-
<Button
|
|
237
|
-
onPress={handlePurchase}
|
|
238
|
-
disabled={!selectedPackage || isLoading}
|
|
239
|
-
title="Subscribe"
|
|
240
|
-
/>
|
|
241
|
-
|
|
242
|
-
<Button
|
|
243
|
-
onPress={restorePurchases}
|
|
244
|
-
disabled={isLoading}
|
|
245
|
-
title="Restore"
|
|
246
|
-
/>
|
|
247
|
-
</View>
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
### useRestorePurchase
|
|
253
|
-
|
|
254
|
-
Satın alma geri yükleme için:
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
import { useRestorePurchase } from '@umituz/react-native-subscription';
|
|
258
|
-
|
|
259
|
-
function RestoreButton() {
|
|
260
|
-
const { restorePurchase, isLoading, error, isRestored } = useRestorePurchase();
|
|
261
|
-
|
|
262
|
-
const handleRestore = async () => {
|
|
263
|
-
const result = await restorePurchase();
|
|
264
|
-
|
|
265
|
-
if (result.success) {
|
|
266
|
-
Alert.alert('Success', 'Purchase restored!');
|
|
267
|
-
} else {
|
|
268
|
-
Alert.alert('Error', result.error?.message || 'Restore failed');
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<Button
|
|
274
|
-
onPress={handleRestore}
|
|
275
|
-
disabled={isLoading}
|
|
276
|
-
title={isLoading ? 'Restoring...' : 'Restore Purchase'}
|
|
277
|
-
/>
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## Hata Yönetimi
|
|
283
|
-
|
|
284
|
-
### RevenueCatError
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
import {
|
|
288
|
-
RevenueCatError,
|
|
289
|
-
ErrorCode,
|
|
290
|
-
handleRevenueCatError,
|
|
291
|
-
} from '@umituz/react-native-subscription';
|
|
292
|
-
|
|
293
|
-
try {
|
|
294
|
-
await purchasePackage(packageToPurchase);
|
|
295
|
-
} catch (error) {
|
|
296
|
-
if (error instanceof RevenueCatError) {
|
|
297
|
-
switch (error.code) {
|
|
298
|
-
case ErrorCode.PurchaseCancelledError:
|
|
299
|
-
console.log('User cancelled');
|
|
300
|
-
break;
|
|
301
|
-
case ErrorCode.PurchaseInvalidError:
|
|
302
|
-
console.log('Invalid purchase');
|
|
303
|
-
break;
|
|
304
|
-
case ErrorCode.NetworkError:
|
|
305
|
-
console.log('Network error');
|
|
306
|
-
break;
|
|
307
|
-
default:
|
|
308
|
-
handleRevenueCatError(error);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
## User ID Yönetimi
|
|
315
|
-
|
|
316
|
-
### Auth ile Entegrasyon
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
import { useAuthSubscriptionSync } from '@umituz/react-native-subscription';
|
|
320
|
-
|
|
321
|
-
function AuthSync() {
|
|
322
|
-
const { user } = useAuth();
|
|
323
|
-
const { syncUserId, clearUserId } = useAuthSubscriptionSync();
|
|
324
|
-
|
|
325
|
-
useEffect(() => {
|
|
326
|
-
if (user?.uid) {
|
|
327
|
-
// Kullanıcı giriş yaptığında
|
|
328
|
-
syncUserId(user.uid);
|
|
329
|
-
} else {
|
|
330
|
-
// Kullanıcı çıkış yaptığında
|
|
331
|
-
clearUserId();
|
|
332
|
-
}
|
|
333
|
-
}, [user?.uid]);
|
|
334
|
-
|
|
335
|
-
return null;
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Manuel User ID
|
|
340
|
-
|
|
341
|
-
```typescript
|
|
342
|
-
import { configureUserId } from '@umituz/react-native-subscription';
|
|
343
|
-
|
|
344
|
-
// Kullanıcı giriş yaptığında
|
|
345
|
-
await configureUserId('user-123');
|
|
346
|
-
|
|
347
|
-
// Kullanıcı çıkış yaptığında
|
|
348
|
-
await configureUserId(null); // veya await resetUserId()
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## API Key Çözümleme
|
|
352
|
-
|
|
353
|
-
### Environment Bazlı API Keys
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
import {
|
|
357
|
-
ApiKeyResolver,
|
|
358
|
-
resolveApiKey,
|
|
359
|
-
} from '@umituz/react-native-subscription';
|
|
360
|
-
|
|
361
|
-
const apiKeyResolver = new ApiKeyResolver({
|
|
362
|
-
development: 'dev_api_key',
|
|
363
|
-
production: 'prod_api_key',
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
const apiKey = apiKeyResolver.resolve(__DEV__ ? 'development' : 'production');
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## SubscriptionManager
|
|
370
|
-
|
|
371
|
-
Gelişmiş işlemler için SubscriptionManager kullanımı:
|
|
372
|
-
|
|
373
|
-
```typescript
|
|
374
|
-
import { SubscriptionManager } from '@umituz/react-native-subscription';
|
|
375
|
-
|
|
376
|
-
const manager = new SubscriptionManager(config);
|
|
377
|
-
|
|
378
|
-
// Başlatma
|
|
379
|
-
await manager.initialize(userId);
|
|
380
|
-
|
|
381
|
-
// Satın alma
|
|
382
|
-
const result = await manager.purchasePackage(packageToPurchase);
|
|
383
|
-
|
|
384
|
-
// Geri yükleme
|
|
385
|
-
const restoreResult = await manager.restorePurchases();
|
|
386
|
-
|
|
387
|
-
// Customer info
|
|
388
|
-
const info = await manager.getCustomerInfo();
|
|
389
|
-
|
|
390
|
-
// Offerings
|
|
391
|
-
const offerings = await manager.getOfferings();
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
## Best Practices
|
|
395
|
-
|
|
396
|
-
1. **User ID Sync**: Auth sistemiyle user ID'leri her zaman senkronize edin
|
|
397
|
-
2. **Error Handling**: TümRevenueCat işlemlerinde hata yönetimi kullanın
|
|
398
|
-
3. **Loading States**: Kullanıcıya uygun loading feedback'i verin
|
|
399
|
-
4. **Restore**: Her zaman "Restore Purchase" seçeneği sunun
|
|
400
|
-
5. **Test Mode**: Geliştirme sırasında test mode kullanın
|
|
401
|
-
6. **Debug Mode**: Production'da debug modu kapalı tutun
|
|
402
|
-
|
|
403
|
-
## Örnek Uygulama
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
import React, { useEffect } from 'react';
|
|
407
|
-
import { View, Text, Button, ActivityIndicator } from 'react-native';
|
|
408
|
-
import {
|
|
409
|
-
usePaywallFlow,
|
|
410
|
-
useCustomerInfo,
|
|
411
|
-
useRestorePurchase,
|
|
412
|
-
} from '@umituz/react-native-subscription';
|
|
413
|
-
|
|
414
|
-
export default function SubscriptionScreen() {
|
|
415
|
-
const {
|
|
416
|
-
packages,
|
|
417
|
-
selectedPackage,
|
|
418
|
-
isLoading,
|
|
419
|
-
selectPackage,
|
|
420
|
-
purchaseSelectedPackage,
|
|
421
|
-
} = usePaywallFlow();
|
|
422
|
-
|
|
423
|
-
const { customerInfo, isLoading: infoLoading } = useCustomerInfo();
|
|
424
|
-
const { restorePurchase } = useRestorePurchase();
|
|
425
|
-
|
|
426
|
-
const entitlement = customerInfo?.entitlements.active['premium'];
|
|
427
|
-
|
|
428
|
-
const handleSubscribe = async () => {
|
|
429
|
-
if (!selectedPackage) return;
|
|
430
|
-
|
|
431
|
-
try {
|
|
432
|
-
const result = await purchaseSelectedPackage();
|
|
433
|
-
|
|
434
|
-
if (result.success) {
|
|
435
|
-
Alert.alert('Success', 'Welcome to Premium!');
|
|
436
|
-
} else {
|
|
437
|
-
Alert.alert('Error', result.error?.message || 'Purchase failed');
|
|
438
|
-
}
|
|
439
|
-
} catch (error) {
|
|
440
|
-
Alert.alert('Error', 'Something went wrong');
|
|
441
|
-
}
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
if (isLoading || infoLoading) {
|
|
445
|
-
return <ActivityIndicator />;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return (
|
|
449
|
-
<View>
|
|
450
|
-
{entitlement ? (
|
|
451
|
-
<>
|
|
452
|
-
<Text>You are Premium!</Text>
|
|
453
|
-
<Text>
|
|
454
|
-
Expires: {new Date(entitlement.expirationDate).toLocaleDateString()}
|
|
455
|
-
</Text>
|
|
456
|
-
</>
|
|
457
|
-
) : (
|
|
458
|
-
<>
|
|
459
|
-
<Text>Choose your plan:</Text>
|
|
460
|
-
{packages.map((pkg) => (
|
|
461
|
-
<TouchableOpacity
|
|
462
|
-
key={pkg.identifier}
|
|
463
|
-
onPress={() => selectPackage(pkg)}
|
|
464
|
-
style={
|
|
465
|
-
selectedPackage?.identifier === pkg.identifier &&
|
|
466
|
-
styles.selected
|
|
467
|
-
}
|
|
468
|
-
>
|
|
469
|
-
<Text>{pkg.product.title}</Text>
|
|
470
|
-
<Text>{pkg.product.priceString}</Text>
|
|
471
|
-
<Text>{pkg.product.description}</Text>
|
|
472
|
-
</TouchableOpacity>
|
|
473
|
-
))}
|
|
474
|
-
|
|
475
|
-
<Button
|
|
476
|
-
onPress={handleSubscribe}
|
|
477
|
-
disabled={!selectedPackage || isLoading}
|
|
478
|
-
title="Subscribe"
|
|
479
|
-
/>
|
|
480
|
-
|
|
481
|
-
<Button onPress={restorePurchase} title="Restore" />
|
|
482
|
-
</>
|
|
483
|
-
)}
|
|
484
|
-
</View>
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
## Tip Tanımlamaları
|
|
490
|
-
|
|
491
|
-
```typescript
|
|
492
|
-
interface RevenueCatConfig {
|
|
493
|
-
apiKey: string;
|
|
494
|
-
entitlements: {
|
|
495
|
-
premium: string;
|
|
496
|
-
};
|
|
497
|
-
userDefaultsSuiteName?: string;
|
|
498
|
-
diagnosticsEnabled?: boolean;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
interface PurchaseResult {
|
|
502
|
-
success: boolean;
|
|
503
|
-
error?: Error;
|
|
504
|
-
customerInfo?: CustomerInfo;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
interface CustomerInfo {
|
|
508
|
-
entitlements: {
|
|
509
|
-
active: Record<string, EntitlementInfo>;
|
|
510
|
-
all: Record<string, EntitlementInfo>;
|
|
511
|
-
};
|
|
512
|
-
activeSubscriptions: string[];
|
|
513
|
-
allPurchasedProductIdentifiers: string[];
|
|
514
|
-
latestExpirationDate: string;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
interface Package {
|
|
518
|
-
identifier: string;
|
|
519
|
-
packageType: PACKAGE_TYPE;
|
|
520
|
-
product: Product;
|
|
521
|
-
offeringIdentifier: string;
|
|
522
|
-
}
|
|
523
|
-
```
|
|
12
|
+
## Strategy
|
|
13
|
+
|
|
14
|
+
### RevenueCat SDK Integration
|
|
15
|
+
|
|
16
|
+
Seamless RevenueCat SDK initialization and configuration.
|
|
17
|
+
|
|
18
|
+
- **Automatic Initialization**: SDK startup and configuration
|
|
19
|
+
- **User ID Management**: Auth system integration
|
|
20
|
+
- **Purchase Flow**: Managed purchase operations
|
|
21
|
+
- **Restore Operations**: Purchase restoration support
|
|
22
|
+
- **Error Handling**: RevenueCat error management
|
|
23
|
+
|
|
24
|
+
### Hook Architecture
|
|
25
|
+
|
|
26
|
+
React hooks for RevenueCat functionality.
|
|
27
|
+
|
|
28
|
+
- **useRevenueCat**: Core RevenueCat access
|
|
29
|
+
- **useCustomerInfo**: Subscription information tracking
|
|
30
|
+
- **useInitializeSubscription**: Initialization status monitoring
|
|
31
|
+
- **useSubscriptionPackages**: Package listing and selection
|
|
32
|
+
- **usePaywallFlow**: Complete paywall flow management
|
|
33
|
+
- **useRestorePurchase**: Purchase restoration
|
|
34
|
+
|
|
35
|
+
### State Management
|
|
36
|
+
|
|
37
|
+
Customer info and subscription state tracking.
|
|
38
|
+
|
|
39
|
+
- **Customer Info Tracking**: Real-time subscription updates
|
|
40
|
+
- **Offerings Management**: Package offering configuration
|
|
41
|
+
- **Purchase State**: Purchase operation states
|
|
42
|
+
- **Error States**: Comprehensive error handling
|
|
43
|
+
|
|
44
|
+
### User ID Synchronization
|
|
45
|
+
|
|
46
|
+
Auth system integration for user management.
|
|
47
|
+
|
|
48
|
+
- **Auth Sync**: Automatic user ID synchronization
|
|
49
|
+
- **Login/Logout**: User ID management on auth changes
|
|
50
|
+
- **Anonymous Users**: Anonymous user support
|
|
51
|
+
- **Migration**: User migration support
|
|
52
|
+
|
|
53
|
+
## Restrictions
|
|
54
|
+
|
|
55
|
+
### REQUIRED
|
|
56
|
+
|
|
57
|
+
- **Initialization**: Must initialize before any operations
|
|
58
|
+
- **User ID Sync**: Sync user IDs with auth system
|
|
59
|
+
- **Error Handling**: All operations must handle errors
|
|
60
|
+
- **Loading States**: Show appropriate loading indicators
|
|
61
|
+
|
|
62
|
+
### PROHIBITED
|
|
63
|
+
|
|
64
|
+
- **Direct SDK Calls**: Use hooks instead of direct RevenueCat calls
|
|
65
|
+
- **Missing User IDs**: Operations require valid user IDs
|
|
66
|
+
- **Uninitialized Access**: Don't call methods before initialization
|
|
67
|
+
- **Ignoring Errors**: All errors must be handled
|
|
68
|
+
|
|
69
|
+
### CRITICAL
|
|
70
|
+
|
|
71
|
+
- **API Key Security**: Never expose API keys in client code
|
|
72
|
+
- **User ID Consistency**: Maintain consistent user IDs
|
|
73
|
+
- **Purchase Validation**: Validate all purchase results
|
|
74
|
+
- **Entitlement Check**: Always verify entitlements
|
|
75
|
+
|
|
76
|
+
## AI Agent Guidelines
|
|
77
|
+
|
|
78
|
+
### When Modifying RevenueCat Integration
|
|
79
|
+
|
|
80
|
+
1. **SDK Version**: Check RevenueCat SDK version compatibility
|
|
81
|
+
2. **Type Definitions**: Update TypeScript types
|
|
82
|
+
3. **Error Handling**: Maintain comprehensive error handling
|
|
83
|
+
4. **Testing**: Test with different subscription states
|
|
84
|
+
|
|
85
|
+
### When Adding New Hooks
|
|
86
|
+
|
|
87
|
+
1. **Hook Pattern**: Follow existing hook patterns
|
|
88
|
+
2. **State Management**: Proper state management
|
|
89
|
+
3. **Error Handling**: Comprehensive error handling
|
|
90
|
+
4. **Documentation**: Document hook usage and return values
|
|
91
|
+
|
|
92
|
+
### When Fixing RevenueCat Bugs
|
|
93
|
+
|
|
94
|
+
1. **SDK Integration**: Check RevenueCat SDK integration
|
|
95
|
+
2. **State Updates**: Verify state update mechanisms
|
|
96
|
+
3. **User ID**: Verify user ID consistency
|
|
97
|
+
4. **Purchase Flow**: Test complete purchase flows
|
|
98
|
+
|
|
99
|
+
## Related Documentation
|
|
100
|
+
|
|
101
|
+
- [Paywall Domain](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/domains/paywall/README.md)
|
|
102
|
+
- [Config Domain](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/domains/config/README.md)
|
|
103
|
+
- [Infrastructure Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/infrastructure/README.md)
|
|
104
|
+
- [Application Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/application/README.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# RevenueCat Application Layer
|
|
2
|
+
|
|
3
|
+
## Location
|
|
4
|
+
Application layer for RevenueCat integration, containing use cases and orchestration logic.
|
|
5
|
+
|
|
6
|
+
## Strategy
|
|
7
|
+
This directory contains use cases and application-level operations for managing RevenueCat subscriptions and purchases with proper error handling and state synchronization.
|
|
8
|
+
|
|
9
|
+
## Restrictions
|
|
10
|
+
|
|
11
|
+
### REQUIRED
|
|
12
|
+
- Must handle RevenueCat errors gracefully
|
|
13
|
+
- Must provide user ID when available
|
|
14
|
+
- Must use entitlements instead of product IDs
|
|
15
|
+
- Must keep local state synchronized
|
|
16
|
+
|
|
17
|
+
### PROHIBITED
|
|
18
|
+
- DO NOT ignore RevenueCat errors
|
|
19
|
+
- DO NOT skip user ID provision
|
|
20
|
+
- DO NOT use product IDs directly
|
|
21
|
+
- DO NOT allow state desynchronization
|
|
22
|
+
|
|
23
|
+
### CRITICAL SAFETY
|
|
24
|
+
- All errors MUST be handled gracefully
|
|
25
|
+
- User IDs MUST be provided when available
|
|
26
|
+
- Entitlements MUST be used for flexibility
|
|
27
|
+
- Local state MUST stay synchronized
|
|
28
|
+
|
|
29
|
+
## AI Agent Guidelines
|
|
30
|
+
1. Always handle RevenueCat errors with proper recovery
|
|
31
|
+
2. Provide user ID when available for better tracking
|
|
32
|
+
3. Use entitlements instead of product IDs for flexibility
|
|
33
|
+
4. Check if offerings are available before purchasing
|
|
34
|
+
5. Validate customer info after purchases
|
|
35
|
+
6. Keep local state synchronized with RevenueCat
|
|
36
|
+
7. Handle network timeouts appropriately
|
|
37
|
+
8. Log all RevenueCat operations for debugging
|
|
38
|
+
|
|
39
|
+
## Related Documentation
|
|
40
|
+
- [RevenueCat Integration](../README.md)
|
|
41
|
+
- [RevenueCat Domain](../domain/README.md)
|
|
42
|
+
- [RevenueCat Infrastructure](../infrastructure/README.md)
|
|
43
|
+
- [Application Ports](./ports/README.md)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# RevenueCat Application Ports
|
|
2
|
+
|
|
3
|
+
## Location
|
|
4
|
+
Interface definitions for RevenueCat service layer.
|
|
5
|
+
|
|
6
|
+
## Strategy
|
|
7
|
+
This directory defines the ports (interfaces) that the RevenueCat infrastructure must implement, following the Dependency Inversion Principle for testability and flexibility.
|
|
8
|
+
|
|
9
|
+
## Restrictions
|
|
10
|
+
|
|
11
|
+
### REQUIRED
|
|
12
|
+
- Must define clear interfaces for all operations
|
|
13
|
+
- Must support mocking for testing
|
|
14
|
+
- Must enable implementation swapping
|
|
15
|
+
- Must maintain contracts between layers
|
|
16
|
+
|
|
17
|
+
### PROHIBITED
|
|
18
|
+
- DO NOT depend on concrete implementations
|
|
19
|
+
- DO NOT create interfaces without clear purpose
|
|
20
|
+
- DO NOT break interface contracts
|
|
21
|
+
- DO NOT couple application to infrastructure
|
|
22
|
+
|
|
23
|
+
### CRITICAL SAFETY
|
|
24
|
+
- All dependencies MUST be inverted
|
|
25
|
+
- Interfaces MUST be clearly defined
|
|
26
|
+
- Implementations MUST be swappable
|
|
27
|
+
- Contracts MUST be maintained
|
|
28
|
+
|
|
29
|
+
## AI Agent Guidelines
|
|
30
|
+
1. Define clear interfaces for all RevenueCat operations
|
|
31
|
+
2. Design interfaces for easy mocking in tests
|
|
32
|
+
3. Enable implementation swapping when needed
|
|
33
|
+
4. Keep application layer decoupled from infrastructure
|
|
34
|
+
5. Maintain clear contracts between layers
|
|
35
|
+
6. Document interface behavior thoroughly
|
|
36
|
+
7. Test with mock implementations
|
|
37
|
+
|
|
38
|
+
## Related Documentation
|
|
39
|
+
- [RevenueCat Application Layer](../README.md)
|
|
40
|
+
- [RevenueCat Infrastructure](../infrastructure/README.md)
|
|
41
|
+
- [RevenueCat Domain](../domain/README.md)
|