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; recurring: Recurring;
stripe_price_id: null | string; stripe_price_id: null | string;
tiers_mode: null | string; tiers_mode: null | string;
tiers?: null | Tier[];
type: null | string; type: null | string;
unit_amount: number; unit_amount: null | number;
unit_amount_decimal: null | string; unit_amount_decimal: null | string;
} }
@@ -685,9 +686,11 @@ export interface StripeCustomerId {
} }
export interface Tier { export interface Tier {
up_to: number; up_to: null | number;
flat_amount: number; flat_amount: null | number;
unit_amount: number; unit_amount: null | number;
flat_amount_decimal: null | string;
unit_amount_decimal: null | string;
} }
export interface ServiceData { export interface ServiceData {

View File

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