@umituz/react-native-subscription 3.1.34 → 3.1.36

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 (55) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/CreditsInitializer.ts +34 -39
  3. package/src/domains/credits/application/DeductCreditsCommand.ts +13 -12
  4. package/src/domains/credits/infrastructure/operations/CreditsWriter.ts +1 -1
  5. package/src/domains/credits/presentation/deduct-credit/useDeductCredit.ts +1 -1
  6. package/src/domains/credits/presentation/useCredits.types.ts +1 -1
  7. package/src/domains/paywall/components/PaywallScreen.tsx +12 -11
  8. package/src/domains/paywall/hooks/usePaywallActions.ts +4 -3
  9. package/src/domains/paywall/hooks/usePaywallActions.utils.ts +14 -19
  10. package/src/domains/paywall/hooks/usePaywallPurchase.ts +10 -17
  11. package/src/domains/paywall/hooks/usePaywallRestore.ts +8 -15
  12. package/src/domains/revenuecat/core/errors/RevenueCatError.ts +1 -1
  13. package/src/domains/revenuecat/infrastructure/services/ConfigurationStateManager.ts +1 -1
  14. package/src/domains/revenuecat/infrastructure/services/RevenueCatInitializer.ts +7 -6
  15. package/src/domains/revenuecat/infrastructure/services/UserSwitchMutex.ts +8 -10
  16. package/src/domains/revenuecat/infrastructure/services/initializerConstants.ts +1 -1
  17. package/src/domains/revenuecat/infrastructure/services/userSwitchCore.ts +17 -34
  18. package/src/domains/revenuecat/infrastructure/services/userSwitchHelpers.ts +4 -5
  19. package/src/domains/revenuecat/infrastructure/services/userSwitchInitializer.ts +19 -29
  20. package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +17 -29
  21. package/src/domains/subscription/application/sync/CreditDocumentOperations.ts +16 -17
  22. package/src/domains/subscription/application/sync/PurchaseSyncHandler.ts +20 -23
  23. package/src/domains/subscription/application/sync/RenewalSyncHandler.ts +8 -7
  24. package/src/domains/subscription/application/sync/StatusChangeSyncHandler.ts +4 -3
  25. package/src/domains/subscription/application/sync/SyncProcessorLogger.ts +40 -65
  26. package/src/domains/subscription/application/sync/UserIdResolver.ts +5 -1
  27. package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +1 -1
  28. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +1 -1
  29. package/src/domains/subscription/infrastructure/handlers/package-operations/PackageFetcher.ts +7 -6
  30. package/src/domains/subscription/infrastructure/handlers/package-operations/PackagePurchaser.ts +8 -7
  31. package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +4 -3
  32. package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +21 -28
  33. package/src/domains/subscription/infrastructure/managers/initializationHandler.ts +1 -1
  34. package/src/domains/subscription/infrastructure/managers/managerOperations.ts +1 -1
  35. package/src/domains/subscription/infrastructure/managers/packageHandlerFactory.ts +1 -1
  36. package/src/domains/subscription/infrastructure/managers/premiumStatusChecker.ts +1 -1
  37. package/src/domains/subscription/infrastructure/managers/subscriptionManagerUtils.ts +1 -1
  38. package/src/domains/subscription/infrastructure/services/CustomerInfoListenerManager.ts +10 -9
  39. package/src/domains/subscription/infrastructure/services/OfferingsFetcher.ts +14 -21
  40. package/src/domains/subscription/infrastructure/services/PurchaseHandler.ts +9 -8
  41. package/src/domains/subscription/infrastructure/services/RestoreHandler.ts +1 -1
  42. package/src/domains/subscription/infrastructure/services/RevenueCatService.types.ts +5 -4
  43. package/src/domains/subscription/infrastructure/services/listeners/CustomerInfoHandler.ts +15 -29
  44. package/src/domains/subscription/infrastructure/services/purchase/PurchaseErrorHandler.ts +4 -2
  45. package/src/domains/subscription/infrastructure/services/purchase/PurchaseExecutor.ts +27 -33
  46. package/src/domains/subscription/infrastructure/utils/InitializationCache.ts +5 -1
  47. package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +11 -17
  48. package/src/domains/subscription/presentation/providers/SubscriptionFlowProvider.tsx +11 -12
  49. package/src/domains/subscription/presentation/screens/SubscriptionDetailScreen.tsx +1 -1
  50. package/src/domains/subscription/presentation/useSyncStatusListener.ts +10 -9
  51. package/src/domains/wallet/presentation/components/TransactionList.tsx +1 -1
  52. package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +2 -2
  53. package/src/domains/wallet/presentation/screens/WalletScreen.tsx +1 -1
  54. package/src/init/createSubscriptionInitModule.ts +4 -1
  55. package/src/shared/infrastructure/SubscriptionEventBus.ts +4 -1
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import Purchases, { type CustomerInfo } from "react-native-purchases";
8
- import type { InitializeResult } from "../../../../shared/application/ports/IRevenueCatService";
8
+ import type { InitializeResult } from "../../../shared/application/ports/IRevenueCatService";
9
9
  import type { InitializerDeps } from "./RevenueCatInitializer.types";
10
10
  import { FAILED_INITIALIZATION_RESULT } from "./initializerConstants";
11
11
  import { UserSwitchMutex } from "./UserSwitchMutex";
@@ -16,8 +16,9 @@ import {
16
16
  buildSuccessResult,
17
17
  fetchOfferingsSafe,
18
18
  } from "./userSwitchHelpers";
19
+ import { createLogger } from "../../../../../shared/utils/logger";
19
20
 
20
- declare const __DEV__: boolean;
21
+ const logger = createLogger("UserSwitchCore");
21
22
 
22
23
  /**
23
24
  * Handle user switch operation with mutex protection.
@@ -31,9 +32,7 @@ export async function handleUserSwitch(
31
32
  const { shouldProceed, existingPromise } = await UserSwitchMutex.acquire(mutexKey);
32
33
 
33
34
  if (!shouldProceed && existingPromise) {
34
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
35
- console.log('[UserSwitchCore] Using result from active switch operation');
36
- }
35
+ logger.debug("Using result from active switch operation");
37
36
  return existingPromise as Promise<InitializeResult>;
38
37
  }
39
38
 
@@ -54,38 +53,28 @@ async function performUserSwitch(
54
53
  const normalizedUserId = normalizeUserId(userId);
55
54
  const normalizedCurrentUserId = isAnonymousId(currentAppUserId) ? null : currentAppUserId;
56
55
 
57
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
58
- console.log('[UserSwitchCore] performUserSwitch:', {
59
- providedUserId: userId,
60
- normalizedUserId: normalizedUserId || '(null - anonymous)',
61
- currentAppUserId,
62
- normalizedCurrentUserId: normalizedCurrentUserId || '(null - anonymous)',
63
- needsSwitch: normalizedCurrentUserId !== normalizedUserId,
64
- });
65
- }
56
+ logger.debug("performUserSwitch", {
57
+ providedUserId: userId,
58
+ normalizedUserId: normalizedUserId || '(null - anonymous)',
59
+ currentAppUserId,
60
+ normalizedCurrentUserId: normalizedCurrentUserId || '(null - anonymous)',
61
+ needsSwitch: normalizedCurrentUserId !== normalizedUserId,
62
+ });
66
63
 
67
64
  let customerInfo: CustomerInfo;
68
65
 
69
66
  if (normalizedCurrentUserId !== normalizedUserId) {
70
67
  if (normalizedUserId) {
71
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
72
- console.log('[UserSwitchCore] Calling Purchases.logIn() to switch from anonymous to:', normalizedUserId);
73
- }
68
+ logger.debug("Calling Purchases.logIn() to switch from anonymous to", normalizedUserId);
74
69
  const result = await Purchases.logIn(normalizedUserId!);
75
70
  customerInfo = result.customerInfo;
76
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
77
- console.log('[UserSwitchCore] Purchases.logIn() successful, created:', result.created);
78
- }
71
+ logger.debug("Purchases.logIn() successful, created", result.created);
79
72
  } else {
80
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
81
- console.log('[UserSwitchCore] User is anonymous, fetching customer info');
82
- }
73
+ logger.debug("User is anonymous, fetching customer info");
83
74
  customerInfo = await Purchases.getCustomerInfo();
84
75
  }
85
76
  } else {
86
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
87
- console.log('[UserSwitchCore] No user switch needed, fetching current customer info');
88
- }
77
+ logger.debug("No user switch needed, fetching current customer info");
89
78
  customerInfo = await Purchases.getCustomerInfo();
90
79
  }
91
80
 
@@ -93,9 +82,7 @@ async function performUserSwitch(
93
82
  deps.setCurrentUserId(normalizedUserId || undefined);
94
83
  const offerings = await fetchOfferingsSafe();
95
84
 
96
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
97
- console.log('[UserSwitchCore] User switch completed successfully');
98
- }
85
+ logger.debug("User switch completed successfully");
99
86
 
100
87
  return buildSuccessResult(deps, customerInfo, offerings);
101
88
  } catch (error) {
@@ -106,11 +93,7 @@ async function performUserSwitch(
106
93
  // Ignore error in error handler
107
94
  }
108
95
 
109
- console.error('[UserSwitchCore] Failed during user switch or fetch', {
110
- userId,
111
- currentAppUserId,
112
- error
113
- });
96
+ logger.error("Failed during user switch or fetch", error, { userId, currentAppUserId });
114
97
  return FAILED_INITIALIZATION_RESULT;
115
98
  }
116
99
  }
@@ -5,11 +5,12 @@
5
5
  */
6
6
 
7
7
  import Purchases, { type CustomerInfo, type PurchasesOfferings } from "react-native-purchases";
8
- import type { InitializeResult } from "../../../../shared/application/ports/IRevenueCatService";
8
+ import type { InitializeResult } from "../../../shared/application/ports/IRevenueCatService";
9
9
  import type { InitializerDeps } from "./RevenueCatInitializer.types";
10
10
  import { ANONYMOUS_CACHE_KEY } from "../../../subscription/core/SubscriptionConstants";
11
+ import { createLogger } from "../../../../../shared/utils/logger";
11
12
 
12
- declare const __DEV__: boolean;
13
+ const logger = createLogger("UserSwitchHelpers");
13
14
 
14
15
  /**
15
16
  * Normalize user ID to null if empty or anonymous cache key.
@@ -47,9 +48,7 @@ export async function fetchOfferingsSafe(): Promise<PurchasesOfferings | null> {
47
48
  try {
48
49
  return await Purchases.getOfferings();
49
50
  } catch (error) {
50
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
51
- console.warn('[UserSwitchHelpers] Offerings fetch failed (non-fatal):', error);
52
- }
51
+ logger.warn("Offerings fetch failed (non-fatal)", error);
53
52
  return null;
54
53
  }
55
54
  }
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import Purchases, { type CustomerInfo } from "react-native-purchases";
8
- import type { InitializeResult } from "../../../../shared/application/ports/IRevenueCatService";
8
+ import type { InitializeResult } from "../../../shared/application/ports/IRevenueCatService";
9
9
  import type { InitializerDeps } from "./RevenueCatInitializer.types";
10
10
  import { FAILED_INITIALIZATION_RESULT } from "./initializerConstants";
11
11
  import { getPremiumEntitlement } from "../../core/types/RevenueCatTypes";
@@ -15,8 +15,9 @@ import {
15
15
  buildSuccessResult,
16
16
  fetchOfferingsSafe,
17
17
  } from "./userSwitchHelpers";
18
+ import { createLogger } from "../../../../../shared/utils/logger";
18
19
 
19
- declare const __DEV__: boolean;
20
+ const logger = createLogger("UserSwitchInitializer");
20
21
 
21
22
  /**
22
23
  * Handle initial SDK configuration with API key and user ID.
@@ -29,14 +30,12 @@ export async function handleInitialConfiguration(
29
30
  try {
30
31
  const normalizedUserId = normalizeUserId(userId);
31
32
 
32
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
33
- console.log('[UserSwitchInitializer] handleInitialConfiguration:', {
34
- providedUserId: userId,
35
- normalizedUserId: normalizedUserId || '(null - anonymous)',
36
- apiKeyPrefix: apiKey.substring(0, 5) + '...',
37
- isTestKey: apiKey.startsWith('test_'),
38
- });
39
- }
33
+ logger.debug("handleInitialConfiguration", {
34
+ providedUserId: userId,
35
+ normalizedUserId: normalizedUserId || '(null - anonymous)',
36
+ apiKeyPrefix: apiKey.substring(0, 5) + '...',
37
+ isTestKey: apiKey.startsWith('test_'),
38
+ });
40
39
 
41
40
  Purchases.setLogLevel(
42
41
  (typeof __DEV__ !== 'undefined' && __DEV__)
@@ -48,32 +47,25 @@ export async function handleInitialConfiguration(
48
47
  deps.setInitialized(true);
49
48
  deps.setCurrentUserId(normalizedUserId || undefined);
50
49
 
51
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
52
- console.log('[UserSwitchInitializer] Purchases.configure() successful');
53
- }
50
+ logger.debug("Purchases.configure() successful");
54
51
 
55
52
  const [customerInfo, offerings] = await Promise.all([
56
53
  Purchases.getCustomerInfo(),
57
54
  fetchOfferingsSafe(),
58
55
  ]);
59
56
 
60
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
61
- const currentUserId = await Purchases.getAppUserID();
62
- console.log('[UserSwitchInitializer] Initial configuration completed:', {
63
- revenueCatUserId: currentUserId,
64
- activeEntitlements: Object.keys(customerInfo.entitlements.active),
65
- offeringsCount: offerings?.all ? Object.keys(offerings.all).length : 0,
66
- });
67
- }
57
+ const currentUserId = await Purchases.getAppUserID();
58
+ logger.debug("Initial configuration completed", {
59
+ revenueCatUserId: currentUserId,
60
+ activeEntitlements: Object.keys(customerInfo.entitlements.active),
61
+ offeringsCount: offerings?.all ? Object.keys(offerings.all).length : 0,
62
+ });
68
63
 
69
64
  await syncPremiumStatusIfConfigured(deps, normalizedUserId, customerInfo);
70
65
 
71
66
  return buildSuccessResult(deps, customerInfo, offerings);
72
67
  } catch (error) {
73
- console.error('[UserSwitchInitializer] SDK configuration failed', {
74
- userId,
75
- error
76
- });
68
+ logger.error("SDK configuration failed", error, { userId });
77
69
  return FAILED_INITIALIZATION_RESULT;
78
70
  }
79
71
  }
@@ -89,9 +81,7 @@ export async function fetchCurrentUserData(deps: InitializerDeps): Promise<Initi
89
81
  ]);
90
82
  return buildSuccessResult(deps, customerInfo, offerings);
91
83
  } catch (error) {
92
- console.error('[UserSwitchInitializer] Failed to fetch customer info for initialized user', {
93
- error
94
- });
84
+ logger.error("Failed to fetch customer info for initialized user", error);
95
85
  return FAILED_INITIALIZATION_RESULT;
96
86
  }
97
87
  }
@@ -138,6 +128,6 @@ async function syncPremiumStatusIfConfigured(
138
128
  });
139
129
  }
140
130
  } catch (error) {
141
- console.error('[UserSwitchInitializer] Premium status sync callback failed:', error);
131
+ logger.error("Premium status sync callback failed", error);
142
132
  }
143
133
  }
@@ -1,6 +1,9 @@
1
1
  import { SubscriptionManager } from "../../infrastructure/managers/SubscriptionManager";
2
2
  import { getCurrentUserId, setupAuthStateListener } from "../SubscriptionAuthListener";
3
3
  import type { SubscriptionInitConfig } from "../SubscriptionInitializerTypes";
4
+ import { createLogger } from "../../../shared/utils/logger";
5
+
6
+ const logger = createLogger("BackgroundInitializer");
4
7
 
5
8
  const AUTH_STATE_DEBOUNCE_MS = 500;
6
9
  const MAX_RETRY_ATTEMPTS = 3;
@@ -16,18 +19,14 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
16
19
  let lastUserId: string | undefined = undefined;
17
20
 
18
21
  const initializeInBackground = async (revenueCatUserId?: string): Promise<void> => {
19
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
20
- console.log('[BackgroundInitializer] initializeInBackground called with userId:', revenueCatUserId || '(undefined - anonymous)');
21
- }
22
+ logger.debug("initializeInBackground called with userId", revenueCatUserId || '(undefined - anonymous)');
22
23
  await SubscriptionManager.initialize(revenueCatUserId);
23
24
  };
24
25
 
25
26
  const attemptInitWithRetry = async (revenueCatUserId: string | undefined, attempt: number, sequenceId: number): Promise<void> => {
26
27
  // Abort if this is no longer the active sequence (e.g., user changed)
27
28
  if (sequenceId !== currentSequenceId) {
28
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
29
- console.log('[BackgroundInitializer] Aborting retry - sequence changed');
30
- }
29
+ logger.debug("Aborting retry - sequence changed");
31
30
  return;
32
31
  }
33
32
 
@@ -38,23 +37,20 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
38
37
  }
39
38
  } catch (error) {
40
39
  if (sequenceId !== currentSequenceId) return;
41
-
40
+
42
41
  lastInitSucceeded = false;
43
- console.error('[BackgroundInitializer] Initialization failed:', {
42
+ logger.error("Initialization failed", error, {
44
43
  userId: revenueCatUserId,
45
44
  attempt: attempt + 1,
46
45
  maxAttempts: MAX_RETRY_ATTEMPTS,
47
- error: error instanceof Error ? error.message : String(error)
48
46
  });
49
47
 
50
48
  if (attempt < MAX_RETRY_ATTEMPTS - 1) {
51
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
52
- console.log('[BackgroundInitializer] Scheduling retry', { attempt: attempt + 2 });
53
- }
49
+ logger.debug("Scheduling retry", { attempt: attempt + 2 });
54
50
  retryTimer = setTimeout(() => {
55
51
  // Fire and forget promise, but safe because of sequenceId check
56
52
  attemptInitWithRetry(revenueCatUserId, attempt + 1, sequenceId).catch(err => {
57
- console.error('[BackgroundInitializer] Retry failed unhandled:', err);
53
+ logger.error("Retry failed unhandled", err);
58
54
  });
59
55
  }, RETRY_DELAY_MS * (attempt + 1));
60
56
  }
@@ -71,9 +67,7 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
71
67
  }
72
68
 
73
69
  if (lastUserId === revenueCatUserId && lastInitSucceeded) {
74
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
75
- console.log('[BackgroundInitializer] UserId unchanged and init succeeded, skipping');
76
- }
70
+ logger.debug("UserId unchanged and init succeeded, skipping");
77
71
  return;
78
72
  }
79
73
 
@@ -83,15 +77,11 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
83
77
  const sequenceId = currentSequenceId;
84
78
 
85
79
  if (!revenueCatUserId && !lastUserId) {
86
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
87
- console.log('[BackgroundInitializer] No user and no previous user, waiting for auth');
88
- }
80
+ logger.debug("No user and no previous user, waiting for auth");
89
81
  return;
90
82
  }
91
83
 
92
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
93
- console.log('[BackgroundInitializer] Auth state listener triggered, reinitializing with userId:', revenueCatUserId || '(undefined - anonymous)');
94
- }
84
+ logger.debug("Auth state listener triggered, reinitializing with userId", revenueCatUserId || '(undefined - anonymous)');
95
85
 
96
86
  // Important: Always reset on user change, not just on logout.
97
87
  // This ensures previous user's cached state is cleared before init.
@@ -104,7 +94,7 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
104
94
 
105
95
  // Start the retry chain
106
96
  attemptInitWithRetry(revenueCatUserId, 0, sequenceId).catch(err => {
107
- console.error('[BackgroundInitializer] Init sequence failed unhandled:', err);
97
+ logger.error("Init sequence failed unhandled", err);
108
98
  });
109
99
  }, AUTH_STATE_DEBOUNCE_MS);
110
100
  };
@@ -117,17 +107,15 @@ export async function startBackgroundInitialization(config: SubscriptionInitConf
117
107
  const initialRevenueCatUserId = getCurrentUserId(() => auth);
118
108
  lastUserId = initialRevenueCatUserId;
119
109
 
120
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
121
- console.log('[BackgroundInitializer] Initial RevenueCat userId:', initialRevenueCatUserId || '(undefined - anonymous)');
122
- }
110
+ logger.debug("Initial RevenueCat userId", initialRevenueCatUserId || '(undefined - anonymous)');
123
111
 
124
112
  if (initialRevenueCatUserId) {
125
113
  currentSequenceId++;
126
114
  attemptInitWithRetry(initialRevenueCatUserId, 0, currentSequenceId).catch(err => {
127
- console.error('[BackgroundInitializer] Initial sequence failed unhandled:', err);
115
+ logger.error("Initial sequence failed unhandled", err);
128
116
  });
129
- } else if (typeof __DEV__ !== 'undefined' && __DEV__) {
130
- console.log('[BackgroundInitializer] No user available yet, waiting for auth state');
117
+ } else {
118
+ logger.debug("No user available yet, waiting for auth state");
131
119
  }
132
120
 
133
121
  const unsubscribe = setupAuthStateListener(() => auth, debouncedInitialize);
@@ -5,6 +5,9 @@
5
5
 
6
6
  import { getCreditsRepository } from "../../../credits/infrastructure/CreditsRepositoryManager";
7
7
  import type { PremiumStatusChangedEvent } from "../../core/SubscriptionEvents";
8
+ import { createLogger } from "../../../shared/utils/logger";
9
+
10
+ const logger = createLogger("CreditDocumentOperations");
8
11
 
9
12
  export class CreditDocumentOperations {
10
13
  async expireSubscription(userId: string): Promise<void> {
@@ -14,14 +17,12 @@ export class CreditDocumentOperations {
14
17
  async syncPremiumStatus(userId: string, event: PremiumStatusChangedEvent): Promise<void> {
15
18
  const repo = getCreditsRepository();
16
19
 
17
- if (__DEV__) {
18
- console.log('[CreditDocumentOperations] 🔵 syncPremiumStatus: Starting', {
19
- userId,
20
- isPremium: event.isPremium,
21
- productId: event.productId,
22
- willRenew: event.willRenew,
23
- });
24
- }
20
+ logger.debug("syncPremiumStatus: Starting", {
21
+ userId,
22
+ isPremium: event.isPremium,
23
+ productId: event.productId,
24
+ willRenew: event.willRenew,
25
+ });
25
26
 
26
27
  // Ensure premium user has a credits document (recovery)
27
28
  if (event.isPremium) {
@@ -32,8 +33,8 @@ export class CreditDocumentOperations {
32
33
  event.expirationDate ?? null,
33
34
  event.periodType ?? null,
34
35
  );
35
- if (__DEV__ && created) {
36
- console.log('[CreditDocumentOperations] 🟢 Recovery: created missing credits document for premium user', {
36
+ if (created) {
37
+ logger.debug("Recovery: created missing credits document for premium user", {
37
38
  userId,
38
39
  productId: event.productId,
39
40
  });
@@ -53,12 +54,10 @@ export class CreditDocumentOperations {
53
54
  ownershipType: event.ownershipType ?? null,
54
55
  });
55
56
 
56
- if (__DEV__) {
57
- console.log('[CreditDocumentOperations] 🟢 syncPremiumStatus: Completed', {
58
- userId,
59
- isPremium: event.isPremium,
60
- productId: event.productId,
61
- });
62
- }
57
+ logger.debug("syncPremiumStatus: Completed", {
58
+ userId,
59
+ isPremium: event.isPremium,
60
+ productId: event.productId,
61
+ });
63
62
  }
64
63
  }
@@ -9,6 +9,9 @@ import { extractRevenueCatData } from "../SubscriptionSyncUtils";
9
9
  import { generatePurchaseId } from "../syncIdGenerators";
10
10
  import type { PurchaseCompletedEvent } from "../../core/SubscriptionEvents";
11
11
  import { UserIdResolver } from "./UserIdResolver";
12
+ import { createLogger } from "../../../shared/utils/logger";
13
+
14
+ const logger = createLogger("PurchaseSyncHandler");
12
15
 
13
16
  export class PurchaseSyncHandler {
14
17
  private purchaseInProgress = false;
@@ -25,14 +28,12 @@ export class PurchaseSyncHandler {
25
28
  async processPurchase(event: PurchaseCompletedEvent): Promise<void> {
26
29
  this.purchaseInProgress = true;
27
30
 
28
- if (__DEV__) {
29
- console.log('[PurchaseSyncHandler] 🔵 Starting credit initialization', {
30
- productId: event.productId,
31
- source: event.source,
32
- packageType: event.packageType,
33
- activeEntitlements: Object.keys(event.customerInfo.entitlements.active),
34
- });
35
- }
31
+ logger.debug("Starting credit initialization", {
32
+ productId: event.productId,
33
+ source: event.source,
34
+ packageType: event.packageType,
35
+ activeEntitlements: Object.keys(event.customerInfo.entitlements.active),
36
+ });
36
37
 
37
38
  try {
38
39
  // Extract revenue cat data
@@ -46,14 +47,12 @@ export class PurchaseSyncHandler {
46
47
  // Resolve user ID
47
48
  const creditsUserId = await this.userIdResolver.resolveCreditsUserId(event.userId);
48
49
 
49
- if (__DEV__) {
50
- console.log('[PurchaseSyncHandler] 🔵 Calling initializeCredits', {
51
- creditsUserId,
52
- purchaseId,
53
- productId: event.productId,
54
- revenueCatUserId: revenueCatData.revenueCatUserId,
55
- });
56
- }
50
+ logger.debug("Calling initializeCredits", {
51
+ creditsUserId,
52
+ purchaseId,
53
+ productId: event.productId,
54
+ revenueCatUserId: revenueCatData.revenueCatUserId,
55
+ });
57
56
 
58
57
  // Initialize credits
59
58
  const result = await getCreditsRepository().initializeCredits(
@@ -69,13 +68,11 @@ export class PurchaseSyncHandler {
69
68
  throw new Error(`[PurchaseSyncHandler] Credit initialization failed: ${result.error?.message ?? 'unknown'}`);
70
69
  }
71
70
 
72
- if (__DEV__) {
73
- console.log('[PurchaseSyncHandler] 🟢 Credits initialized successfully', {
74
- creditsUserId,
75
- purchaseId,
76
- credits: result.data?.credits,
77
- });
78
- }
71
+ logger.debug("Credits initialized successfully", {
72
+ creditsUserId,
73
+ purchaseId,
74
+ credits: result.data?.credits,
75
+ });
79
76
  } finally {
80
77
  this.purchaseInProgress = false;
81
78
  }
@@ -9,6 +9,9 @@ import { extractRevenueCatData } from "../SubscriptionSyncUtils";
9
9
  import { generateRenewalId } from "../syncIdGenerators";
10
10
  import type { RenewalDetectedEvent } from "../../core/SubscriptionEvents";
11
11
  import { UserIdResolver } from "./UserIdResolver";
12
+ import { createLogger } from "../../../shared/utils/logger";
13
+
14
+ const logger = createLogger("RenewalSyncHandler");
12
15
 
13
16
  export class RenewalSyncHandler {
14
17
  private renewalInProgress = false;
@@ -55,13 +58,11 @@ export class RenewalSyncHandler {
55
58
  throw new Error(`[RenewalSyncHandler] Credit initialization failed: ${result.error?.message ?? 'unknown'}`);
56
59
  }
57
60
 
58
- if (__DEV__) {
59
- console.log('[RenewalSyncHandler] 🟢 Renewal credits allocated successfully', {
60
- creditsUserId,
61
- purchaseId,
62
- productId: event.productId,
63
- });
64
- }
61
+ logger.debug("Renewal credits allocated successfully", {
62
+ creditsUserId,
63
+ purchaseId,
64
+ productId: event.productId,
65
+ });
65
66
  } finally {
66
67
  this.renewalInProgress = false;
67
68
  }
@@ -8,6 +8,9 @@ import type { PremiumStatusChangedEvent } from "../../core/SubscriptionEvents";
8
8
  import { UserIdResolver } from "./UserIdResolver";
9
9
  import { CreditDocumentOperations } from "./CreditDocumentOperations";
10
10
  import { PurchaseSyncHandler } from "./PurchaseSyncHandler";
11
+ import { createLogger } from "../../../shared/utils/logger";
12
+
13
+ const logger = createLogger("StatusChangeSyncHandler");
11
14
 
12
15
  export class StatusChangeSyncHandler {
13
16
  constructor(
@@ -19,9 +22,7 @@ export class StatusChangeSyncHandler {
19
22
  async processStatusChange(event: PremiumStatusChangedEvent): Promise<void> {
20
23
  // If purchase is in progress, only do recovery sync
21
24
  if (this.purchaseHandler.isProcessing()) {
22
- if (__DEV__) {
23
- console.log("[StatusChangeSyncHandler] Purchase in progress - running recovery only");
24
- }
25
+ logger.debug("Purchase in progress - running recovery only");
25
26
  if (event.isPremium && event.productId) {
26
27
  const creditsUserId = await this.userIdResolver.resolveCreditsUserId(event.userId);
27
28
  await this.creditOps.syncPremiumStatus(creditsUserId, event);