@umituz/react-native-subscription 2.27.43 → 2.27.44

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.43",
3
+ "version": "2.27.44",
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",
@@ -19,6 +19,8 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = (props) => {
19
19
  features,
20
20
  heroImage,
21
21
  bestValueIdentifier,
22
+ creditAmounts,
23
+ creditsLabel,
22
24
  source,
23
25
  onPurchaseSuccess,
24
26
  onPurchaseError,
@@ -98,6 +100,8 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = (props) => {
98
100
  features={features ? [...features] : undefined}
99
101
  heroImage={heroImage}
100
102
  bestValueIdentifier={bestValueIdentifier}
103
+ creditAmounts={creditAmounts}
104
+ creditsLabel={creditsLabel}
101
105
  onPurchase={handlePurchase}
102
106
  onRestore={handleRestore}
103
107
  trialEligibility={trialEligibility}
@@ -33,6 +33,10 @@ export interface PaywallContainerProps {
33
33
  readonly heroImage?: ImageSourcePropType;
34
34
  /** Best value package identifier for badge */
35
35
  readonly bestValueIdentifier?: string;
36
+ /** Credit amounts per product identifier */
37
+ readonly creditAmounts?: Record<string, number>;
38
+ /** Credits label text (e.g., "credits") */
39
+ readonly creditsLabel?: string;
36
40
  /** Source of the paywall - affects pending purchase handling */
37
41
  readonly source?: PurchaseSource;
38
42
  /** Callback when purchase succeeds */
@@ -33,6 +33,10 @@ export interface PaywallModalProps {
33
33
  isLoading?: boolean;
34
34
  legalUrls?: PaywallLegalUrls;
35
35
  bestValueIdentifier?: string;
36
+ /** Credit amounts per product identifier */
37
+ creditAmounts?: Record<string, number>;
38
+ /** Credits label text (e.g., "credits") */
39
+ creditsLabel?: string;
36
40
  heroImage?: ImageSourcePropType;
37
41
  onPurchase?: (pkg: PurchasesPackage) => Promise<void | boolean>;
38
42
  onRestore?: () => Promise<void | boolean>;
@@ -43,7 +47,7 @@ export interface PaywallModalProps {
43
47
  }
44
48
 
45
49
  export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
46
- const { visible, onClose, translations, packages = [], features = [], isLoading = false, legalUrls = {}, bestValueIdentifier, heroImage, onPurchase, onRestore, trialEligibility = {}, trialSubtitleText } = props;
50
+ const { visible, onClose, translations, packages = [], features = [], isLoading = false, legalUrls = {}, bestValueIdentifier, creditAmounts, creditsLabel, heroImage, onPurchase, onRestore, trialEligibility = {}, trialSubtitleText } = props;
47
51
  const tokens = useAppDesignTokens();
48
52
  const [selectedPlanId, setSelectedPlanId] = useState<string | null>(null);
49
53
  const [isLocalProcessing, setIsLocalProcessing] = useState(false);
@@ -150,6 +154,8 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
150
154
  isSelected={selectedPlanId === productId}
151
155
  onSelect={() => setSelectedPlanId(productId)}
152
156
  badge={productId === bestValueIdentifier ? translations.bestValueBadgeText : undefined}
157
+ creditAmount={creditAmounts?.[productId]}
158
+ creditsLabel={creditsLabel}
153
159
  hasFreeTrial={hasFreeTrial}
154
160
  trialSubtitleText={hasFreeTrial ? trialSubtitleText : undefined}
155
161
  />
@@ -21,6 +21,10 @@ interface PlanCardProps {
21
21
  onSelect: () => void;
22
22
  /** Badge text (e.g., "Best Value") - NOT for trial */
23
23
  badge?: string;
24
+ /** Credit amount for this plan */
25
+ creditAmount?: number;
26
+ /** Credits label text (e.g., "credits") */
27
+ creditsLabel?: string;
24
28
  /** Whether this plan has a free trial (Apple-compliant display) */
25
29
  hasFreeTrial?: boolean;
26
30
  /** Trial subtitle text (e.g., "7 days free, then billed") - shown as small gray text */
@@ -28,7 +32,7 @@ interface PlanCardProps {
28
32
  }
29
33
 
30
34
  export const PlanCard: React.FC<PlanCardProps> = React.memo(
31
- ({ pkg, isSelected, onSelect, badge, hasFreeTrial, trialSubtitleText }) => {
35
+ ({ pkg, isSelected, onSelect, badge, creditAmount, creditsLabel, hasFreeTrial, trialSubtitleText }) => {
32
36
  const tokens = useAppDesignTokens();
33
37
  const title = pkg.product.title;
34
38
  const price = formatPriceWithPeriod(pkg.product.price, pkg.product.currencyCode, pkg.identifier);
@@ -73,6 +77,13 @@ export const PlanCard: React.FC<PlanCardProps> = React.memo(
73
77
  {title}
74
78
  </AtomicText>
75
79
 
80
+ {/* Credits info */}
81
+ {creditAmount && creditsLabel && (
82
+ <AtomicText type="bodySmall" style={{ color: tokens.colors.textSecondary }}>
83
+ {creditAmount} {creditsLabel}
84
+ </AtomicText>
85
+ )}
86
+
76
87
  {/* Trial info - Apple-compliant: small, gray, subordinate */}
77
88
  {hasFreeTrial && trialSubtitleText && (
78
89
  <AtomicText
@@ -1,4 +1,4 @@
1
- import type { SubscriptionPackageType } from "./packageTypeDetector";
1
+ import { detectPackageType, type SubscriptionPackageType } from "./packageTypeDetector";
2
2
  import type { PackageAllocationMap } from "../domain/entities/Credits";
3
3
 
4
4
  /**
@@ -11,3 +11,31 @@ export function getCreditAllocation(
11
11
  if (packageType === "unknown" || !allocations) return null;
12
12
  return allocations[packageType]?.credits ?? null;
13
13
  }
14
+
15
+ /**
16
+ * Create credit amounts mapping for PaywallModal from RevenueCat packages
17
+ * Maps product.identifier to credit amount using dynamic allocations
18
+ */
19
+ export function createCreditAmountsFromPackages(
20
+ packages: Array<{ product: { identifier: string } }>,
21
+ allocations?: PackageAllocationMap
22
+ ): Record<string, number> {
23
+ const result: Record<string, number> = {};
24
+
25
+ if (!allocations) return result;
26
+
27
+ for (const pkg of packages) {
28
+ const identifier = pkg?.product?.identifier;
29
+
30
+ if (!identifier) continue;
31
+
32
+ const packageType = detectPackageType(identifier);
33
+ const credits = getCreditAllocation(packageType, allocations);
34
+
35
+ if (credits !== null) {
36
+ result[identifier] = credits;
37
+ }
38
+ }
39
+
40
+ return result;
41
+ }