@umituz/react-native-subscription 2.27.12 → 2.27.14
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.27.
|
|
3
|
+
"version": "2.27.14",
|
|
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
|
@@ -97,6 +97,15 @@ export * from "./utils";
|
|
|
97
97
|
// RevenueCat
|
|
98
98
|
export * from "./revenuecat";
|
|
99
99
|
|
|
100
|
+
// App Service Helpers (for configureAppServices)
|
|
101
|
+
export {
|
|
102
|
+
createCreditService,
|
|
103
|
+
createPaywallService,
|
|
104
|
+
type CreditServiceConfig,
|
|
105
|
+
type ICreditService,
|
|
106
|
+
type IPaywallService,
|
|
107
|
+
} from "./infrastructure/services/app-service-helpers";
|
|
108
|
+
|
|
100
109
|
// Init Module Factory
|
|
101
110
|
export {
|
|
102
111
|
createSubscriptionInitModule,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Service Helpers
|
|
3
|
+
* Creates ready-to-use service implementations for configureAppServices
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getCreditsRepository } from "../repositories/CreditsRepositoryProvider";
|
|
7
|
+
import { getRevenueCatService } from "../../revenuecat/infrastructure/services/RevenueCatService";
|
|
8
|
+
import { getPremiumEntitlement } from "../../revenuecat/domain/types/RevenueCatTypes";
|
|
9
|
+
import { creditsQueryKeys } from "../../presentation/hooks/useCredits";
|
|
10
|
+
import { paywallControl } from "../../presentation/hooks/usePaywallVisibility";
|
|
11
|
+
import {
|
|
12
|
+
getGlobalQueryClient,
|
|
13
|
+
hasGlobalQueryClient,
|
|
14
|
+
} from "@umituz/react-native-design-system";
|
|
15
|
+
import {
|
|
16
|
+
useAuthStore,
|
|
17
|
+
selectUserId,
|
|
18
|
+
} from "@umituz/react-native-auth";
|
|
19
|
+
|
|
20
|
+
declare const __DEV__: boolean;
|
|
21
|
+
|
|
22
|
+
export interface CreditServiceConfig {
|
|
23
|
+
entitlementId: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ICreditService {
|
|
27
|
+
checkCredits: (cost: number) => Promise<boolean>;
|
|
28
|
+
deductCredits: (cost: number) => Promise<void>;
|
|
29
|
+
refundCredits: (amount: number, error?: unknown) => Promise<void>;
|
|
30
|
+
calculateCost: (capability: string, metadata?: Record<string, unknown>) => number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface IPaywallService {
|
|
34
|
+
showPaywall: (requiredCredits: number) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const checkPremiumStatus = async (entitlementId: string): Promise<boolean> => {
|
|
38
|
+
try {
|
|
39
|
+
const rcService = getRevenueCatService();
|
|
40
|
+
if (!rcService) return false;
|
|
41
|
+
|
|
42
|
+
const customerInfo = await rcService.getCustomerInfo();
|
|
43
|
+
if (!customerInfo) return false;
|
|
44
|
+
|
|
45
|
+
return !!getPremiumEntitlement(customerInfo, entitlementId);
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates a credit service implementation
|
|
53
|
+
*/
|
|
54
|
+
export function createCreditService(config: CreditServiceConfig): ICreditService {
|
|
55
|
+
const { entitlementId } = config;
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
checkCredits: async (cost: number): Promise<boolean> => {
|
|
59
|
+
const userId = selectUserId(useAuthStore.getState());
|
|
60
|
+
if (!userId) return false;
|
|
61
|
+
|
|
62
|
+
// Premium users bypass credit check
|
|
63
|
+
if (await checkPremiumStatus(entitlementId)) return true;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const repository = getCreditsRepository();
|
|
67
|
+
const result = await repository.getCredits(userId);
|
|
68
|
+
if (!result.success || !result.data) return false;
|
|
69
|
+
return (result.data.credits ?? 0) >= cost;
|
|
70
|
+
} catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
deductCredits: async (cost: number): Promise<void> => {
|
|
76
|
+
const userId = selectUserId(useAuthStore.getState());
|
|
77
|
+
if (!userId) return;
|
|
78
|
+
|
|
79
|
+
// Premium users don't consume credits
|
|
80
|
+
if (await checkPremiumStatus(entitlementId)) return;
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const repository = getCreditsRepository();
|
|
84
|
+
await repository.deductCredit(userId, cost);
|
|
85
|
+
|
|
86
|
+
if (hasGlobalQueryClient()) {
|
|
87
|
+
getGlobalQueryClient().invalidateQueries({
|
|
88
|
+
queryKey: creditsQueryKeys.user(userId),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
93
|
+
console.error("[CreditService] Deduct error:", error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
refundCredits: async (): Promise<void> => {
|
|
99
|
+
// No-op for now
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
calculateCost: (): number => 1,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Creates a paywall service implementation
|
|
108
|
+
*/
|
|
109
|
+
export function createPaywallService(): IPaywallService {
|
|
110
|
+
return {
|
|
111
|
+
showPaywall: () => paywallControl.open(),
|
|
112
|
+
};
|
|
113
|
+
}
|