@umituz/react-native-subscription 2.14.97 → 2.14.99
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/LICENSE +21 -0
- package/README.md +461 -0
- package/package.json +1 -3
- package/src/application/README.md +229 -0
- package/src/application/ports/README.md +103 -0
- package/src/domain/README.md +402 -0
- package/src/domain/constants/README.md +80 -0
- package/src/domain/entities/README.md +176 -0
- package/src/domain/errors/README.md +307 -0
- package/src/domain/value-objects/README.md +186 -0
- package/src/domains/README.md +240 -0
- package/src/domains/config/README.md +390 -0
- package/src/domains/config/domain/README.md +390 -0
- package/src/domains/config/domain/entities/README.md +350 -0
- package/src/domains/paywall/README.md +371 -0
- package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
- package/src/domains/paywall/components/README.md +185 -0
- package/src/domains/paywall/entities/README.md +199 -0
- package/src/domains/paywall/hooks/README.md +129 -0
- package/src/domains/wallet/README.md +292 -0
- package/src/domains/wallet/domain/README.md +108 -0
- package/src/domains/wallet/domain/entities/README.md +122 -0
- package/src/domains/wallet/domain/errors/README.md +157 -0
- package/src/domains/wallet/infrastructure/README.md +96 -0
- package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
- package/src/domains/wallet/presentation/components/README.md +231 -0
- package/src/domains/wallet/presentation/hooks/README.md +255 -0
- package/src/infrastructure/README.md +514 -0
- package/src/infrastructure/mappers/README.md +34 -0
- package/src/infrastructure/models/README.md +26 -0
- package/src/infrastructure/repositories/README.md +385 -0
- package/src/infrastructure/services/README.md +374 -0
- package/src/presentation/README.md +410 -0
- package/src/presentation/components/README.md +183 -0
- package/src/presentation/components/details/CreditRow.md +337 -0
- package/src/presentation/components/details/DetailRow.md +283 -0
- package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
- package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
- package/src/presentation/components/details/README.md +449 -0
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
- package/src/presentation/components/feedback/README.md +447 -0
- package/src/presentation/components/paywall/PaywallModal.md +444 -0
- package/src/presentation/components/paywall/README.md +190 -0
- package/src/presentation/components/sections/README.md +468 -0
- package/src/presentation/components/sections/SubscriptionSection.md +246 -0
- package/src/presentation/hooks/README.md +743 -0
- package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
- package/src/presentation/hooks/useAuthGate.md +403 -0
- package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
- package/src/presentation/hooks/useCreditChecker.md +407 -0
- package/src/presentation/hooks/useCredits.md +342 -0
- package/src/presentation/hooks/useCreditsGate.md +346 -0
- package/src/presentation/hooks/useDeductCredit.md +176 -0
- package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
- package/src/presentation/hooks/useFeatureGate.md +157 -0
- package/src/presentation/hooks/useInitializeCredits.md +458 -0
- package/src/presentation/hooks/usePaywall.md +334 -0
- package/src/presentation/hooks/usePaywallOperations.md +486 -0
- package/src/presentation/hooks/usePaywallVisibility.md +344 -0
- package/src/presentation/hooks/usePremium.md +230 -0
- package/src/presentation/hooks/usePremiumGate.md +423 -0
- package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
- package/src/presentation/hooks/useSubscription.md +450 -0
- package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
- package/src/presentation/hooks/useSubscriptionGate.md +168 -0
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
- package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
- package/src/presentation/hooks/useUserTier.md +356 -0
- package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
- package/src/presentation/screens/README.md +194 -0
- package/src/presentation/types/README.md +38 -0
- package/src/presentation/utils/README.md +52 -0
- package/src/revenuecat/README.md +523 -0
- package/src/revenuecat/application/README.md +158 -0
- package/src/revenuecat/application/ports/README.md +169 -0
- package/src/revenuecat/domain/README.md +147 -0
- package/src/revenuecat/domain/constants/README.md +183 -0
- package/src/revenuecat/domain/entities/README.md +382 -0
- package/src/revenuecat/domain/errors/README.md +197 -0
- package/src/revenuecat/domain/types/README.md +373 -0
- package/src/revenuecat/domain/value-objects/README.md +441 -0
- package/src/revenuecat/infrastructure/README.md +50 -0
- package/src/revenuecat/infrastructure/config/README.md +40 -0
- package/src/revenuecat/infrastructure/handlers/README.md +218 -0
- package/src/revenuecat/infrastructure/managers/README.md +49 -0
- package/src/revenuecat/infrastructure/services/README.md +325 -0
- package/src/revenuecat/infrastructure/utils/README.md +382 -0
- package/src/revenuecat/presentation/README.md +184 -0
- package/src/revenuecat/presentation/hooks/README.md +56 -0
- package/src/utils/README.md +529 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Config Domain Entities
|
|
2
|
+
|
|
3
|
+
Domain entities for configuration management.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This directory contains entity classes representing configuration concepts like packages, features, and paywalls.
|
|
8
|
+
|
|
9
|
+
## Entities
|
|
10
|
+
|
|
11
|
+
### PackageConfig
|
|
12
|
+
|
|
13
|
+
Represents a subscription package configuration.
|
|
14
|
+
|
|
15
|
+
**File**: `PackageConfig.ts`
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
class PackageConfig {
|
|
19
|
+
readonly identifier: string;
|
|
20
|
+
readonly productId: string;
|
|
21
|
+
readonly period: PackagePeriod;
|
|
22
|
+
readonly price: Money;
|
|
23
|
+
readonly features: string[];
|
|
24
|
+
readonly credits?: number;
|
|
25
|
+
readonly metadata: PackageMetadata;
|
|
26
|
+
|
|
27
|
+
// Methods
|
|
28
|
+
isAnnual(): boolean;
|
|
29
|
+
isMonthly(): boolean;
|
|
30
|
+
isLifetime(): boolean;
|
|
31
|
+
hasCredits(): boolean;
|
|
32
|
+
isRecommended(): boolean;
|
|
33
|
+
isHighlighted(): boolean;
|
|
34
|
+
getPerMonthPrice(): Money | null;
|
|
35
|
+
getDiscountPercentage(): number | null;
|
|
36
|
+
getBadge(): string | null;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Usage:**
|
|
41
|
+
```typescript
|
|
42
|
+
const pkg = new PackageConfig({
|
|
43
|
+
identifier: 'premium_annual',
|
|
44
|
+
productId: 'com.app.premium.annual',
|
|
45
|
+
period: 'annual',
|
|
46
|
+
price: 79.99,
|
|
47
|
+
currency: 'USD',
|
|
48
|
+
features: ['Unlimited Access', 'Ad-Free'],
|
|
49
|
+
credits: 1200,
|
|
50
|
+
metadata: {
|
|
51
|
+
recommended: true,
|
|
52
|
+
badge: 'Best Value',
|
|
53
|
+
discount: { percentage: 20, description: 'Save 20%' },
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
console.log(pkg.isAnnual()); // true
|
|
58
|
+
console.log(pkg.getPerMonthPrice()?.format()); // '$6.67'
|
|
59
|
+
console.log(pkg.getDiscountPercentage()); // 20
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### FeatureConfig
|
|
63
|
+
|
|
64
|
+
Represents a feature configuration with gating rules.
|
|
65
|
+
|
|
66
|
+
**File**: `FeatureConfig.ts`
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
class FeatureConfig {
|
|
70
|
+
readonly id: string;
|
|
71
|
+
readonly name: string;
|
|
72
|
+
readonly description?: string;
|
|
73
|
+
readonly requiresPremium: boolean;
|
|
74
|
+
readonly requiresCredits: boolean;
|
|
75
|
+
readonly creditCost?: number;
|
|
76
|
+
readonly enabled: boolean;
|
|
77
|
+
readonly gateType: 'premium' | 'credits' | 'both';
|
|
78
|
+
|
|
79
|
+
// Methods
|
|
80
|
+
isAccessible(userHasPremium: boolean, userCredits: number): boolean;
|
|
81
|
+
getRequiredCredits(): number;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Usage:**
|
|
86
|
+
```typescript
|
|
87
|
+
const feature = new FeatureConfig({
|
|
88
|
+
id: 'ai_generation',
|
|
89
|
+
name: 'AI Generation',
|
|
90
|
+
requiresPremium: false,
|
|
91
|
+
requiresCredits: true,
|
|
92
|
+
creditCost: 5,
|
|
93
|
+
enabled: true,
|
|
94
|
+
gateType: 'credits',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log(feature.isAccessible(false, 10)); // true
|
|
98
|
+
console.log(feature.isAccessible(false, 3)); // false
|
|
99
|
+
console.log(feature.getRequiredCredits()); // 5
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### PaywallConfig
|
|
103
|
+
|
|
104
|
+
Represents a paywall screen configuration.
|
|
105
|
+
|
|
106
|
+
**File**: `PaywallConfig.ts`
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
class PaywallConfig {
|
|
110
|
+
readonly id: string;
|
|
111
|
+
readonly title: string;
|
|
112
|
+
readonly subtitle?: string;
|
|
113
|
+
readonly features: string[];
|
|
114
|
+
readonly packages: PackageConfig[];
|
|
115
|
+
readonly highlightPackage?: string;
|
|
116
|
+
readonly style: PaywallStyle;
|
|
117
|
+
readonly triggers: PaywallTrigger[];
|
|
118
|
+
|
|
119
|
+
// Methods
|
|
120
|
+
getHighlightedPackage(): PackageConfig | null;
|
|
121
|
+
getPackageByIdentifier(identifier: string): PackageConfig | null;
|
|
122
|
+
shouldTrigger(triggerType: string): boolean;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Usage:**
|
|
127
|
+
```typescript
|
|
128
|
+
const paywall = new PaywallConfig({
|
|
129
|
+
id: 'premium_upgrade',
|
|
130
|
+
title: 'Upgrade to Premium',
|
|
131
|
+
features: ['Unlimited Access', 'Ad-Free'],
|
|
132
|
+
packages: [monthlyPkg, annualPkg],
|
|
133
|
+
highlightPackage: 'premium_annual',
|
|
134
|
+
style: {
|
|
135
|
+
primaryColor: '#007AFF',
|
|
136
|
+
backgroundColor: '#FFFFFF',
|
|
137
|
+
},
|
|
138
|
+
triggers: [{ type: 'credit_gate', enabled: true }],
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const highlighted = paywall.getHighlightedPackage();
|
|
142
|
+
console.log(highlighted?.identifier); // 'premium_annual'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### SubscriptionSettingsConfig
|
|
146
|
+
|
|
147
|
+
Represents subscription settings configuration.
|
|
148
|
+
|
|
149
|
+
**File**: `SubscriptionSettingsConfig.ts`
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
class SubscriptionSettingsConfig {
|
|
153
|
+
readonly showSubscriptionDetails: boolean;
|
|
154
|
+
readonly showCreditBalance: boolean;
|
|
155
|
+
readonly allowRestorePurchases: boolean;
|
|
156
|
+
readonly showManageSubscriptionButton: boolean;
|
|
157
|
+
readonly subscriptionManagementURL: string;
|
|
158
|
+
readonly supportEmail: string;
|
|
159
|
+
|
|
160
|
+
// Methods
|
|
161
|
+
getAvailableActions(): string[];
|
|
162
|
+
isRestoreAllowed(): boolean;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Usage:**
|
|
167
|
+
```typescript
|
|
168
|
+
const settings = new SubscriptionSettingsConfig({
|
|
169
|
+
showSubscriptionDetails: true,
|
|
170
|
+
showCreditBalance: true,
|
|
171
|
+
allowRestorePurchases: true,
|
|
172
|
+
showManageSubscriptionButton: true,
|
|
173
|
+
subscriptionManagementURL: 'https://apps.apple.com/account/subscriptions',
|
|
174
|
+
supportEmail: 'support@example.com',
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
console.log(settings.isRestoreAllowed()); // true
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Supporting Types
|
|
181
|
+
|
|
182
|
+
### PackageMetadata
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface PackageMetadata {
|
|
186
|
+
highlight?: boolean;
|
|
187
|
+
recommended?: boolean;
|
|
188
|
+
discount?: {
|
|
189
|
+
percentage: number;
|
|
190
|
+
description: string;
|
|
191
|
+
};
|
|
192
|
+
badge?: string;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### PaywallStyle
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
interface PaywallStyle {
|
|
200
|
+
primaryColor: string;
|
|
201
|
+
backgroundColor: string;
|
|
202
|
+
textColor?: string;
|
|
203
|
+
image?: string;
|
|
204
|
+
logo?: string;
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### PaywallTrigger
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface PaywallTrigger {
|
|
212
|
+
type: string;
|
|
213
|
+
enabled: boolean;
|
|
214
|
+
conditions?: Record<string, unknown>;
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Factory Functions
|
|
219
|
+
|
|
220
|
+
### createDefaultPackages
|
|
221
|
+
|
|
222
|
+
Create default package configurations.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
function createDefaultPackages(): PackageConfig[] {
|
|
226
|
+
return [
|
|
227
|
+
new PackageConfig({
|
|
228
|
+
identifier: 'premium_monthly',
|
|
229
|
+
productId: 'com.app.premium.monthly',
|
|
230
|
+
period: 'monthly',
|
|
231
|
+
price: 9.99,
|
|
232
|
+
currency: 'USD',
|
|
233
|
+
features: ['Unlimited Access', 'Ad-Free'],
|
|
234
|
+
credits: 100,
|
|
235
|
+
}),
|
|
236
|
+
new PackageConfig({
|
|
237
|
+
identifier: 'premium_annual',
|
|
238
|
+
productId: 'com.app.premium.annual',
|
|
239
|
+
period: 'annual',
|
|
240
|
+
price: 79.99,
|
|
241
|
+
currency: 'USD',
|
|
242
|
+
features: ['Unlimited Access', 'Ad-Free', 'Save 20%'],
|
|
243
|
+
credits: 1200,
|
|
244
|
+
metadata: {
|
|
245
|
+
recommended: true,
|
|
246
|
+
badge: 'Best Value',
|
|
247
|
+
discount: { percentage: 20, description: 'Save 20%' },
|
|
248
|
+
},
|
|
249
|
+
}),
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### createDefaultPaywall
|
|
255
|
+
|
|
256
|
+
Create default paywall configuration.
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
function createDefaultPaywall(): PaywallConfig {
|
|
260
|
+
return new PaywallConfig({
|
|
261
|
+
id: 'default_paywall',
|
|
262
|
+
title: 'Upgrade to Premium',
|
|
263
|
+
subtitle: 'Get unlimited access to all features',
|
|
264
|
+
features: [
|
|
265
|
+
'Unlimited Access',
|
|
266
|
+
'Ad-Free Experience',
|
|
267
|
+
'Priority Support',
|
|
268
|
+
'Exclusive Features',
|
|
269
|
+
],
|
|
270
|
+
packages: createDefaultPackages(),
|
|
271
|
+
highlightPackage: 'premium_annual',
|
|
272
|
+
style: {
|
|
273
|
+
primaryColor: '#007AFF',
|
|
274
|
+
backgroundColor: '#FFFFFF',
|
|
275
|
+
},
|
|
276
|
+
triggers: [
|
|
277
|
+
{ type: 'premium_feature', enabled: true },
|
|
278
|
+
{ type: 'credit_gate', enabled: true },
|
|
279
|
+
],
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Usage Examples
|
|
285
|
+
|
|
286
|
+
### Validating Package Configuration
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
function validatePackage(config: PackageConfigData): boolean {
|
|
290
|
+
try {
|
|
291
|
+
new PackageConfig(config);
|
|
292
|
+
return true;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error('Invalid package config:', error.message);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Finding Recommended Package
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
function findRecommendedPackage(packages: PackageConfig[]): PackageConfig | null {
|
|
304
|
+
return packages.find(pkg => pkg.isRecommended()) ?? null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const recommended = findRecommendedPackage(packages);
|
|
308
|
+
console.log('Recommended:', recommended?.identifier);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Filtering Packages by Period
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
function getPackagesByPeriod(packages: PackageConfig[], period: 'monthly' | 'annual'): PackageConfig[] {
|
|
315
|
+
return packages.filter(pkg => {
|
|
316
|
+
if (period === 'monthly') return pkg.isMonthly();
|
|
317
|
+
if (period === 'annual') return pkg.isAnnual();
|
|
318
|
+
return false;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const monthlyPackages = getPackagesByPeriod(packages, 'monthly');
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Checking Feature Access
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
function canUserAccessFeature(feature: FeatureConfig, user: User): boolean {
|
|
329
|
+
return feature.isAccessible(user.isPremium, user.credits);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const aiFeature = new FeatureConfig({ /* ... */ });
|
|
333
|
+
const canAccess = canUserAccessFeature(aiFeature, currentUser);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Best Practices
|
|
337
|
+
|
|
338
|
+
1. **Validation**: Always validate configuration in constructor
|
|
339
|
+
2. **Immutability**: Never modify entities after creation
|
|
340
|
+
3. **Business Logic**: Keep business logic in entities
|
|
341
|
+
4. **Type Safety**: Use TypeScript strictly
|
|
342
|
+
5. **Error Messages**: Provide clear error messages
|
|
343
|
+
6. **Defaults**: Provide factory functions for defaults
|
|
344
|
+
7. **Testing**: Test validation logic thoroughly
|
|
345
|
+
|
|
346
|
+
## Related
|
|
347
|
+
|
|
348
|
+
- [Config Domain](../README.md)
|
|
349
|
+
- [Config Value Objects](../value-objects/README.md)
|
|
350
|
+
- [Config Utils](../../utils/README.md)
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# Paywall Domain
|
|
2
|
+
|
|
3
|
+
Abonelik ve kredi satın alımı için kullanıcı dostu ödeme duvarı (paywall) bileşenleri ve hooks.
|
|
4
|
+
|
|
5
|
+
## Özellikler
|
|
6
|
+
|
|
7
|
+
- **Hazır Paywall Bileşenleri**: Önceden tasarlanmış, özelleştirilebilir paywall UI'ları
|
|
8
|
+
- **Modal ve Full-Screen Desteği**: Modal veya tam ekran paywall seçenekleri
|
|
9
|
+
- **Çoklu Dil Desteği**: Built-in i18n desteği
|
|
10
|
+
- **A/B Test Hazır**: Farklı paywall varyantları kolayca oluşturulabilir
|
|
11
|
+
- **Analytics Entegrasyonu**: Kullanıcı davranışlarını takip edin
|
|
12
|
+
|
|
13
|
+
## Kurulum
|
|
14
|
+
|
|
15
|
+
### Temel Konfigürasyon
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { SubscriptionProvider } from '@umituz/react-native-subscription';
|
|
19
|
+
|
|
20
|
+
function App() {
|
|
21
|
+
return (
|
|
22
|
+
<SubscriptionProvider
|
|
23
|
+
config={{
|
|
24
|
+
revenueCatApiKey: 'your_api_key',
|
|
25
|
+
entitlementId: 'premium',
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
{/* Your app */}
|
|
29
|
+
</SubscriptionProvider>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Kullanım
|
|
35
|
+
|
|
36
|
+
### PaywallModal
|
|
37
|
+
|
|
38
|
+
Modal paywall gösterimi için:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { PaywallModal } from '@umituz/react-native-subscription';
|
|
42
|
+
|
|
43
|
+
function MyComponent() {
|
|
44
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<>
|
|
48
|
+
<Button onPress={() => setIsVisible(true)} title="Upgrade to Premium" />
|
|
49
|
+
|
|
50
|
+
<PaywallModal
|
|
51
|
+
isVisible={isVisible}
|
|
52
|
+
onClose={() => setIsVisible(false)}
|
|
53
|
+
config={{
|
|
54
|
+
title: 'Unlock Premium Features',
|
|
55
|
+
description: 'Get unlimited access to all features',
|
|
56
|
+
features: [
|
|
57
|
+
{ icon: 'star', text: 'Unlimited credits' },
|
|
58
|
+
{ icon: 'zap', text: 'AI-powered tools' },
|
|
59
|
+
{ icon: 'shield', text: 'Ad-free experience' },
|
|
60
|
+
],
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### usePaywall Hook
|
|
69
|
+
|
|
70
|
+
Paywall görünürlüğünü ve davranışlarını kontrol etmek için:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { usePaywall } from '@umituz/react-native-subscription';
|
|
74
|
+
|
|
75
|
+
function PremiumFeature() {
|
|
76
|
+
const { showPaywall, hidePaywall, isPaywallVisible } = usePaywall();
|
|
77
|
+
|
|
78
|
+
const handleUpgradeClick = () => {
|
|
79
|
+
showPaywall({
|
|
80
|
+
trigger: 'premium_button',
|
|
81
|
+
featureId: 'ai_tools',
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<View>
|
|
87
|
+
<Text>Premium Feature</Text>
|
|
88
|
+
<Button onPress={handleUpgradeClick} title="Unlock" />
|
|
89
|
+
</View>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### usePaywallActions Hook
|
|
95
|
+
|
|
96
|
+
Paywall aksiyonları için:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { usePaywallActions } from '@umituz/react-native-subscription';
|
|
100
|
+
|
|
101
|
+
function PaywallHandler() {
|
|
102
|
+
const { handlePurchase, handleRestore, isLoading } = usePaywallActions();
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<View>
|
|
106
|
+
<Button
|
|
107
|
+
onPress={handlePurchase}
|
|
108
|
+
disabled={isLoading}
|
|
109
|
+
title="Subscribe Now"
|
|
110
|
+
/>
|
|
111
|
+
<Button onPress={handleRestore} title="Restore Purchase" />
|
|
112
|
+
</View>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### useSubscriptionModal Hook
|
|
118
|
+
|
|
119
|
+
Subscription modal yönetimi için:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { useSubscriptionModal } from '@umituz/react-native-subscription';
|
|
123
|
+
|
|
124
|
+
function SubscriptionButton() {
|
|
125
|
+
const { openModal, closeModal, isModalOpen } = useSubscriptionModal();
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<>
|
|
129
|
+
<Button onPress={openModal} title="View Plans" />
|
|
130
|
+
<SubscriptionModal
|
|
131
|
+
isOpen={isModalOpen}
|
|
132
|
+
onClose={closeModal}
|
|
133
|
+
/>
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Bileşenler
|
|
140
|
+
|
|
141
|
+
### PaywallContainer
|
|
142
|
+
|
|
143
|
+
Paywall içerik wrapper'ı:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { PaywallContainer } from '@umituz/react-native-subscription';
|
|
147
|
+
|
|
148
|
+
<PaywallContainer
|
|
149
|
+
config={{
|
|
150
|
+
theme: 'dark',
|
|
151
|
+
showCloseButton: true,
|
|
152
|
+
closeOnBackdropPress: false,
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
{/* Paywall content */}
|
|
156
|
+
</PaywallContainer>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### PaywallScreen
|
|
160
|
+
|
|
161
|
+
Tam ekran paywall:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { PaywallScreen } from '@umituz/react-native-subscription';
|
|
165
|
+
|
|
166
|
+
<PaywallScreen
|
|
167
|
+
packages={subscriptionPackages}
|
|
168
|
+
onPackageSelect={handlePackageSelect}
|
|
169
|
+
config={{
|
|
170
|
+
highlightPackage: 'annual',
|
|
171
|
+
showPerks: true,
|
|
172
|
+
showTerms: true,
|
|
173
|
+
}}
|
|
174
|
+
translations={{
|
|
175
|
+
title: 'Choose Your Plan',
|
|
176
|
+
subtitle: 'Cancel anytime',
|
|
177
|
+
terms: 'Terms & Privacy Policy',
|
|
178
|
+
}}
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Hooks Referansı
|
|
183
|
+
|
|
184
|
+
### usePaywall
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const {
|
|
188
|
+
showPaywall, // Paywall göster
|
|
189
|
+
hidePaywall, // Paywall gizle
|
|
190
|
+
isPaywallVisible, // Paywall görünürlük durumu
|
|
191
|
+
paywallConfig, // Mevcut konfigürasyon
|
|
192
|
+
} = usePaywall();
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### usePaywallActions
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const {
|
|
199
|
+
handlePurchase, // Satın alma işlemi
|
|
200
|
+
handleRestore, // Satın alma geri yükleme
|
|
201
|
+
isLoading, // Yüklenme durumu
|
|
202
|
+
error, // Hata mesajı
|
|
203
|
+
selectedPackage, // Seçili paket
|
|
204
|
+
} = usePaywallActions();
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### usePaywallTranslations
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const {
|
|
211
|
+
translations, // Çeviri objeleri
|
|
212
|
+
t, // Çeviri fonksiyonu
|
|
213
|
+
isLoading, // Yüklenme durumu
|
|
214
|
+
} = usePaywallTranslations({
|
|
215
|
+
language: 'tr',
|
|
216
|
+
fallbackLanguage: 'en',
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Özelleştirme
|
|
221
|
+
|
|
222
|
+
### Tema Konfigürasyonu
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const customTheme = {
|
|
226
|
+
colors: {
|
|
227
|
+
primary: '#FF6B6B',
|
|
228
|
+
background: '#1A1A1A',
|
|
229
|
+
text: '#FFFFFF',
|
|
230
|
+
textSecondary: '#A0A0A0',
|
|
231
|
+
},
|
|
232
|
+
fonts: {
|
|
233
|
+
title: { fontSize: 28, fontWeight: 'bold' },
|
|
234
|
+
body: { fontSize: 16, fontWeight: 'normal' },
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
<PaywallModal theme={customTheme} />
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Özel Feature Listesi
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const customFeatures = [
|
|
245
|
+
{
|
|
246
|
+
id: 'feature1',
|
|
247
|
+
icon: 'rocket',
|
|
248
|
+
title: 'AI-Powered Tools',
|
|
249
|
+
description: 'Advanced AI features',
|
|
250
|
+
highlight: true,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: 'feature2',
|
|
254
|
+
icon: 'infinity',
|
|
255
|
+
title: 'Unlimited Credits',
|
|
256
|
+
description: 'Never run out of credits',
|
|
257
|
+
},
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
<PaywallScreen features={customFeatures} />
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Event Tracking
|
|
264
|
+
|
|
265
|
+
Analytics entegrasyonu için:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import { usePaywallFeedback } from '@umituz/react-native-subscription';
|
|
269
|
+
|
|
270
|
+
function PaywallWithTracking() {
|
|
271
|
+
const { trackEvent, trackPurchase, trackDismiss } = usePaywallFeedback();
|
|
272
|
+
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
trackEvent('paywall_impression', {
|
|
275
|
+
source: 'home_screen',
|
|
276
|
+
});
|
|
277
|
+
}, []);
|
|
278
|
+
|
|
279
|
+
const handlePurchase = async () => {
|
|
280
|
+
await purchasePackage();
|
|
281
|
+
trackPurchase('premium_monthly', {
|
|
282
|
+
revenue: 9.99,
|
|
283
|
+
currency: 'USD',
|
|
284
|
+
});
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const handleClose = () => {
|
|
288
|
+
trackDismiss('paywall_closed', {
|
|
289
|
+
duration: 30, // seconds
|
|
290
|
+
});
|
|
291
|
+
closeModal();
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Best Practices
|
|
297
|
+
|
|
298
|
+
1. **Trigger Bazlı Gösterim**: Farklı trigger'lar için farklı paywall'lar kullanın
|
|
299
|
+
2. **A/B Test**: Farklı varyasyonları test edin
|
|
300
|
+
3. **Analytics**: Kullanıcı davranışlarını takip edin
|
|
301
|
+
4. **Copywriting**: Farklı dillerde optimize edilmiş copy kullanın
|
|
302
|
+
5. **Loading States**: Satın alma sırasında loading gösterin
|
|
303
|
+
6. **Error Handling**: Hataları kullanıcı dostu mesajlarla gösterin
|
|
304
|
+
|
|
305
|
+
## Örnek Uygulama
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import React, { useState } from 'react';
|
|
309
|
+
import { View, Button } from 'react-native';
|
|
310
|
+
import {
|
|
311
|
+
PaywallModal,
|
|
312
|
+
usePaywall,
|
|
313
|
+
usePaywallActions,
|
|
314
|
+
} from '@umituz/react-native-subscription';
|
|
315
|
+
|
|
316
|
+
export default function PaywallExample() {
|
|
317
|
+
const { isPaywallVisible, showPaywall, hidePaywall } = usePaywall();
|
|
318
|
+
const { handlePurchase, isLoading } = usePaywallActions();
|
|
319
|
+
|
|
320
|
+
return (
|
|
321
|
+
<View>
|
|
322
|
+
<Button
|
|
323
|
+
onPress={() => showPaywall({ trigger: 'upgrade_button' })}
|
|
324
|
+
title="Upgrade to Premium"
|
|
325
|
+
/>
|
|
326
|
+
|
|
327
|
+
<PaywallModal
|
|
328
|
+
isVisible={isPaywallVisible}
|
|
329
|
+
onClose={hidePaywall}
|
|
330
|
+
config={{
|
|
331
|
+
title: 'Go Premium',
|
|
332
|
+
description: 'Unlock all features',
|
|
333
|
+
features: [
|
|
334
|
+
{ icon: 'star', text: 'Unlimited access' },
|
|
335
|
+
{ icon: 'zap', text: 'AI features' },
|
|
336
|
+
{ icon: 'shield', text: 'No ads' },
|
|
337
|
+
],
|
|
338
|
+
}}
|
|
339
|
+
onPurchase={handlePurchase}
|
|
340
|
+
isLoading={isLoading}
|
|
341
|
+
/>
|
|
342
|
+
</View>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Tip Tanımlamaları
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
interface PaywallConfig {
|
|
351
|
+
title?: string;
|
|
352
|
+
description?: string;
|
|
353
|
+
features?: PaywallFeature[];
|
|
354
|
+
theme?: 'light' | 'dark';
|
|
355
|
+
showCloseButton?: boolean;
|
|
356
|
+
closeOnBackdropPress?: boolean;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
interface PaywallFeature {
|
|
360
|
+
icon: string;
|
|
361
|
+
text: string;
|
|
362
|
+
description?: string;
|
|
363
|
+
highlight?: boolean;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
interface PaywallTrigger {
|
|
367
|
+
trigger: string;
|
|
368
|
+
featureId?: string;
|
|
369
|
+
source?: string;
|
|
370
|
+
}
|
|
371
|
+
```
|