@umituz/react-native-subscription 2.37.71 → 2.37.73
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.73",
|
|
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,6 +10,8 @@ import { handleExpiredSubscription, handlePremiumStatusSync } from "./statusChan
|
|
|
10
10
|
import type { PackageType } from "../../revenuecat/core/types";
|
|
11
11
|
|
|
12
12
|
export class SubscriptionSyncProcessor {
|
|
13
|
+
private purchaseInProgress = false;
|
|
14
|
+
|
|
13
15
|
constructor(
|
|
14
16
|
private entitlementId: string,
|
|
15
17
|
private getAnonymousUserId: () => Promise<string>
|
|
@@ -35,43 +37,53 @@ export class SubscriptionSyncProcessor {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
async processPurchase(userId: string, productId: string, customerInfo: CustomerInfo, source?: PurchaseSource, packageType?: PackageType | null) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
this.purchaseInProgress = true;
|
|
41
|
+
try {
|
|
42
|
+
const revenueCatData = extractRevenueCatData(customerInfo, this.entitlementId);
|
|
43
|
+
revenueCatData.packageType = packageType ?? null;
|
|
44
|
+
revenueCatData.revenueCatUserId = await this.getRevenueCatAppUserId();
|
|
45
|
+
const purchaseId = generatePurchaseId(revenueCatData.originalTransactionId, productId);
|
|
46
|
+
|
|
47
|
+
const creditsUserId = await this.getCreditsUserId(userId);
|
|
48
|
+
|
|
49
|
+
await getCreditsRepository().initializeCredits(
|
|
50
|
+
creditsUserId,
|
|
51
|
+
purchaseId,
|
|
52
|
+
productId,
|
|
53
|
+
source ?? PURCHASE_SOURCE.SETTINGS,
|
|
54
|
+
revenueCatData,
|
|
55
|
+
PURCHASE_TYPE.INITIAL
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
emitCreditsUpdated(creditsUserId);
|
|
59
|
+
} finally {
|
|
60
|
+
this.purchaseInProgress = false;
|
|
61
|
+
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
async processRenewal(userId: string, productId: string, newExpirationDate: string, customerInfo: CustomerInfo) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
this.purchaseInProgress = true;
|
|
66
|
+
try {
|
|
67
|
+
const revenueCatData = extractRevenueCatData(customerInfo, this.entitlementId);
|
|
68
|
+
revenueCatData.expirationDate = newExpirationDate ?? revenueCatData.expirationDate;
|
|
69
|
+
revenueCatData.revenueCatUserId = await this.getRevenueCatAppUserId();
|
|
70
|
+
const purchaseId = generateRenewalId(revenueCatData.originalTransactionId, productId, newExpirationDate);
|
|
71
|
+
|
|
72
|
+
const creditsUserId = await this.getCreditsUserId(userId);
|
|
73
|
+
|
|
74
|
+
await getCreditsRepository().initializeCredits(
|
|
75
|
+
creditsUserId,
|
|
76
|
+
purchaseId,
|
|
77
|
+
productId,
|
|
78
|
+
PURCHASE_SOURCE.RENEWAL,
|
|
79
|
+
revenueCatData,
|
|
80
|
+
PURCHASE_TYPE.RENEWAL
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
emitCreditsUpdated(creditsUserId);
|
|
84
|
+
} finally {
|
|
85
|
+
this.purchaseInProgress = false;
|
|
86
|
+
}
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
async processStatusChange(
|
|
@@ -82,6 +94,16 @@ export class SubscriptionSyncProcessor {
|
|
|
82
94
|
willRenew?: boolean,
|
|
83
95
|
periodType?: PeriodType
|
|
84
96
|
) {
|
|
97
|
+
// Skip if a purchase is already handling the credits document.
|
|
98
|
+
// Both PurchaseExecutor and CustomerInfoListener fire after a purchase —
|
|
99
|
+
// the purchase handler writes credits + metadata, so the status handler can skip.
|
|
100
|
+
if (this.purchaseInProgress) {
|
|
101
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
102
|
+
console.log("[SubscriptionSyncProcessor] Skipping status change - purchase in progress");
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
85
107
|
const creditsUserId = await this.getCreditsUserId(userId);
|
|
86
108
|
|
|
87
109
|
if (!isPremium && productId) {
|
|
@@ -90,6 +112,9 @@ export class SubscriptionSyncProcessor {
|
|
|
90
112
|
}
|
|
91
113
|
|
|
92
114
|
if (!isPremium && !productId) {
|
|
115
|
+
// Cancellation: RevenueCat removed entitlement, no productId available.
|
|
116
|
+
// Must still update Firestore to reflect expired/canceled status.
|
|
117
|
+
await handleExpiredSubscription(creditsUserId);
|
|
93
118
|
return;
|
|
94
119
|
}
|
|
95
120
|
|