@umituz/react-native-subscription 2.37.70 → 2.37.71
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.37.
|
|
3
|
+
"version": "2.37.71",
|
|
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",
|
|
@@ -8,8 +8,9 @@ import { refundCreditsOperation } from "../application/RefundCreditsCommand";
|
|
|
8
8
|
import { PURCHASE_TYPE, type PurchaseType } from "../../subscription/core/SubscriptionConstants";
|
|
9
9
|
import { requireFirestore, buildDocRef, type CollectionConfig } from "../../../shared/infrastructure/firestore";
|
|
10
10
|
import { fetchCredits, checkHasCredits } from "./operations/CreditsFetcher";
|
|
11
|
-
import { syncExpiredStatus, syncPremiumMetadata, type PremiumMetadata } from "./operations/CreditsWriter";
|
|
11
|
+
import { syncExpiredStatus, syncPremiumMetadata, createRecoveryCreditsDocument, type PremiumMetadata } from "./operations/CreditsWriter";
|
|
12
12
|
import { initializeCreditsWithRetry } from "./operations/CreditsInitializer";
|
|
13
|
+
import { calculateCreditLimit } from "../application/CreditLimitCalculator";
|
|
13
14
|
|
|
14
15
|
export class CreditsRepository extends BaseRepository {
|
|
15
16
|
constructor(private config: CreditsConfig) {
|
|
@@ -79,6 +80,25 @@ export class CreditsRepository extends BaseRepository {
|
|
|
79
80
|
const db = requireFirestore();
|
|
80
81
|
await syncPremiumMetadata(this.getRef(db, userId), metadata);
|
|
81
82
|
}
|
|
83
|
+
|
|
84
|
+
async ensurePremiumCreditsExist(
|
|
85
|
+
userId: string,
|
|
86
|
+
productId: string,
|
|
87
|
+
willRenew: boolean,
|
|
88
|
+
expirationDate: string | null,
|
|
89
|
+
periodType: string | null,
|
|
90
|
+
): Promise<boolean> {
|
|
91
|
+
const db = requireFirestore();
|
|
92
|
+
const creditLimit = calculateCreditLimit(productId, this.config);
|
|
93
|
+
return createRecoveryCreditsDocument(
|
|
94
|
+
this.getRef(db, userId),
|
|
95
|
+
creditLimit,
|
|
96
|
+
productId,
|
|
97
|
+
willRenew,
|
|
98
|
+
expirationDate,
|
|
99
|
+
periodType,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
82
102
|
}
|
|
83
103
|
|
|
84
104
|
export function createCreditsRepository(config: CreditsConfig): CreditsRepository {
|
|
@@ -5,6 +5,7 @@ import { SUBSCRIPTION_STATUS } from "../../../subscription/core/SubscriptionCons
|
|
|
5
5
|
import { resolveSubscriptionStatus } from "../../../subscription/core/SubscriptionStatus";
|
|
6
6
|
import { toTimestamp } from "../../../../shared/utils/dateConverter";
|
|
7
7
|
import { isPast } from "../../../../utils/dateUtils";
|
|
8
|
+
import { getAppVersion, validatePlatform } from "../../../../utils/appUtils";
|
|
8
9
|
|
|
9
10
|
export async function syncExpiredStatus(ref: DocumentReference): Promise<void> {
|
|
10
11
|
const doc = await getDoc(ref);
|
|
@@ -62,3 +63,52 @@ export async function syncPremiumMetadata(
|
|
|
62
63
|
...(metadata.ownershipType && { ownershipType: metadata.ownershipType }),
|
|
63
64
|
}, { merge: true });
|
|
64
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Recovery: creates a credits document for premium users who don't have one.
|
|
69
|
+
* This handles edge cases like test store purchases, reinstalls, or failed initializations.
|
|
70
|
+
* Returns true if a new document was created, false if one already existed.
|
|
71
|
+
*/
|
|
72
|
+
export async function createRecoveryCreditsDocument(
|
|
73
|
+
ref: DocumentReference,
|
|
74
|
+
creditLimit: number,
|
|
75
|
+
productId: string,
|
|
76
|
+
willRenew: boolean,
|
|
77
|
+
expirationDate: string | null,
|
|
78
|
+
periodType: string | null,
|
|
79
|
+
): Promise<boolean> {
|
|
80
|
+
const doc = await getDoc(ref);
|
|
81
|
+
if (doc.exists()) return false;
|
|
82
|
+
|
|
83
|
+
const platform = validatePlatform();
|
|
84
|
+
const appVersion = getAppVersion();
|
|
85
|
+
|
|
86
|
+
const isExpired = expirationDate ? isPast(expirationDate) : false;
|
|
87
|
+
const status = resolveSubscriptionStatus({
|
|
88
|
+
isPremium: true,
|
|
89
|
+
willRenew,
|
|
90
|
+
isExpired,
|
|
91
|
+
periodType: periodType ?? undefined,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const expirationTimestamp = expirationDate ? toTimestamp(expirationDate) : null;
|
|
95
|
+
|
|
96
|
+
await setDoc(ref, {
|
|
97
|
+
credits: creditLimit,
|
|
98
|
+
creditLimit,
|
|
99
|
+
isPremium: true,
|
|
100
|
+
status,
|
|
101
|
+
willRenew,
|
|
102
|
+
productId,
|
|
103
|
+
platform,
|
|
104
|
+
appVersion,
|
|
105
|
+
processedPurchases: [],
|
|
106
|
+
purchaseHistory: [],
|
|
107
|
+
createdAt: serverTimestamp(),
|
|
108
|
+
lastUpdatedAt: serverTimestamp(),
|
|
109
|
+
recoveryInitialized: true,
|
|
110
|
+
...(expirationTimestamp && { expirationDate: expirationTimestamp }),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
@@ -19,7 +19,24 @@ export const handlePremiumStatusSync = async (
|
|
|
19
19
|
store?: string | null,
|
|
20
20
|
ownershipType?: string | null
|
|
21
21
|
): Promise<void> => {
|
|
22
|
-
|
|
22
|
+
const repo = getCreditsRepository();
|
|
23
|
+
|
|
24
|
+
// Recovery: if premium user has no credits document, create one.
|
|
25
|
+
// Handles edge cases like test store, reinstalls, or failed purchase initialization.
|
|
26
|
+
if (isPremium) {
|
|
27
|
+
const created = await repo.ensurePremiumCreditsExist(
|
|
28
|
+
userId,
|
|
29
|
+
productId,
|
|
30
|
+
willRenew,
|
|
31
|
+
expiresAt,
|
|
32
|
+
periodType,
|
|
33
|
+
);
|
|
34
|
+
if (__DEV__ && created) {
|
|
35
|
+
console.log('[handlePremiumStatusSync] Recovery: created missing credits document for premium user', { userId, productId });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await repo.syncPremiumMetadata(userId, {
|
|
23
40
|
isPremium,
|
|
24
41
|
willRenew,
|
|
25
42
|
expirationDate: expiresAt,
|