mirror of https://github.com/kortix-ai/suna.git
billing stuff
This commit is contained in:
parent
4bcbea3464
commit
24d95d278c
|
@ -1,12 +1,11 @@
|
|||
from datetime import datetime, timezone
|
||||
from typing import Dict, Optional, Tuple
|
||||
from services.supabase import DBConnection
|
||||
|
||||
# Define subscription tiers and their monthly hour limits
|
||||
# Define subscription tiers and their monthly limits (in minutes)
|
||||
SUBSCRIPTION_TIERS = {
|
||||
'price_1RDQbOG6l1KZGqIrgrYzMbnL': {'name': 'free', 'hours': 100},
|
||||
'price_1RC2PYG6l1KZGqIrpbzFB9Lp': {'name': 'base', 'hours': 100},
|
||||
'price_1RDQWqG6l1KZGqIrChli4Ys4': {'name': 'extra', 'hours': 100}
|
||||
'price_1RGJ9GG6l1KZGqIroxSqgphC': {'name': 'free', 'minutes': 10},
|
||||
'price_1RGJ9LG6l1KZGqIrd9pwzeNW': {'name': 'base', 'minutes': 6000}, # 100 hours = 6000 minutes
|
||||
'price_1RGJ9JG6l1KZGqIrVUU4ZRv6': {'name': 'extra', 'minutes': 6000} # 100 hours = 6000 minutes
|
||||
}
|
||||
|
||||
async def get_account_subscription(client, account_id: str) -> Optional[Dict]:
|
||||
|
@ -24,7 +23,7 @@ async def get_account_subscription(client, account_id: str) -> Optional[Dict]:
|
|||
return None
|
||||
|
||||
async def calculate_monthly_usage(client, account_id: str) -> float:
|
||||
"""Calculate total agent run hours for the current month for an account."""
|
||||
"""Calculate total agent run minutes for the current month for an account."""
|
||||
# Get start of current month in UTC
|
||||
now = datetime.now(timezone.utc)
|
||||
start_of_month = datetime(now.year, now.month, 1, tzinfo=timezone.utc)
|
||||
|
@ -50,7 +49,7 @@ async def calculate_monthly_usage(client, account_id: str) -> float:
|
|||
if not runs_result.data:
|
||||
return 0.0
|
||||
|
||||
# Calculate total hours
|
||||
# Calculate total minutes
|
||||
total_seconds = 0
|
||||
now_ts = now.timestamp()
|
||||
|
||||
|
@ -64,7 +63,7 @@ async def calculate_monthly_usage(client, account_id: str) -> float:
|
|||
|
||||
total_seconds += (end_time - start_time)
|
||||
|
||||
return total_seconds / 3600 # Convert to hours
|
||||
return total_seconds / 60 # Convert to minutes
|
||||
|
||||
async def check_billing_status(client, account_id: str) -> Tuple[bool, str, Optional[Dict]]:
|
||||
"""
|
||||
|
@ -79,7 +78,7 @@ async def check_billing_status(client, account_id: str) -> Tuple[bool, str, Opti
|
|||
# If no subscription, they can use free tier
|
||||
if not subscription:
|
||||
subscription = {
|
||||
'price_id': 'price_1RDQbOG6l1KZGqIrgrYzMbnL', # Free tier
|
||||
'price_id': 'price_1RGJ9GG6l1KZGqIroxSqgphC', # Free tier
|
||||
'plan_name': 'Free'
|
||||
}
|
||||
|
||||
|
@ -92,8 +91,8 @@ async def check_billing_status(client, account_id: str) -> Tuple[bool, str, Opti
|
|||
current_usage = await calculate_monthly_usage(client, account_id)
|
||||
|
||||
# Check if within limits
|
||||
if current_usage >= tier_info['hours']:
|
||||
return False, f"Monthly limit of {tier_info['hours']} hours reached. Please upgrade your plan or wait until next month.", subscription
|
||||
if current_usage >= tier_info['minutes']:
|
||||
return False, f"Monthly limit of {tier_info['minutes']} minutes reached. Please upgrade your plan or wait until next month.", subscription
|
||||
|
||||
return True, "OK", subscription
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import { SubmitButton } from "@/components/ui/submit-button";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { siteConfig } from "@/lib/home";
|
||||
export const SUBSCRIPTION_PLANS = {
|
||||
FREE: 'price_1RDQbOG6l1KZGqIrgrYzMbnL',
|
||||
BASIC: 'price_1RC2PYG6l1KZGqIrpbzFB9Lp',
|
||||
PRO: 'price_1RDQWqG6l1KZGqIrChli4Ys4'
|
||||
FREE: 'price_1RGJ9GG6l1KZGqIroxSqgphC',
|
||||
BASIC: 'price_1RGJ9LG6l1KZGqIrd9pwzeNW',
|
||||
PRO: 'price_1RGJ9JG6l1KZGqIrVUU4ZRv6'
|
||||
} as const;
|
||||
|
||||
interface PlanComparisonProps {
|
||||
|
@ -171,6 +171,16 @@ export function PlanComparison({
|
|||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{(tier as any).showContactSales && (
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full h-10 rounded-full font-medium transition-colors mt-4"
|
||||
onClick={() => window.open('mailto:support@kortix.ai?subject=Enterprise Plan Inquiry', '_blank')}
|
||||
>
|
||||
Need more? Contact Sales
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -366,6 +366,15 @@ export function PricingSection() {
|
|||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{(tier as any).showContactSales && (
|
||||
<button
|
||||
className="h-10 w-full flex items-center justify-center text-sm font-normal tracking-wide rounded-full px-4 cursor-pointer transition-all ease-out active:scale-95 bg-transparent border border-secondary/20 text-secondary shadow-[0px_1px_2px_0px_rgba(255,255,255,0.05)_inset] mt-6"
|
||||
onClick={() => window.open('mailto:support@kortix.ai?subject=Enterprise Plan Inquiry', '_blank')}
|
||||
>
|
||||
Need more? Contact Sales
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -111,7 +111,7 @@ export const siteConfig = {
|
|||
name: "Enterprise",
|
||||
price: "$199",
|
||||
description: "For organizations with complex needs",
|
||||
buttonText: "Contact Sales",
|
||||
buttonText: "Hire Suna",
|
||||
buttonColor: "bg-secondary text-white",
|
||||
isPopular: false,
|
||||
hours: "40 hours",
|
||||
|
@ -123,6 +123,7 @@ export const siteConfig = {
|
|||
"Service level agreement",
|
||||
"Custom AI model training",
|
||||
],
|
||||
showContactSales: true,
|
||||
},
|
||||
],
|
||||
companyShowcase: {
|
||||
|
|
Loading…
Reference in New Issue