@umituz/react-native-subscription 2.14.57 → 2.14.59
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.
|
|
3
|
+
"version": "2.14.59",
|
|
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
|
@@ -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;
|
|
@@ -22,8 +30,10 @@ export interface SubscriptionInitConfig {
|
|
|
22
30
|
getAnonymousUserId: () => Promise<string>;
|
|
23
31
|
getFirebaseAuth: () => FirebaseAuthLike | null;
|
|
24
32
|
showAuthModal: () => void;
|
|
33
|
+
/** Callback after credits are updated (for cache invalidation) */
|
|
25
34
|
onCreditsUpdated?: (userId: string) => void;
|
|
26
|
-
|
|
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> => {
|
|
@@ -71,7 +90,7 @@ export const initializeSubscription = async (
|
|
|
71
90
|
getFirebaseAuth,
|
|
72
91
|
showAuthModal,
|
|
73
92
|
onCreditsUpdated,
|
|
74
|
-
|
|
93
|
+
creditPackages,
|
|
75
94
|
timeoutMs = 10000,
|
|
76
95
|
authStateTimeoutMs = 2000,
|
|
77
96
|
} = config;
|
|
@@ -82,13 +101,87 @@ export const initializeSubscription = async (
|
|
|
82
101
|
|
|
83
102
|
configureCreditsRepository(credits);
|
|
84
103
|
|
|
104
|
+
// Build consumable product identifiers from credit package pattern
|
|
105
|
+
const consumableIdentifiers: string[] = [];
|
|
106
|
+
if (creditPackages?.identifierPattern) {
|
|
107
|
+
consumableIdentifiers.push(creditPackages.identifierPattern);
|
|
108
|
+
} else {
|
|
109
|
+
consumableIdentifiers.push("credit");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Create onPurchaseCompleted handler for credit packages
|
|
113
|
+
const handlePurchaseCompleted = async (
|
|
114
|
+
userId: string,
|
|
115
|
+
productId: string,
|
|
116
|
+
_customerInfo: CustomerInfo
|
|
117
|
+
): Promise<void> => {
|
|
118
|
+
const isCredit = isCreditPackage(productId, creditPackages?.identifierPattern);
|
|
119
|
+
|
|
120
|
+
if (!isCredit) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const repository = getCreditsRepository();
|
|
126
|
+
const purchaseId = `purchase_${productId}_${Date.now()}`;
|
|
127
|
+
|
|
128
|
+
await repository.initializeCredits(userId, purchaseId, productId);
|
|
129
|
+
|
|
130
|
+
if (__DEV__) {
|
|
131
|
+
console.log("[SubscriptionInitializer] Credits added for purchase:", {
|
|
132
|
+
userId,
|
|
133
|
+
productId,
|
|
134
|
+
purchaseId,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (onCreditsUpdated) {
|
|
139
|
+
onCreditsUpdated(userId);
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (__DEV__) {
|
|
143
|
+
console.error("[SubscriptionInitializer] Failed to add credits:", error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Create onCreditRenewal handler for subscription renewals
|
|
149
|
+
const handleCreditRenewal = async (
|
|
150
|
+
userId: string,
|
|
151
|
+
productId: string,
|
|
152
|
+
renewalId: string
|
|
153
|
+
): Promise<void> => {
|
|
154
|
+
try {
|
|
155
|
+
const repository = getCreditsRepository();
|
|
156
|
+
await repository.initializeCredits(userId, renewalId, productId);
|
|
157
|
+
|
|
158
|
+
if (__DEV__) {
|
|
159
|
+
console.log("[SubscriptionInitializer] Credits renewed:", {
|
|
160
|
+
userId,
|
|
161
|
+
productId,
|
|
162
|
+
renewalId,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (onCreditsUpdated) {
|
|
167
|
+
onCreditsUpdated(userId);
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (__DEV__) {
|
|
171
|
+
console.error("[SubscriptionInitializer] Failed to renew credits:", error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
85
176
|
SubscriptionManager.configure({
|
|
86
177
|
config: {
|
|
87
178
|
apiKey,
|
|
88
179
|
testStoreKey,
|
|
89
180
|
entitlementIdentifier: entitlementId,
|
|
90
|
-
|
|
181
|
+
consumableProductIdentifiers: consumableIdentifiers,
|
|
182
|
+
onCreditRenewal: handleCreditRenewal,
|
|
91
183
|
onCreditsUpdated,
|
|
184
|
+
onPurchaseCompleted: handlePurchaseCompleted,
|
|
92
185
|
},
|
|
93
186
|
apiKey,
|
|
94
187
|
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,
|