diff --git a/backend/services/billing.py b/backend/services/billing.py index 30f80c80..b47938a5 100644 --- a/backend/services/billing.py +++ b/backend/services/billing.py @@ -84,21 +84,21 @@ def get_model_pricing(model: str) -> tuple[float, float] | None: SUBSCRIPTION_TIERS = { config.STRIPE_FREE_TIER_ID: {'name': 'free', 'minutes': 60, 'cost': 5}, - config.STRIPE_TIER_2_20_ID: {'name': 'tier_2_20', 'minutes': 120, 'cost': 20}, # 2 hours - config.STRIPE_TIER_6_50_ID: {'name': 'tier_6_50', 'minutes': 360, 'cost': 50}, # 6 hours - config.STRIPE_TIER_12_100_ID: {'name': 'tier_12_100', 'minutes': 720, 'cost': 100}, # 12 hours - config.STRIPE_TIER_25_200_ID: {'name': 'tier_25_200', 'minutes': 1500, 'cost': 200}, # 25 hours - config.STRIPE_TIER_50_400_ID: {'name': 'tier_50_400', 'minutes': 3000, 'cost': 400}, # 50 hours - config.STRIPE_TIER_125_800_ID: {'name': 'tier_125_800', 'minutes': 7500, 'cost': 800}, # 125 hours - config.STRIPE_TIER_200_1000_ID: {'name': 'tier_200_1000', 'minutes': 12000, 'cost': 1000}, # 200 hours + config.STRIPE_TIER_2_20_ID: {'name': 'tier_2_20', 'minutes': 120, 'cost': 20 + 5}, # 2 hours + config.STRIPE_TIER_6_50_ID: {'name': 'tier_6_50', 'minutes': 360, 'cost': 50 + 5}, # 6 hours + config.STRIPE_TIER_12_100_ID: {'name': 'tier_12_100', 'minutes': 720, 'cost': 100 + 5}, # 12 hours + config.STRIPE_TIER_25_200_ID: {'name': 'tier_25_200', 'minutes': 1500, 'cost': 200 + 5}, # 25 hours + config.STRIPE_TIER_50_400_ID: {'name': 'tier_50_400', 'minutes': 3000, 'cost': 400 + 5}, # 50 hours + config.STRIPE_TIER_125_800_ID: {'name': 'tier_125_800', 'minutes': 7500, 'cost': 800 + 5}, # 125 hours + config.STRIPE_TIER_200_1000_ID: {'name': 'tier_200_1000', 'minutes': 12000, 'cost': 1000 + 5}, # 200 hours # Yearly tiers (same usage limits, different billing period) - config.STRIPE_TIER_2_20_YEARLY_ID: {'name': 'tier_2_20', 'minutes': 120, 'cost': 20}, # 2 hours/month, $204/year - config.STRIPE_TIER_6_50_YEARLY_ID: {'name': 'tier_6_50', 'minutes': 360, 'cost': 50}, # 6 hours/month, $510/year - config.STRIPE_TIER_12_100_YEARLY_ID: {'name': 'tier_12_100', 'minutes': 720, 'cost': 100}, # 12 hours/month, $1020/year - config.STRIPE_TIER_25_200_YEARLY_ID: {'name': 'tier_25_200', 'minutes': 1500, 'cost': 200}, # 25 hours/month, $2040/year - config.STRIPE_TIER_50_400_YEARLY_ID: {'name': 'tier_50_400', 'minutes': 3000, 'cost': 400}, # 50 hours/month, $4080/year - config.STRIPE_TIER_125_800_YEARLY_ID: {'name': 'tier_125_800', 'minutes': 7500, 'cost': 800}, # 125 hours/month, $8160/year - config.STRIPE_TIER_200_1000_YEARLY_ID: {'name': 'tier_200_1000', 'minutes': 12000, 'cost': 1000}, # 200 hours/month, $10200/year + config.STRIPE_TIER_2_20_YEARLY_ID: {'name': 'tier_2_20', 'minutes': 120, 'cost': 20 + 5}, # 2 hours/month, $204/year + config.STRIPE_TIER_6_50_YEARLY_ID: {'name': 'tier_6_50', 'minutes': 360, 'cost': 50 + 5}, # 6 hours/month, $510/year + config.STRIPE_TIER_12_100_YEARLY_ID: {'name': 'tier_12_100', 'minutes': 720, 'cost': 100 + 5}, # 12 hours/month, $1020/year + config.STRIPE_TIER_25_200_YEARLY_ID: {'name': 'tier_25_200', 'minutes': 1500, 'cost': 200 + 5}, # 25 hours/month, $2040/year + config.STRIPE_TIER_50_400_YEARLY_ID: {'name': 'tier_50_400', 'minutes': 3000, 'cost': 400 + 5}, # 50 hours/month, $4080/year + config.STRIPE_TIER_125_800_YEARLY_ID: {'name': 'tier_125_800', 'minutes': 7500, 'cost': 800 + 5}, # 125 hours/month, $8160/year + config.STRIPE_TIER_200_1000_YEARLY_ID: {'name': 'tier_200_1000', 'minutes': 12000, 'cost': 1000 + 5}, # 200 hours/month, $10200/year } # Pydantic models for request/response validation diff --git a/frontend/src/components/billing/account-billing-status.tsx b/frontend/src/components/billing/account-billing-status.tsx index 4c20134a..445b9788 100644 --- a/frontend/src/components/billing/account-billing-status.tsx +++ b/frontend/src/components/billing/account-billing-status.tsx @@ -135,7 +135,7 @@ export default function AccountBillingStatus({ accountId, returnUrl }: Props) { className="border-border hover:bg-muted/50 shadow-sm hover:shadow-md transition-all whitespace-nowrap flex items-center" > - View Compute Pricing + View Model Pricing diff --git a/frontend/src/components/home/sections/pricing-section.tsx b/frontend/src/components/home/sections/pricing-section.tsx index 5eff3e73..8664321e 100644 --- a/frontend/src/components/home/sections/pricing-section.tsx +++ b/frontend/src/components/home/sections/pricing-section.tsx @@ -420,8 +420,8 @@ function PricingTier({ className={cn( 'rounded-xl flex flex-col relative', insideDialog - ? 'min-h-[420px]' - : 'h-full min-h-[480px]', + ? 'min-h-[300px]' + : 'h-full min-h-[300px]', tier.isPopular && !insideDialog ? 'md:shadow-[0px_61px_24px_-10px_rgba(0,0,0,0.01),0px_34px_20px_-8px_rgba(0,0,0,0.05),0px_15px_15px_-6px_rgba(0,0,0,0.09),0px_4px_8px_-2px_rgba(0,0,0,0.10),0px_0px_0px_1px_rgba(0,0,0,0.08)] bg-accent' : 'bg-[#F3F4F6] dark:bg-[#F9FAFB]/[0.02] border border-border', @@ -473,14 +473,14 @@ function PricingTier({ )} -

{tier.description}

+

{tier.description}

{billingPeriod === 'yearly' && tier.yearlyPrice && tier.discountPercentage ? (
Save ${Math.round(parseFloat(tier.originalYearlyPrice?.slice(1) || '0') - parseFloat(tier.yearlyPrice.slice(1)))} per year
) : ( -
+
{billingPeriod === 'yearly' && tier.yearlyPrice && displayPrice !== '$0' ? `$${Math.round(parseFloat(tier.yearlyPrice.slice(1)) / 12)}/month (billed yearly)` : `${displayPrice}/month` diff --git a/frontend/src/lib/home.tsx b/frontend/src/lib/home.tsx index 44a8fb43..f310184d 100644 --- a/frontend/src/lib/home.tsx +++ b/frontend/src/lib/home.tsx @@ -122,9 +122,9 @@ export const siteConfig = { /** @deprecated */ hours: '60 min', features: [ - '$5/month usage', + 'Free $5/month usage included', 'Public Projects', - 'Basic Model (Limited capabilities)', + 'Limited models', ], stripePriceId: config.SUBSCRIPTION_TIERS.FREE.priceId, upgradePlans: [], @@ -143,8 +143,9 @@ export const siteConfig = { hours: '2 hours', features: [ '$20/month usage', + '+ $5 free included', 'Private projects', - 'Access to intelligent Model (Full Suna)', + 'More models', ], stripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20.priceId, yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20_YEARLY.priceId, @@ -164,8 +165,9 @@ export const siteConfig = { hours: '6 hours', features: [ '$50/month usage', + '+ $5 free included', 'Private projects', - 'Access to intelligent Model (Full Suna)', + 'More models', ], stripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50.priceId, yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50_YEARLY.priceId, @@ -184,8 +186,8 @@ export const siteConfig = { hours: '12 hours', features: [ '$100/month usage', + '+ $5 free included', 'Private projects', - 'Access to intelligent Model (Full Suna)', 'Priority support', ], stripePriceId: config.SUBSCRIPTION_TIERS.TIER_12_100.priceId, @@ -206,8 +208,9 @@ export const siteConfig = { hours: '25 hours', features: [ '$200/month usage', + '+ $5 free included', 'Private projects', - 'Access to intelligent Model (Full Suna)', + 'More models', ], stripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200.priceId, yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200_YEARLY.priceId, @@ -226,6 +229,7 @@ export const siteConfig = { hours: '50 hours', features: [ '$400/month usage', + '+ $5 free included', 'Private projects', 'Access to intelligent Model (Full Suna)', 'Priority support', @@ -249,6 +253,7 @@ export const siteConfig = { hours: '125 hours', features: [ '$800/month usage', + '+ $5 free included', 'Private projects', 'Access to intelligent Model (Full Suna)', 'Priority support', @@ -273,6 +278,7 @@ export const siteConfig = { hours: '200 hours', features: [ '$1000/month usage', + '+ $5 free included', 'Private projects', 'Access to intelligent Model (Full Suna)', 'Priority support',