mirror of https://github.com/kortix-ai/suna.git
chore(billing): add 5 free credits
This commit is contained in:
parent
d87dcd67c6
commit
83bf4a7189
|
@ -84,21 +84,21 @@ def get_model_pricing(model: str) -> tuple[float, float] | None:
|
||||||
|
|
||||||
SUBSCRIPTION_TIERS = {
|
SUBSCRIPTION_TIERS = {
|
||||||
config.STRIPE_FREE_TIER_ID: {'name': 'free', 'minutes': 60, 'cost': 5},
|
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_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}, # 6 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}, # 12 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}, # 25 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}, # 50 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}, # 125 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}, # 200 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)
|
# 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_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}, # 6 hours/month, $510/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}, # 12 hours/month, $1020/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}, # 25 hours/month, $2040/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}, # 50 hours/month, $4080/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}, # 125 hours/month, $8160/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}, # 200 hours/month, $10200/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
|
# Pydantic models for request/response validation
|
||||||
|
|
|
@ -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"
|
className="border-border hover:bg-muted/50 shadow-sm hover:shadow-md transition-all whitespace-nowrap flex items-center"
|
||||||
>
|
>
|
||||||
<Link href="/model-pricing">
|
<Link href="/model-pricing">
|
||||||
View Compute Pricing <OpenInNewWindowIcon className='w-4 h-4 inline ml-2' />
|
View Model Pricing <OpenInNewWindowIcon className='w-4 h-4 inline ml-2' />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
@ -182,7 +182,7 @@ export default function AccountBillingStatus({ accountId, returnUrl }: Props) {
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="w-full border-border hover:bg-muted/50 shadow-sm hover:shadow-md transition-all"
|
className="w-full border-border hover:bg-muted/50 shadow-sm hover:shadow-md transition-all"
|
||||||
>
|
>
|
||||||
View Compute Pricing
|
View Model Pricing
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleManageSubscription}
|
onClick={handleManageSubscription}
|
||||||
|
|
|
@ -211,7 +211,7 @@ export default function UsageLogs({ accountId }: Props) {
|
||||||
Your token usage organized by day, sorted by most recent.{" "}
|
Your token usage organized by day, sorted by most recent.{" "}
|
||||||
<Button variant='outline' asChild className='text-sm ml-4'>
|
<Button variant='outline' asChild className='text-sm ml-4'>
|
||||||
<Link href="/model-pricing">
|
<Link href="/model-pricing">
|
||||||
View Compute Pricing <OpenInNewWindowIcon className='w-4 h-4' />
|
View Model Pricing <OpenInNewWindowIcon className='w-4 h-4' />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -420,8 +420,8 @@ function PricingTier({
|
||||||
className={cn(
|
className={cn(
|
||||||
'rounded-xl flex flex-col relative',
|
'rounded-xl flex flex-col relative',
|
||||||
insideDialog
|
insideDialog
|
||||||
? 'min-h-[420px]'
|
? 'min-h-[300px]'
|
||||||
: 'h-full min-h-[480px]',
|
: 'h-full min-h-[300px]',
|
||||||
tier.isPopular && !insideDialog
|
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'
|
? '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',
|
: 'bg-[#F3F4F6] dark:bg-[#F9FAFB]/[0.02] border border-border',
|
||||||
|
@ -473,14 +473,14 @@ function PricingTier({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm mt-2">{tier.description}</p>
|
<p className="hidden text-sm mt-2">{tier.description}</p>
|
||||||
|
|
||||||
{billingPeriod === 'yearly' && tier.yearlyPrice && tier.discountPercentage ? (
|
{billingPeriod === 'yearly' && tier.yearlyPrice && tier.discountPercentage ? (
|
||||||
<div className="inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold bg-green-50 border-green-200 text-green-700 w-fit">
|
<div className="inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold bg-green-50 border-green-200 text-green-700 w-fit">
|
||||||
Save ${Math.round(parseFloat(tier.originalYearlyPrice?.slice(1) || '0') - parseFloat(tier.yearlyPrice.slice(1)))} per year
|
Save ${Math.round(parseFloat(tier.originalYearlyPrice?.slice(1) || '0') - parseFloat(tier.yearlyPrice.slice(1)))} per year
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold bg-primary/10 border-primary/20 text-primary w-fit">
|
<div className="hidden items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold bg-primary/10 border-primary/20 text-primary w-fit">
|
||||||
{billingPeriod === 'yearly' && tier.yearlyPrice && displayPrice !== '$0'
|
{billingPeriod === 'yearly' && tier.yearlyPrice && displayPrice !== '$0'
|
||||||
? `$${Math.round(parseFloat(tier.yearlyPrice.slice(1)) / 12)}/month (billed yearly)`
|
? `$${Math.round(parseFloat(tier.yearlyPrice.slice(1)) / 12)}/month (billed yearly)`
|
||||||
: `${displayPrice}/month`
|
: `${displayPrice}/month`
|
||||||
|
|
|
@ -122,9 +122,9 @@ export const siteConfig = {
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
hours: '60 min',
|
hours: '60 min',
|
||||||
features: [
|
features: [
|
||||||
'$5/month usage',
|
'Free $5/month usage included',
|
||||||
'Public Projects',
|
'Public Projects',
|
||||||
'Basic Model (Limited capabilities)',
|
'Limited models',
|
||||||
],
|
],
|
||||||
stripePriceId: config.SUBSCRIPTION_TIERS.FREE.priceId,
|
stripePriceId: config.SUBSCRIPTION_TIERS.FREE.priceId,
|
||||||
upgradePlans: [],
|
upgradePlans: [],
|
||||||
|
@ -143,8 +143,9 @@ export const siteConfig = {
|
||||||
hours: '2 hours',
|
hours: '2 hours',
|
||||||
features: [
|
features: [
|
||||||
'$20/month usage',
|
'$20/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'More models',
|
||||||
],
|
],
|
||||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20.priceId,
|
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20.priceId,
|
||||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20_YEARLY.priceId,
|
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20_YEARLY.priceId,
|
||||||
|
@ -164,8 +165,9 @@ export const siteConfig = {
|
||||||
hours: '6 hours',
|
hours: '6 hours',
|
||||||
features: [
|
features: [
|
||||||
'$50/month usage',
|
'$50/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'More models',
|
||||||
],
|
],
|
||||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50.priceId,
|
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50.priceId,
|
||||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50_YEARLY.priceId,
|
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50_YEARLY.priceId,
|
||||||
|
@ -184,8 +186,8 @@ export const siteConfig = {
|
||||||
hours: '12 hours',
|
hours: '12 hours',
|
||||||
features: [
|
features: [
|
||||||
'$100/month usage',
|
'$100/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
|
||||||
'Priority support',
|
'Priority support',
|
||||||
],
|
],
|
||||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_12_100.priceId,
|
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_12_100.priceId,
|
||||||
|
@ -206,8 +208,9 @@ export const siteConfig = {
|
||||||
hours: '25 hours',
|
hours: '25 hours',
|
||||||
features: [
|
features: [
|
||||||
'$200/month usage',
|
'$200/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'More models',
|
||||||
],
|
],
|
||||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200.priceId,
|
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200.priceId,
|
||||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200_YEARLY.priceId,
|
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200_YEARLY.priceId,
|
||||||
|
@ -226,6 +229,7 @@ export const siteConfig = {
|
||||||
hours: '50 hours',
|
hours: '50 hours',
|
||||||
features: [
|
features: [
|
||||||
'$400/month usage',
|
'$400/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'Access to intelligent Model (Full Suna)',
|
||||||
'Priority support',
|
'Priority support',
|
||||||
|
@ -249,6 +253,7 @@ export const siteConfig = {
|
||||||
hours: '125 hours',
|
hours: '125 hours',
|
||||||
features: [
|
features: [
|
||||||
'$800/month usage',
|
'$800/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'Access to intelligent Model (Full Suna)',
|
||||||
'Priority support',
|
'Priority support',
|
||||||
|
@ -273,6 +278,7 @@ export const siteConfig = {
|
||||||
hours: '200 hours',
|
hours: '200 hours',
|
||||||
features: [
|
features: [
|
||||||
'$1000/month usage',
|
'$1000/month usage',
|
||||||
|
'+ $5 free included',
|
||||||
'Private projects',
|
'Private projects',
|
||||||
'Access to intelligent Model (Full Suna)',
|
'Access to intelligent Model (Full Suna)',
|
||||||
'Priority support',
|
'Priority support',
|
||||||
|
|
Loading…
Reference in New Issue