@umituz/react-native-subscription 2.14.24 → 2.14.26

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.14.24",
3
+ "version": "2.14.26",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -9,6 +9,7 @@ import { useCredits } from "./useCredits";
9
9
  import { useSubscriptionStatus } from "./useSubscriptionStatus";
10
10
  import { useCustomerInfo } from "../../revenuecat/presentation/hooks/useCustomerInfo";
11
11
  import { usePaywallVisibility } from "./usePaywallVisibility";
12
+ import { SubscriptionManager } from "../../revenuecat/infrastructure/managers/SubscriptionManager";
12
13
  import {
13
14
  convertPurchasedAt,
14
15
  formatDateForLocale,
@@ -45,7 +46,10 @@ export const useSubscriptionSettingsConfig = (
45
46
 
46
47
  // Internal hooks
47
48
  const { credits } = useCredits({ userId, enabled: !!userId });
48
- const { isPremium: subscriptionActive } = useSubscriptionStatus({
49
+ const {
50
+ isPremium: subscriptionActive,
51
+ expirationDate: statusExpirationDate,
52
+ } = useSubscriptionStatus({
49
53
  userId,
50
54
  enabled: !!userId,
51
55
  });
@@ -55,9 +59,16 @@ export const useSubscriptionSettingsConfig = (
55
59
  // Premium status from actual RevenueCat subscription
56
60
  const isPremium = subscriptionActive;
57
61
 
58
- // RevenueCat entitlement info
59
- const premiumEntitlement = customerInfo?.entitlements.active["premium"];
60
- const expiresAtIso = premiumEntitlement?.expirationDate || null;
62
+ // RevenueCat entitlement info - dynamically using configured entitlementId
63
+ const entitlementId = SubscriptionManager.getEntitlementId() || "premium";
64
+ const premiumEntitlement = customerInfo?.entitlements.active[entitlementId];
65
+
66
+ // Prefer expiration date from useSubscriptionStatus (checkPremiumStatus)
67
+ // as it is already processed and typed. Fallback to CustomerInfo ISO string.
68
+ const expiresAtIso = statusExpirationDate
69
+ ? statusExpirationDate.toISOString()
70
+ : premiumEntitlement?.expirationDate || null;
71
+
61
72
  const willRenew = premiumEntitlement?.willRenew || false;
62
73
  const purchasedAtIso = convertPurchasedAt(credits?.purchasedAt);
63
74
 
@@ -53,6 +53,11 @@ export interface IRevenueCatService {
53
53
  */
54
54
  reset(): Promise<void>;
55
55
 
56
+ /**
57
+ * Get current customer info
58
+ */
59
+ getCustomerInfo(): Promise<CustomerInfo | null>;
60
+
56
61
  /**
57
62
  * Get RevenueCat API key for current platform
58
63
  */
@@ -3,7 +3,7 @@
3
3
  * Handles package operations (fetch, purchase, restore, premium status)
4
4
  */
5
5
 
6
- import type { PurchasesPackage } from "react-native-purchases";
6
+ import type { PurchasesPackage, CustomerInfo } from "react-native-purchases";
7
7
  import type { IRevenueCatService } from "../../application/ports/IRevenueCatService";
8
8
  import { getPremiumEntitlement } from "../../domain/types/RevenueCatTypes";
9
9
  import {
@@ -126,37 +126,24 @@ export class PackageHandler {
126
126
  }
127
127
  }
128
128
 
129
- async checkPremiumStatus(userId: string): Promise<PremiumStatus> {
130
- if (!this.service?.isInitialized()) {
131
- return { isPremium: false, expirationDate: null };
129
+ checkPremiumStatusFromInfo(customerInfo: CustomerInfo): PremiumStatus {
130
+ const entitlement = getPremiumEntitlement(
131
+ customerInfo,
132
+ this.entitlementId
133
+ );
134
+
135
+ if (entitlement) {
136
+ return {
137
+ isPremium: true,
138
+ expirationDate: entitlement.expirationDate
139
+ ? new Date(entitlement.expirationDate)
140
+ : null,
141
+ };
132
142
  }
133
143
 
134
- try {
135
- const restoreResult = await this.service.restorePurchases(userId);
136
-
137
- if (restoreResult.customerInfo) {
138
- const entitlement = getPremiumEntitlement(
139
- restoreResult.customerInfo,
140
- this.entitlementId
141
- );
142
- if (entitlement) {
143
- return {
144
- isPremium: true,
145
- expirationDate: entitlement.expirationDate
146
- ? new Date(entitlement.expirationDate)
147
- : null,
148
- };
149
- }
150
- }
151
-
152
- return { isPremium: restoreResult.isPremium, expirationDate: null };
153
- } catch (error) {
154
- trackPackageError(error instanceof Error ? error : new Error(String(error)), {
155
- packageName: "subscription",
156
- operation: "check_premium_status",
157
- userId,
158
- });
159
- return { isPremium: false, expirationDate: null };
160
- }
144
+ return {
145
+ isPremium: !!customerInfo.entitlements.active[this.entitlementId],
146
+ expirationDate: null,
147
+ };
161
148
  }
162
149
  }
@@ -107,6 +107,10 @@ class SubscriptionManagerImpl {
107
107
  this.initCache.getCurrentUserId() === userId;
108
108
  }
109
109
 
110
+ getEntitlementId(): string | null {
111
+ return this.managerConfig?.config.entitlementIdentifier || null;
112
+ }
113
+
110
114
  async getPackages(): Promise<PurchasesPackage[]> {
111
115
  this.ensureConfigured();
112
116
  if (__DEV__) {
@@ -150,7 +154,13 @@ class SubscriptionManagerImpl {
150
154
  this.ensureConfigured();
151
155
  const userId = this.initCache.getCurrentUserId();
152
156
  if (!userId) return { isPremium: false, expirationDate: null };
153
- return this.packageHandler!.checkPremiumStatus(userId);
157
+
158
+ const customerInfo = await this.serviceInstance?.getCustomerInfo();
159
+ if (customerInfo) {
160
+ return this.packageHandler!.checkPremiumStatusFromInfo(customerInfo);
161
+ }
162
+
163
+ return { isPremium: false, expirationDate: null };
154
164
  }
155
165
 
156
166
  async reset(): Promise<void> {
@@ -193,7 +193,12 @@ export async function initializeSDK(
193
193
  appUserID: userId,
194
194
  });
195
195
  }
196
- await Purchases.configure({ apiKey: key, appUserID: userId });
196
+ await Purchases.configure({
197
+ apiKey: key,
198
+ appUserID: userId,
199
+ // Disable StoreKit 2 to prevent Apple Sign In dialog on simulator
200
+ usesStoreKit2IfAvailable: false,
201
+ });
197
202
  isPurchasesConfigured = true;
198
203
  deps.setInitialized(true);
199
204
  deps.setCurrentUserId(userId);
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import Purchases from "react-native-purchases";
7
- import type { PurchasesOffering, PurchasesPackage } from "react-native-purchases";
7
+ import type { PurchasesOffering, PurchasesPackage, CustomerInfo } from "react-native-purchases";
8
8
  import type {
9
9
  IRevenueCatService,
10
10
  InitializeResult,
@@ -129,6 +129,13 @@ export class RevenueCatService implements IRevenueCatService {
129
129
  );
130
130
  }
131
131
 
132
+ async getCustomerInfo(): Promise<CustomerInfo | null> {
133
+ if (!this.isInitialized()) {
134
+ return null;
135
+ }
136
+ return Purchases.getCustomerInfo();
137
+ }
138
+
132
139
  async reset(): Promise<void> {
133
140
  if (!this.isInitialized()) {
134
141
  return;