@umituz/react-native-subscription 2.27.66 → 2.27.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/domains/credits/application/CreditLimitCalculator.ts +17 -0
- package/src/domains/credits/application/CreditsInitializer.ts +85 -0
- package/src/domains/credits/application/DeductCreditsCommand.ts +52 -0
- package/src/domains/credits/application/PurchaseMetadataGenerator.ts +59 -0
- package/src/domains/credits/application/credit-strategies/CreditAllocationContext.ts +35 -0
- package/src/domains/credits/application/credit-strategies/ICreditStrategy.ts +18 -0
- package/src/domains/credits/application/credit-strategies/StandardPurchaseCreditStrategy.ts +16 -0
- package/src/domains/credits/application/credit-strategies/SyncCreditStrategy.ts +15 -0
- package/src/domains/credits/application/credit-strategies/TrialCreditStrategy.ts +18 -0
- package/src/{infrastructure/mappers → domains/credits/core}/CreditsMapper.ts +4 -4
- package/src/domains/credits/infrastructure/CreditsRepository.ts +102 -0
- package/src/{presentation/hooks → domains/credits/presentation}/useCredits.ts +21 -4
- package/src/domains/subscription/application/SubscriptionAuthListener.ts +26 -0
- package/src/domains/subscription/application/SubscriptionInitializer.ts +77 -0
- package/src/{infrastructure/services → domains/subscription/application}/SubscriptionInitializerTypes.ts +21 -1
- package/src/domains/subscription/application/SubscriptionSyncService.ts +71 -0
- package/src/domains/subscription/application/SubscriptionSyncUtils.ts +16 -0
- package/src/{revenuecat/domain/value-objects → domains/subscription/core}/RevenueCatConfig.ts +1 -1
- package/src/{domain/types → domains/subscription/core}/RevenueCatData.ts +1 -1
- package/src/{domain/entities → domains/subscription/core}/SubscriptionStatus.ts +13 -21
- package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +51 -0
- package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +67 -0
- package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +27 -0
- package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCat.ts +1 -1
- package/src/domains/subscription/infrastructure/managers/SubscriptionInternalState.ts +12 -0
- package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +110 -0
- package/src/{revenuecat → domains/subscription}/infrastructure/services/PurchaseHandler.ts +1 -1
- package/src/{revenuecat → domains/subscription}/infrastructure/services/RestoreHandler.ts +1 -1
- package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatInitializer.ts +1 -1
- package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatService.ts +2 -2
- package/src/{presentation/hooks → domains/subscription/presentation}/usePremium.ts +7 -4
- package/src/domains/trial/application/TrialEligibilityService.ts +25 -0
- package/src/domains/trial/application/TrialService.ts +69 -0
- package/src/{infrastructure/services → domains/trial/core}/TrialTypes.ts +1 -1
- package/src/domains/trial/infrastructure/DeviceTrialRepository.ts +30 -0
- package/src/index.ts +28 -59
- package/src/init/createSubscriptionInitModule.ts +1 -1
- package/src/presentation/components/details/PremiumStatusBadge.tsx +1 -3
- package/src/presentation/hooks/feedback/useFeedbackSubmit.ts +1 -1
- package/src/presentation/hooks/index.ts +11 -11
- package/src/shared/application/ports/IRevenueCatService.ts +32 -0
- package/src/shared/infrastructure/SubscriptionEventBus.ts +51 -0
- package/src/application/README.md +0 -50
- package/src/domain/README.md +0 -54
- package/src/domain/entities/README.md +0 -50
- package/src/domain/entities/SubscriptionStatus.test.ts +0 -149
- package/src/domain/errors/README.md +0 -53
- package/src/domain/value-objects/README.md +0 -50
- package/src/infrastructure/README.md +0 -55
- package/src/infrastructure/mappers/README.md +0 -21
- package/src/infrastructure/models/README.md +0 -26
- package/src/infrastructure/repositories/CreditsRepository.ts +0 -132
- package/src/infrastructure/repositories/README.md +0 -99
- package/src/infrastructure/services/CreditsInitializer.ts +0 -170
- package/src/infrastructure/services/README.md +0 -99
- package/src/infrastructure/services/SubscriptionInitializer.ts +0 -176
- package/src/infrastructure/services/SubscriptionService.ts +0 -133
- package/src/infrastructure/services/TrialService.ts +0 -197
- package/src/infrastructure/services/app-service-helpers.ts +0 -111
- package/src/revenuecat/README.md +0 -104
- package/src/revenuecat/application/README.md +0 -43
- package/src/revenuecat/application/ports/IRevenueCatService.ts +0 -76
- package/src/revenuecat/application/ports/README.md +0 -41
- package/src/revenuecat/domain/README.md +0 -48
- package/src/revenuecat/domain/constants/README.md +0 -41
- package/src/revenuecat/domain/entities/README.md +0 -42
- package/src/revenuecat/domain/errors/README.md +0 -53
- package/src/revenuecat/domain/types/README.md +0 -41
- package/src/revenuecat/domain/value-objects/README.md +0 -41
- package/src/revenuecat/index.ts +0 -13
- package/src/revenuecat/infrastructure/handlers/PackageHandler.ts +0 -161
- package/src/revenuecat/infrastructure/managers/SubscriptionManager.ts +0 -165
- package/src/revenuecat/presentation/README.md +0 -42
- /package/src/{domain/entities → domains/credits/core}/Credits.ts +0 -0
- /package/src/{infrastructure/models → domains/credits/core}/UserCreditsDocument.ts +0 -0
- /package/src/{infrastructure/repositories → domains/credits/infrastructure}/CreditsRepositoryProvider.ts +0 -0
- /package/src/{presentation/hooks → domains/credits/presentation}/useDeductCredit.ts +0 -0
- /package/src/{revenuecat/domain/constants → domains/subscription/core}/RevenueCatConstants.ts +0 -0
- /package/src/{revenuecat/domain/errors → domains/subscription/core}/RevenueCatError.ts +0 -0
- /package/src/{revenuecat/domain/types → domains/subscription/core}/RevenueCatTypes.ts +0 -0
- /package/src/{domain/entities → domains/subscription/core}/SubscriptionConstants.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/README.md +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/config/README.md +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/handlers/README.md +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/README.md +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/subscriptionQueryKeys.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useCustomerInfo.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useInitializeSubscription.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePaywallFlow.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePurchasePackage.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRestorePurchase.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCatTrialEligibility.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionPackages.ts +0 -0
- /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionQueries.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/managers/README.md +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/services/CustomerInfoListenerManager.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/services/OfferingsFetcher.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/services/README.md +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/services/ServiceStateManager.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/ApiKeyResolver.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/InitializationCache.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/PremiumStatusSyncer.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/README.md +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/RenewalDetector.ts +0 -0
- /package/src/{revenuecat → domains/subscription}/infrastructure/utils/UserIdProvider.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthAwarePurchase.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthSubscriptionSync.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useFeatureGate.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/usePaywallVisibility.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/usePremiumGate.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useSavedPurchaseAutoExecution.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.utils.ts +0 -0
- /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionStatus.ts +0 -0
- /package/src/{infrastructure/services → shared/application}/ActivationHandler.ts +0 -0
- /package/src/{infrastructure/services → shared/application}/FeedbackService.ts +0 -0
- /package/src/{application → shared/application}/ports/ISubscriptionRepository.ts +0 -0
- /package/src/{application → shared/application}/ports/ISubscriptionService.ts +0 -0
- /package/src/{application → shared/application}/ports/README.md +0 -0
- /package/src/{domain/errors → shared/utils}/InsufficientCreditsError.ts +0 -0
- /package/src/{infrastructure → shared}/utils/Logger.ts +0 -0
- /package/src/{domain/value-objects → shared/utils}/Result.ts +0 -0
- /package/src/{domain/value-objects → shared/utils}/SubscriptionConfig.ts +0 -0
- /package/src/{domain/errors → shared/utils}/SubscriptionError.ts +0 -0
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package Handler
|
|
3
|
-
* Handles package operations (fetch, purchase, restore, premium status)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { PurchasesPackage, CustomerInfo } from "react-native-purchases";
|
|
7
|
-
import type { IRevenueCatService } from "../../application/ports/IRevenueCatService";
|
|
8
|
-
import { getPremiumEntitlement } from "../../domain/types/RevenueCatTypes";
|
|
9
|
-
|
|
10
|
-
export interface PremiumStatus {
|
|
11
|
-
isPremium: boolean;
|
|
12
|
-
expirationDate: Date | null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface RestoreResultInfo {
|
|
16
|
-
success: boolean;
|
|
17
|
-
productId: string | null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class PackageHandler {
|
|
21
|
-
constructor(
|
|
22
|
-
private service: IRevenueCatService | null,
|
|
23
|
-
private entitlementId: string
|
|
24
|
-
) { }
|
|
25
|
-
|
|
26
|
-
setService(service: IRevenueCatService | null): void {
|
|
27
|
-
this.service = service;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async fetchPackages(): Promise<PurchasesPackage[]> {
|
|
31
|
-
if (__DEV__) {
|
|
32
|
-
console.log('[DEBUG PackageHandler] fetchPackages called', {
|
|
33
|
-
hasService: !!this.service,
|
|
34
|
-
isInitialized: this.service?.isInitialized(),
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
if (!this.service?.isInitialized()) {
|
|
38
|
-
if (__DEV__) {
|
|
39
|
-
console.log('[DEBUG PackageHandler] Service not initialized, returning empty');
|
|
40
|
-
}
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const offering = await this.service.fetchOfferings();
|
|
46
|
-
|
|
47
|
-
if (__DEV__) {
|
|
48
|
-
console.log('[DEBUG PackageHandler] fetchOfferings result:', {
|
|
49
|
-
hasOffering: !!offering,
|
|
50
|
-
identifier: offering?.identifier,
|
|
51
|
-
packagesCount: offering?.availablePackages?.length ?? 0,
|
|
52
|
-
packages: offering?.availablePackages?.map(p => ({
|
|
53
|
-
identifier: p.identifier,
|
|
54
|
-
productIdentifier: p.product.identifier,
|
|
55
|
-
offeringIdentifier: p.offeringIdentifier
|
|
56
|
-
}))
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return offering?.availablePackages ?? [];
|
|
61
|
-
} catch (error) {
|
|
62
|
-
if (__DEV__) {
|
|
63
|
-
console.error('[DEBUG PackageHandler] fetchOfferings failed:', error);
|
|
64
|
-
}
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async purchase(pkg: PurchasesPackage, userId: string): Promise<boolean> {
|
|
70
|
-
if (__DEV__) {
|
|
71
|
-
console.log('[DEBUG PackageHandler] purchase() called', {
|
|
72
|
-
productId: pkg.product.identifier,
|
|
73
|
-
userId,
|
|
74
|
-
serviceExists: !!this.service,
|
|
75
|
-
isInitialized: this.service?.isInitialized(),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!this.service?.isInitialized()) {
|
|
80
|
-
if (__DEV__) {
|
|
81
|
-
console.log('[DEBUG PackageHandler] Service not initialized', {
|
|
82
|
-
productId: pkg.product.identifier,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
if (__DEV__) {
|
|
90
|
-
console.log('[DEBUG PackageHandler] Calling service.purchasePackage...');
|
|
91
|
-
}
|
|
92
|
-
const result = await this.service.purchasePackage(pkg, userId);
|
|
93
|
-
if (__DEV__) {
|
|
94
|
-
console.log('[DEBUG PackageHandler] Purchase result:', {
|
|
95
|
-
success: result.success,
|
|
96
|
-
productId: pkg.product.identifier,
|
|
97
|
-
isPremium: result.isPremium,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
return result.success;
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (__DEV__) {
|
|
103
|
-
console.error('[DEBUG PackageHandler] Purchase failed:', {
|
|
104
|
-
error,
|
|
105
|
-
productId: pkg.product.identifier,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async restore(userId: string): Promise<RestoreResultInfo> {
|
|
113
|
-
if (!this.service?.isInitialized()) {
|
|
114
|
-
return { success: false, productId: null };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
const result = await this.service.restorePurchases(userId);
|
|
119
|
-
|
|
120
|
-
// Extract product ID from active entitlement
|
|
121
|
-
let productId: string | null = null;
|
|
122
|
-
if (result.success && result.customerInfo) {
|
|
123
|
-
const entitlement = getPremiumEntitlement(
|
|
124
|
-
result.customerInfo,
|
|
125
|
-
this.entitlementId
|
|
126
|
-
);
|
|
127
|
-
if (entitlement) {
|
|
128
|
-
productId = entitlement.productIdentifier;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return { success: result.success, productId };
|
|
133
|
-
} catch (error) {
|
|
134
|
-
if (__DEV__) {
|
|
135
|
-
console.error('[DEBUG PackageHandler] Restore failed:', {
|
|
136
|
-
error,
|
|
137
|
-
userId,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
return { success: false, productId: null };
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
checkPremiumStatusFromInfo(customerInfo: CustomerInfo): PremiumStatus {
|
|
145
|
-
const entitlement = getPremiumEntitlement(customerInfo, this.entitlementId);
|
|
146
|
-
|
|
147
|
-
if (entitlement) {
|
|
148
|
-
return {
|
|
149
|
-
isPremium: true,
|
|
150
|
-
expirationDate: entitlement.expirationDate
|
|
151
|
-
? new Date(entitlement.expirationDate)
|
|
152
|
-
: null,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
isPremium: false,
|
|
158
|
-
expirationDate: null,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subscription Manager
|
|
3
|
-
* Facade for subscription operations
|
|
4
|
-
* Coordinates UserIdProvider, InitializationCache, and PackageHandler
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { PurchasesPackage } from "react-native-purchases";
|
|
8
|
-
import type { RevenueCatConfig } from "../../domain/value-objects/RevenueCatConfig";
|
|
9
|
-
import type { IRevenueCatService } from "../../application/ports/IRevenueCatService";
|
|
10
|
-
import { initializeRevenueCatService, getRevenueCatService } from "../services/RevenueCatService";
|
|
11
|
-
import { UserIdProvider } from "../utils/UserIdProvider";
|
|
12
|
-
import { InitializationCache } from "../utils/InitializationCache";
|
|
13
|
-
import { PackageHandler } from "../handlers/PackageHandler";
|
|
14
|
-
import type { PremiumStatus, RestoreResultInfo } from "../handlers/PackageHandler";
|
|
15
|
-
|
|
16
|
-
export interface SubscriptionManagerConfig {
|
|
17
|
-
config: RevenueCatConfig;
|
|
18
|
-
apiKey: string;
|
|
19
|
-
getAnonymousUserId?: () => Promise<string>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class SubscriptionManagerImpl {
|
|
23
|
-
private managerConfig: SubscriptionManagerConfig | null = null;
|
|
24
|
-
private serviceInstance: IRevenueCatService | null = null;
|
|
25
|
-
private userIdProvider = new UserIdProvider();
|
|
26
|
-
private initCache = new InitializationCache();
|
|
27
|
-
private packageHandler: PackageHandler | null = null;
|
|
28
|
-
|
|
29
|
-
configure(config: SubscriptionManagerConfig): void {
|
|
30
|
-
this.managerConfig = config;
|
|
31
|
-
this.packageHandler = new PackageHandler(null, config.config.entitlementIdentifier);
|
|
32
|
-
|
|
33
|
-
if (config.getAnonymousUserId) {
|
|
34
|
-
this.userIdProvider.configure(config.getAnonymousUserId);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private ensureConfigured(): void {
|
|
39
|
-
if (!this.managerConfig || !this.packageHandler) {
|
|
40
|
-
throw new Error("SubscriptionManager not configured");
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private async performInitialization(userId: string): Promise<boolean> {
|
|
45
|
-
this.ensureConfigured();
|
|
46
|
-
|
|
47
|
-
await initializeRevenueCatService(this.managerConfig!.config);
|
|
48
|
-
this.serviceInstance = getRevenueCatService();
|
|
49
|
-
|
|
50
|
-
if (!this.serviceInstance) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
this.packageHandler!.setService(this.serviceInstance);
|
|
55
|
-
|
|
56
|
-
const result = await this.serviceInstance.initialize(userId);
|
|
57
|
-
return result.success;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async initialize(userId?: string): Promise<boolean> {
|
|
61
|
-
this.ensureConfigured();
|
|
62
|
-
|
|
63
|
-
const effectiveUserId = userId || (await this.userIdProvider.getOrCreateAnonymousUserId());
|
|
64
|
-
|
|
65
|
-
// Atomic check-and-acquire to prevent race conditions
|
|
66
|
-
const { shouldInit, existingPromise } = this.initCache.tryAcquireInitialization(effectiveUserId);
|
|
67
|
-
|
|
68
|
-
if (!shouldInit && existingPromise) {
|
|
69
|
-
return existingPromise;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const promise = this.performInitialization(effectiveUserId);
|
|
73
|
-
this.initCache.setPromise(promise, effectiveUserId);
|
|
74
|
-
|
|
75
|
-
return promise;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
isConfigured(): boolean {
|
|
79
|
-
return this.managerConfig !== null && this.packageHandler !== null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
isInitialized(): boolean {
|
|
83
|
-
return this.serviceInstance?.isInitialized() ?? false;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
isInitializedForUser(userId: string): boolean {
|
|
87
|
-
return this.serviceInstance?.isInitialized() === true &&
|
|
88
|
-
this.initCache.getCurrentUserId() === userId;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
getEntitlementId(): string | null {
|
|
92
|
-
return this.managerConfig?.config.entitlementIdentifier || null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async getPackages(): Promise<PurchasesPackage[]> {
|
|
96
|
-
if (__DEV__) {
|
|
97
|
-
console.log('[DEBUG SubscriptionManager] getPackages called', {
|
|
98
|
-
isConfigured: this.isConfigured(),
|
|
99
|
-
isInitialized: this.isInitialized(),
|
|
100
|
-
hasServiceInstance: !!this.serviceInstance,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
this.ensureConfigured();
|
|
104
|
-
if (!this.serviceInstance) {
|
|
105
|
-
this.serviceInstance = getRevenueCatService();
|
|
106
|
-
this.packageHandler!.setService(this.serviceInstance);
|
|
107
|
-
}
|
|
108
|
-
return this.packageHandler!.fetchPackages();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async purchasePackage(pkg: PurchasesPackage): Promise<boolean> {
|
|
112
|
-
if (__DEV__) {
|
|
113
|
-
console.log('[DEBUG SubscriptionManager] purchasePackage called', {
|
|
114
|
-
productId: pkg.product.identifier,
|
|
115
|
-
isConfigured: this.isConfigured(),
|
|
116
|
-
isInitialized: this.isInitialized(),
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
this.ensureConfigured();
|
|
120
|
-
const userId = this.initCache.getCurrentUserId();
|
|
121
|
-
if (__DEV__) {
|
|
122
|
-
console.log('[DEBUG SubscriptionManager] userId from cache:', userId);
|
|
123
|
-
}
|
|
124
|
-
if (!userId) {
|
|
125
|
-
if (__DEV__) {
|
|
126
|
-
console.log('[DEBUG SubscriptionManager] No userId, returning false');
|
|
127
|
-
}
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
return this.packageHandler!.purchase(pkg, userId);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async restore(): Promise<RestoreResultInfo> {
|
|
134
|
-
this.ensureConfigured();
|
|
135
|
-
const userId = this.initCache.getCurrentUserId();
|
|
136
|
-
if (!userId) return { success: false, productId: null };
|
|
137
|
-
return this.packageHandler!.restore(userId);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async checkPremiumStatus(): Promise<PremiumStatus> {
|
|
141
|
-
this.ensureConfigured();
|
|
142
|
-
const userId = this.initCache.getCurrentUserId();
|
|
143
|
-
if (!userId) return { isPremium: false, expirationDate: null };
|
|
144
|
-
|
|
145
|
-
const customerInfo = await this.serviceInstance?.getCustomerInfo();
|
|
146
|
-
if (customerInfo) {
|
|
147
|
-
return this.packageHandler!.checkPremiumStatusFromInfo(customerInfo);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return { isPremium: false, expirationDate: null };
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async reset(): Promise<void> {
|
|
154
|
-
if (this.serviceInstance) {
|
|
155
|
-
await this.serviceInstance.reset();
|
|
156
|
-
}
|
|
157
|
-
this.initCache.reset();
|
|
158
|
-
this.userIdProvider.reset();
|
|
159
|
-
this.serviceInstance = null;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export const SubscriptionManager = new SubscriptionManagerImpl();
|
|
164
|
-
|
|
165
|
-
export type { PremiumStatus };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# RevenueCat Presentation
|
|
2
|
-
|
|
3
|
-
## Location
|
|
4
|
-
Presentation layer for RevenueCat integration.
|
|
5
|
-
|
|
6
|
-
## Strategy
|
|
7
|
-
This directory contains React hooks, components, and utilities for integrating RevenueCat functionality into the UI layer with proper loading states, error handling, and caching.
|
|
8
|
-
|
|
9
|
-
## Restrictions
|
|
10
|
-
|
|
11
|
-
### REQUIRED
|
|
12
|
-
- Must show loading states during async operations
|
|
13
|
-
- Must handle and display errors appropriately
|
|
14
|
-
- Must cache customer info and offerings
|
|
15
|
-
- Must re-render on entitlement changes
|
|
16
|
-
|
|
17
|
-
### PROHIBITED
|
|
18
|
-
- DO NOT skip loading states
|
|
19
|
-
- DO NOT show technical errors to users
|
|
20
|
-
- DO NOT ignore cache invalidation
|
|
21
|
-
- DO NOT prevent re-renders on state changes
|
|
22
|
-
|
|
23
|
-
### CRITICAL SAFETY
|
|
24
|
-
- All async operations MUST show loading states
|
|
25
|
-
- All errors MUST be handled and displayed appropriately
|
|
26
|
-
- Data MUST be cached appropriately
|
|
27
|
-
- UI MUST re-render on entitlement changes
|
|
28
|
-
|
|
29
|
-
## AI Agent Guidelines
|
|
30
|
-
1. Always show loading states during async operations
|
|
31
|
-
2. Handle and display errors appropriately to users
|
|
32
|
-
3. Update UI optimistically where possible
|
|
33
|
-
4. Cache customer info and offerings appropriately
|
|
34
|
-
5. Re-render on entitlement changes
|
|
35
|
-
6. Provide clear feedback during purchases
|
|
36
|
-
7. Validate data before displaying to users
|
|
37
|
-
|
|
38
|
-
## Related Documentation
|
|
39
|
-
- [RevenueCat Integration](../README.md)
|
|
40
|
-
- [RevenueCat Application](../application/README.md)
|
|
41
|
-
- [RevenueCat Infrastructure](../infrastructure/README.md)
|
|
42
|
-
- [RevenueCat Domain](../domain/README.md)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat/domain/constants → domains/subscription/core}/RevenueCatConstants.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePaywallFlow.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat → domains/subscription}/infrastructure/services/OfferingsFetcher.ts
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat → domains/subscription}/infrastructure/services/ServiceStateManager.ts
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/{revenuecat → domains/subscription}/infrastructure/utils/InitializationCache.ts
RENAMED
|
File without changes
|
/package/src/{revenuecat → domains/subscription}/infrastructure/utils/PremiumStatusSyncer.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{presentation/hooks → domains/subscription/presentation}/useAuthAwarePurchase.ts
RENAMED
|
File without changes
|
/package/src/{presentation/hooks → domains/subscription/presentation}/useAuthSubscriptionSync.ts
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/{presentation/hooks → domains/subscription/presentation}/usePaywallVisibility.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionStatus.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|