@umituz/react-native-subscription 2.14.57 → 2.14.58

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.57",
3
+ "version": "2.14.58",
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",
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ export {
33
33
  export {
34
34
  initializeSubscription,
35
35
  type SubscriptionInitConfig,
36
+ type CreditPackageConfig,
36
37
  } from "./infrastructure/services/SubscriptionInitializer";
37
38
 
38
39
  export { useSubscription } from "./presentation/hooks/useSubscription";
@@ -4,8 +4,9 @@
4
4
  * Apps just call initializeSubscription with config
5
5
  */
6
6
 
7
+ import type { CustomerInfo } from "react-native-purchases";
7
8
  import type { CreditsConfig } from "../../domain/entities/Credits";
8
- import { configureCreditsRepository } from "../repositories/CreditsRepositoryProvider";
9
+ import { configureCreditsRepository, getCreditsRepository } from "../repositories/CreditsRepositoryProvider";
9
10
  import { SubscriptionManager } from "../../revenuecat/infrastructure/managers/SubscriptionManager";
10
11
  import { configureAuthProvider } from "../../presentation/hooks/useAuthAwarePurchase";
11
12
 
@@ -14,6 +15,13 @@ export interface FirebaseAuthLike {
14
15
  onAuthStateChanged: (callback: (user: { uid: string; isAnonymous: boolean } | null) => void) => () => void;
15
16
  }
16
17
 
18
+ export interface CreditPackageConfig {
19
+ /** Identifier pattern to match credit packages (e.g., "credit") */
20
+ identifierPattern?: string;
21
+ /** Map of productId to credit amounts */
22
+ amounts?: Record<string, number>;
23
+ }
24
+
17
25
  export interface SubscriptionInitConfig {
18
26
  apiKey: string;
19
27
  testStoreKey?: string;
@@ -24,6 +32,8 @@ export interface SubscriptionInitConfig {
24
32
  showAuthModal: () => void;
25
33
  onCreditsUpdated?: (userId: string) => void;
26
34
  onCreditRenewal?: (userId: string, productId: string, renewalId: string) => Promise<void>;
35
+ /** Credit package configuration for consumable purchases */
36
+ creditPackages?: CreditPackageConfig;
27
37
  timeoutMs?: number;
28
38
  authStateTimeoutMs?: number;
29
39
  }
@@ -59,6 +69,15 @@ const waitForAuthState = async (
59
69
  });
60
70
  };
61
71
 
72
+ /**
73
+ * Check if a product is a credit package
74
+ */
75
+ const isCreditPackage = (productId: string, pattern?: string): boolean => {
76
+ const patternToUse = pattern || "credit";
77
+ return productId.toLowerCase().includes(patternToUse.toLowerCase());
78
+ };
79
+
80
+
62
81
  export const initializeSubscription = async (
63
82
  config: SubscriptionInitConfig,
64
83
  ): Promise<void> => {
@@ -72,6 +91,7 @@ export const initializeSubscription = async (
72
91
  showAuthModal,
73
92
  onCreditsUpdated,
74
93
  onCreditRenewal,
94
+ creditPackages,
75
95
  timeoutMs = 10000,
76
96
  authStateTimeoutMs = 2000,
77
97
  } = config;
@@ -82,13 +102,62 @@ export const initializeSubscription = async (
82
102
 
83
103
  configureCreditsRepository(credits);
84
104
 
105
+ // Build consumable product identifiers from credit package pattern
106
+ const consumableIdentifiers: string[] = [];
107
+ if (creditPackages?.identifierPattern) {
108
+ consumableIdentifiers.push(creditPackages.identifierPattern);
109
+ } else {
110
+ consumableIdentifiers.push("credit");
111
+ }
112
+
113
+ // Create onPurchaseCompleted handler for credit packages
114
+ const handlePurchaseCompleted = async (
115
+ userId: string,
116
+ productId: string,
117
+ _customerInfo: CustomerInfo
118
+ ): Promise<void> => {
119
+ const isCredit = isCreditPackage(productId, creditPackages?.identifierPattern);
120
+
121
+ if (!isCredit) {
122
+ return;
123
+ }
124
+
125
+ try {
126
+ const repository = getCreditsRepository();
127
+
128
+ // Create a unique purchase ID to prevent duplicate credit additions
129
+ const purchaseId = `purchase_${productId}_${Date.now()}`;
130
+
131
+ await repository.initializeCredits(userId, purchaseId, productId);
132
+
133
+ if (__DEV__) {
134
+ console.log("[SubscriptionInitializer] Credits added for purchase:", {
135
+ userId,
136
+ productId,
137
+ purchaseId,
138
+ });
139
+ }
140
+
141
+ // Notify about credits update for cache invalidation
142
+ if (onCreditsUpdated) {
143
+ onCreditsUpdated(userId);
144
+ }
145
+ } catch (error) {
146
+ if (__DEV__) {
147
+ console.error("[SubscriptionInitializer] Failed to add credits:", error);
148
+ }
149
+ }
150
+ };
151
+
85
152
  SubscriptionManager.configure({
86
153
  config: {
87
154
  apiKey,
88
155
  testStoreKey,
89
156
  entitlementIdentifier: entitlementId,
157
+ consumableProductIdentifiers: consumableIdentifiers,
90
158
  onCreditRenewal,
91
159
  onCreditsUpdated,
160
+ onPurchaseCompleted: handlePurchaseCompleted,
92
161
  },
93
162
  apiKey,
94
163
  getAnonymousUserId,
@@ -54,6 +54,12 @@ export async function handlePurchase(
54
54
  const customerInfo = purchaseResult.customerInfo;
55
55
 
56
56
  if (isConsumable) {
57
+ await notifyPurchaseCompleted(
58
+ deps.config,
59
+ userId,
60
+ pkg.product.identifier,
61
+ customerInfo
62
+ );
57
63
  return {
58
64
  success: true,
59
65
  isPremium: false,