@umituz/react-native-subscription 2.24.16 → 2.24.17
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 +1 -1
- package/src/infrastructure/services/CreditsInitializer.ts +12 -2
- package/src/infrastructure/services/SubscriptionInitializer.ts +47 -2
- package/src/revenuecat/domain/value-objects/RevenueCatConfig.ts +2 -1
- package/src/revenuecat/infrastructure/utils/PremiumStatusSyncer.ts +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.24.
|
|
3
|
+
"version": "2.24.17",
|
|
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",
|
|
@@ -122,9 +122,19 @@ export async function initializeCreditsTransaction(
|
|
|
122
122
|
? [...(existing?.purchaseHistory || []), purchaseMetadata].slice(-10)
|
|
123
123
|
: existing?.purchaseHistory;
|
|
124
124
|
|
|
125
|
-
// Determine subscription status
|
|
125
|
+
// Determine subscription status based on isPremium and willRenew
|
|
126
126
|
const isPremium = metadata?.isPremium ?? true;
|
|
127
|
-
const
|
|
127
|
+
const willRenew = metadata?.willRenew;
|
|
128
|
+
|
|
129
|
+
// Status logic: canceled if premium but willRenew=false, expired if not premium, active otherwise
|
|
130
|
+
let status: SubscriptionDocStatus;
|
|
131
|
+
if (!isPremium) {
|
|
132
|
+
status = "expired";
|
|
133
|
+
} else if (willRenew === false) {
|
|
134
|
+
status = "canceled";
|
|
135
|
+
} else {
|
|
136
|
+
status = "active";
|
|
137
|
+
}
|
|
128
138
|
|
|
129
139
|
// Build credits data (Single Source of Truth)
|
|
130
140
|
const creditsData: Record<string, unknown> = {
|
|
@@ -104,9 +104,54 @@ export const initializeSubscription = async (config: SubscriptionInitConfig): Pr
|
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
/** Sync premium status changes (including cancellation) to Firestore */
|
|
108
|
+
const onPremiumStatusChanged = async (
|
|
109
|
+
userId: string,
|
|
110
|
+
isPremium: boolean,
|
|
111
|
+
productId?: string,
|
|
112
|
+
expiresAt?: string,
|
|
113
|
+
willRenew?: boolean
|
|
114
|
+
) => {
|
|
115
|
+
if (__DEV__) {
|
|
116
|
+
console.log('[SubscriptionInitializer] onPremiumStatusChanged:', { userId, isPremium, productId, willRenew });
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const revenueCatData: RevenueCatData = {
|
|
120
|
+
expirationDate: expiresAt ?? null,
|
|
121
|
+
willRenew: willRenew ?? false,
|
|
122
|
+
isPremium,
|
|
123
|
+
};
|
|
124
|
+
await getCreditsRepository().initializeCredits(
|
|
125
|
+
userId,
|
|
126
|
+
`status_sync_${Date.now()}`,
|
|
127
|
+
productId,
|
|
128
|
+
"settings" as any,
|
|
129
|
+
revenueCatData
|
|
130
|
+
);
|
|
131
|
+
if (__DEV__) {
|
|
132
|
+
console.log('[SubscriptionInitializer] Premium status synced to Firestore');
|
|
133
|
+
}
|
|
134
|
+
onCreditsUpdated?.(userId);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (__DEV__) {
|
|
137
|
+
console.error('[SubscriptionInitializer] Premium status sync failed:', error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
107
142
|
SubscriptionManager.configure({
|
|
108
|
-
config: {
|
|
109
|
-
|
|
143
|
+
config: {
|
|
144
|
+
apiKey: key,
|
|
145
|
+
testStoreKey,
|
|
146
|
+
entitlementIdentifier: entitlementId,
|
|
147
|
+
consumableProductIdentifiers: [creditPackages?.identifierPattern || "credit"],
|
|
148
|
+
onPurchaseCompleted: onPurchase,
|
|
149
|
+
onRenewalDetected: onRenewal,
|
|
150
|
+
onPremiumStatusChanged,
|
|
151
|
+
onCreditsUpdated,
|
|
152
|
+
},
|
|
153
|
+
apiKey: key,
|
|
154
|
+
getAnonymousUserId,
|
|
110
155
|
});
|
|
111
156
|
|
|
112
157
|
const userId = await waitForAuthState(getFirebaseAuth, authStateTimeoutMs);
|
|
@@ -19,7 +19,8 @@ export interface RevenueCatConfig {
|
|
|
19
19
|
userId: string,
|
|
20
20
|
isPremium: boolean,
|
|
21
21
|
productId?: string,
|
|
22
|
-
expiresAt?: string
|
|
22
|
+
expiresAt?: string,
|
|
23
|
+
willRenew?: boolean
|
|
23
24
|
) => Promise<void> | void;
|
|
24
25
|
/** Callback for purchase completion */
|
|
25
26
|
onPurchaseCompleted?: (
|
|
@@ -27,10 +27,11 @@ export async function syncPremiumStatus(
|
|
|
27
27
|
userId,
|
|
28
28
|
true,
|
|
29
29
|
premiumEntitlement.productIdentifier,
|
|
30
|
-
premiumEntitlement.expirationDate ?? undefined
|
|
30
|
+
premiumEntitlement.expirationDate ?? undefined,
|
|
31
|
+
premiumEntitlement.willRenew
|
|
31
32
|
);
|
|
32
33
|
} else {
|
|
33
|
-
await config.onPremiumStatusChanged(userId, false);
|
|
34
|
+
await config.onPremiumStatusChanged(userId, false, undefined, undefined, undefined);
|
|
34
35
|
}
|
|
35
36
|
} catch {
|
|
36
37
|
// Silent error handling
|