diff --git a/backend/services/billing.py b/backend/services/billing.py index 7bae3c9f..8a0c146e 100644 --- a/backend/services/billing.py +++ b/backend/services/billing.py @@ -21,7 +21,7 @@ import time stripe.api_key = config.STRIPE_SECRET_KEY # Token price multiplier -TOKEN_PRICE_MULTIPLIER = 2 +TOKEN_PRICE_MULTIPLIER = 1.5 # Initialize router router = APIRouter(prefix="/billing", tags=["billing"]) @@ -51,7 +51,11 @@ HARDCODED_MODEL_PRICES = { "openrouter/google/gemini-2.5-flash-preview-05-20": { "input_cost_per_million_tokens": 0.15, "output_cost_per_million_tokens": 0.60 - } + }, + "anthropic/claude-sonnet-4": { + "input_cost_per_million_tokens": 3.00, + "output_cost_per_million_tokens": 15.00, + }, } def get_model_pricing(model: str) -> tuple[float, float] | None: diff --git a/frontend/src/app/(dashboard)/model-pricing/page.tsx b/frontend/src/app/(dashboard)/model-pricing/page.tsx index 4df75abe..76cef25a 100644 --- a/frontend/src/app/(dashboard)/model-pricing/page.tsx +++ b/frontend/src/app/(dashboard)/model-pricing/page.tsx @@ -1,96 +1,26 @@ 'use client'; import { SectionHeader } from '@/components/home/section-header'; -import { AlertCircle } from 'lucide-react'; +import { + AlertCircle, + Clock, + DollarSign, + Zap, + Server, + Globe, +} from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card'; +import { Badge } from '@/components/ui/badge'; import { useAvailableModels } from '@/hooks/react-query/subscriptions/use-billing'; import type { Model } from '@/lib/api'; import { Loader2 } from 'lucide-react'; -import Link from 'next/link'; - -interface ModelCardProps { - model: Model; - index: number; -} - -function ModelCard({ model, index }: ModelCardProps) { - return ( -
-
- {/* Model Header */} -
-

- {model.display_name} -

-
- - {/* Pricing Grid */} -
- {/* Input Cost */} -
-
-
- - Input - -
- {model.input_cost_per_million_tokens !== null && - model.input_cost_per_million_tokens !== undefined ? ( - <> -
- ${model.input_cost_per_million_tokens.toFixed(2)} -
-
- per 1M tokens -
- - ) : ( -
- )} -
- - {/* Output Cost */} -
-
-
- - Output - -
- {model.output_cost_per_million_tokens !== null && - model.output_cost_per_million_tokens !== undefined ? ( - <> -
- ${model.output_cost_per_million_tokens.toFixed(2)} -
-
- per 1M tokens -
- - ) : ( -
- )} -
-
- - {/* Model Stats */} - {model.max_tokens && ( -
-
- Max Tokens - - {model.max_tokens.toLocaleString()} - -
-
- )} -
-
- ); -} export default function PricingPage() { const { @@ -111,77 +41,295 @@ export default function PricingPage() { ); }) || []; - return ( -
- {/* Animated Background */} -
- - {/* Header */} - -
-
-

- Compute Pricing -

-
+ if (loading) { + return ( +
+
+ +

+ Loading pricing data... +

- +
+ ); + } - {/* Content */} -
- {loading ? ( -
-
-
-
-
+ if (error) { + return ( +
+
+ +
+

+ Pricing Unavailable +

+

+ {error instanceof Error + ? error.message + : 'Failed to fetch model pricing'} +

+
+ +
+
+ ); + } + + return ( +
+ {/* Header Section */} +
+

+ Credits & Pricing +

+

+ Understand how credits work, explore pricing for AI models, and find + the right plan for your needs. +

+
+ + {/* What are Credits Section */} + + + + + What are credits? + + + +

+ Credits are our standard unit of measurement for platform usage - + the more complex or lengthy the task, the more credits it requires. + Credits provide a unified way to measure consumption across + different types of AI operations and computational resources. +

+
+
+ + {/* How Credits Work Section */} + + + + + How do credits work? + + + +

+ Credits are consumed based on AI model usage. We apply a 50% markup + over the direct model provider costs. The specific credits + consumption is determined by the model used and the number of tokens + processed (both input and output tokens). +

+
+
+ + {/* Usage Examples Section */} + + + + + Usage Examples + + + Here are some examples demonstrating credits consumption across + different task types and complexity levels. + + + +
+ {/* Example 4 */} +
+
+

+ Social Automation System +

+ Complex
-
-

- Loading compute pricing -

-

- Fetching the latest pricing data... -

+
+
+ Model: + claude-sonnet-4 +
+
+ Duration: + 35 minutes +
+
+ Cost: + $17.45 +
-
- ) : error ? ( -
-
-
- + + {/* Example 6 */} +
+
+

+ Content Marketing Strategy +

+ Standard Complexity
-
-

- Pricing Unavailable -

-

- {error instanceof Error - ? error.message - : 'Failed to fetch model pricing'} -

+
+
+ Model: + claude-sonnet-4 +
+
+ Duration: + 11 minutes +
+
+ Cost: + $1.93 +
-
+ + {/* Example 5 */} +
+
+

+ Go-to-Market Strategy +

+ Standard Complexity +
+
+
+ Model: + deepseek-chat +
+
+ Duration: + 3 minutes +
+
+ Cost: + $0.13 +
+
+
+ + {/* Example 7 */} + {/*
+
+

+ 6-Month Content Marketing Strategy +

+ Standard Complexity +
+
+
+ Task type: + Marketing • SEO • Content +
+
+ Model: + deepseek-chat +
+
+ Duration: + 4 minutes +
+
+ Cost: + $0.20 +
+
+
*/}
- ) : ( -
- {/* Model Cards Grid */} -
+ + + + {/* Model Pricing Table */} + + + Compute Pricing by Model + + Detailed pricing information for available AI models. We apply a 50% + markup on direct LLM provider costs to maintain our service and + generate profit. + + + +
+
+
+
Model
+
Input Cost
+
Output Cost
+
+
+ +
{models.map((model, index) => ( - +
+
+ {/* Model Name */} +
+
+
+
+
+ {model.display_name} +
+
+
+
+ + {/* Input Cost */} +
+
+ {model.input_cost_per_million_tokens !== null && + model.input_cost_per_million_tokens !== undefined ? ( + <> +
+ ${model.input_cost_per_million_tokens.toFixed(2)} +
+
+ per 1M tokens +
+ + ) : ( +
+ — +
+ )} +
+
+ + {/* Output Cost */} +
+
+ {model.output_cost_per_million_tokens !== null && + model.output_cost_per_million_tokens !== undefined ? ( + <> +
+ ${model.output_cost_per_million_tokens.toFixed(2)} +
+
+ per 1M tokens +
+ + ) : ( +
+ — +
+ )} +
+
+
+
))}
- )} -
+ +
); } diff --git a/frontend/src/components/billing/account-billing-status.tsx b/frontend/src/components/billing/account-billing-status.tsx index 2b2f79df..8dea102a 100644 --- a/frontend/src/components/billing/account-billing-status.tsx +++ b/frontend/src/components/billing/account-billing-status.tsx @@ -131,11 +131,12 @@ export default function AccountBillingStatus({ accountId, returnUrl }: Props) { {/* Manage Subscription Button */}