@umituz/react-native-subscription 2.17.4 → 2.17.5

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.17.4",
3
+ "version": "2.17.5",
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",
@@ -10,11 +10,39 @@ import { SubscriptionManager } from "../../infrastructure/managers/SubscriptionM
10
10
  import { SUBSCRIPTION_QUERY_KEYS } from "./subscriptionQueryKeys";
11
11
  import { creditsQueryKeys } from "../../../presentation/hooks/useCredits";
12
12
 
13
+ declare const __DEV__: boolean;
14
+
13
15
  export interface PurchaseResult {
14
16
  success: boolean;
15
17
  productId: string;
16
18
  }
17
19
 
20
+ /**
21
+ * Global purchase lock to prevent double purchases
22
+ */
23
+ let purchaseInProgress = false;
24
+ let purchaseProductId: string | null = null;
25
+
26
+ export const purchaseLock = {
27
+ isLocked: () => purchaseInProgress,
28
+ getProductId: () => purchaseProductId,
29
+ acquire: (productId: string): boolean => {
30
+ if (purchaseInProgress) {
31
+ if (__DEV__) {
32
+ console.log('[PurchaseLock] Already in progress:', purchaseProductId);
33
+ }
34
+ return false;
35
+ }
36
+ purchaseInProgress = true;
37
+ purchaseProductId = productId;
38
+ return true;
39
+ },
40
+ release: () => {
41
+ purchaseInProgress = false;
42
+ purchaseProductId = null;
43
+ },
44
+ };
45
+
18
46
  /**
19
47
  * Purchase a subscription package
20
48
  * Credits are initialized by CustomerInfoListener when entitlement becomes active
@@ -30,6 +58,14 @@ export const usePurchasePackage = (userId: string | undefined) => {
30
58
 
31
59
  const productId = pkg.product.identifier;
32
60
 
61
+ // Check and acquire purchase lock
62
+ if (!purchaseLock.acquire(productId)) {
63
+ if (__DEV__) {
64
+ console.log('[DEBUG usePurchasePackage] Skipping - purchase already in progress');
65
+ }
66
+ return { success: false, productId };
67
+ }
68
+
33
69
  if (__DEV__) {
34
70
  console.log('[DEBUG usePurchasePackage] Starting purchase:', {
35
71
  packageId: pkg.identifier,
@@ -38,27 +74,31 @@ export const usePurchasePackage = (userId: string | undefined) => {
38
74
  });
39
75
  }
40
76
 
41
- const success = await SubscriptionManager.purchasePackage(pkg);
77
+ try {
78
+ const success = await SubscriptionManager.purchasePackage(pkg);
42
79
 
43
- if (success) {
44
- if (__DEV__) {
45
- console.log('[DEBUG usePurchasePackage] Purchase successful:', {
46
- packageId: pkg.identifier,
47
- productId,
48
- userId,
49
- });
80
+ if (success) {
81
+ if (__DEV__) {
82
+ console.log('[DEBUG usePurchasePackage] Purchase successful:', {
83
+ packageId: pkg.identifier,
84
+ productId,
85
+ userId,
86
+ });
87
+ }
88
+ // Credits will be initialized by CustomerInfoListener
89
+ } else {
90
+ if (__DEV__) {
91
+ console.log('[DEBUG usePurchasePackage] Purchase failed:', {
92
+ packageId: pkg.identifier,
93
+ userId,
94
+ });
95
+ }
50
96
  }
51
- // Credits will be initialized by CustomerInfoListener
52
- } else {
53
- if (__DEV__) {
54
- console.log('[DEBUG usePurchasePackage] Purchase failed:', {
55
- packageId: pkg.identifier,
56
- userId,
57
- });
58
- }
59
- }
60
97
 
61
- return { success, productId };
98
+ return { success, productId };
99
+ } finally {
100
+ purchaseLock.release();
101
+ }
62
102
  },
63
103
  onSuccess: (result) => {
64
104
  if (result.success) {