support tier pricing (#520)

This commit is contained in:
Hoan Luu Huu
2025-05-19 01:00:07 +07:00
committed by GitHub
parent 0c35321c1f
commit 8b2bde4e11
2 changed files with 43 additions and 19 deletions

View File

@@ -665,8 +665,9 @@ export interface Price {
recurring: Recurring;
stripe_price_id: null | string;
tiers_mode: null | string;
tiers?: null | Tier[];
type: null | string;
unit_amount: number;
unit_amount: null | number;
unit_amount_decimal: null | string;
}
@@ -685,9 +686,11 @@ export interface StripeCustomerId {
}
export interface Tier {
up_to: number;
flat_amount: number;
unit_amount: number;
up_to: null | number;
flat_amount: null | number;
unit_amount: null | number;
flat_amount_decimal: null | string;
unit_amount_decimal: null | string;
}
export interface ServiceData {

View File

@@ -257,7 +257,10 @@ const SubscriptionForm = () => {
[],
);
const initFeesAndCost = (priceData: PriceInfo[]) => {
const initFeesAndCost = (
priceData: PriceInfo[],
serviceData: ServiceData[],
) => {
serviceData.forEach((service) => {
const record = priceData.find(
(item) => item.category === service.category,
@@ -272,7 +275,23 @@ const SubscriptionForm = () => {
let fees = 0;
switch (price.billing_scheme) {
case "per_unit":
fees = (price.unit_amount * 1) / 100;
fees = ((price.unit_amount || 0) * 1) / 100;
break;
case "tiered":
if (price.tiers && price.tiers.length) {
const tier = price.tiers.find(
(item) => !item.up_to || item.up_to >= service.capacity,
);
if (tier) {
if (typeof tier.flat_amount === "number") {
fees = tier.flat_amount / 100;
} else {
fees = ((tier.unit_amount || 0) * 1) / 100;
}
}
service.tiers = price.tiers;
}
break;
default:
break;
@@ -283,6 +302,7 @@ const SubscriptionForm = () => {
service.product_sid = record.product_sid;
service.stripe_product_id = record.stripe_product_id;
service.fees = fees;
service.cost = fees * service.capacity;
service.feesLabel = `${
CurrencySymbol[service.currency || "usd"]
}${fees} per ${
@@ -294,7 +314,7 @@ const SubscriptionForm = () => {
}
});
setServiceData([...serviceData]);
return [...serviceData];
};
const getServicePrice = (
@@ -320,7 +340,7 @@ const SubscriptionForm = () => {
fees = tier.flat_amount / 100;
cost = fees;
} else {
fees = tier.unit_amount / 100;
fees = (tier.unit_amount || 0) / 100;
cost = fees * capacityNum;
}
}
@@ -362,22 +382,23 @@ const SubscriptionForm = () => {
key: string,
value: (typeof serviceData)[number][keyof ServiceData],
) => {
setServiceData(
serviceData.map((g, i) =>
i === index
? {
...g,
[key]: value,
...(key === "capacity" && { cost: Number(value) * g.fees }),
}
: g,
),
let serviceD = serviceData.map((g, i) =>
i === index
? {
...g,
[key]: value,
}
: g,
);
if (key === "capacity" && priceInfo) {
serviceD = initFeesAndCost(priceInfo, serviceD);
}
setServiceData([...serviceD]);
};
useEffect(() => {
if (priceInfo) {
initFeesAndCost(priceInfo);
setServiceData(initFeesAndCost(priceInfo, serviceData));
}
if (userData && priceInfo) {