billing stuff

This commit is contained in:
Adam Cohen Hillel 2025-04-21 14:26:09 +01:00
parent 4bcbea3464
commit 24d95d278c
4 changed files with 34 additions and 15 deletions

View File

@ -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

View File

@ -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>
);

View File

@ -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>
))}

View File

@ -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: {