SurfSense/surfsense_backend/app/schemas/stripe.py
Vonic 07a4bc3fc3 feat(story-5.2): add Stripe subscription checkout with session verification
Add POST /api/v1/stripe/create-subscription-checkout endpoint with
get_or_create_stripe_customer (SELECT FOR UPDATE), plan_id→price_id
mapping from env vars, active subscription guard (409), and
session_id in success URL. Add GET /verify-checkout-session endpoint
for server-side payment verification. Add /subscription-success
frontend page with loading/verified/failed states.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 23:58:57 +07:00

76 lines
1.8 KiB
Python

"""Schemas for Stripe-backed page purchases and subscriptions."""
import uuid
from datetime import datetime
from enum import Enum
from pydantic import BaseModel, ConfigDict, Field
from app.db import PagePurchaseStatus
class PlanId(str, Enum):
"""Supported subscription plan identifiers."""
pro_monthly = "pro_monthly"
pro_yearly = "pro_yearly"
class CreateCheckoutSessionRequest(BaseModel):
"""Request body for creating a page-purchase checkout session."""
quantity: int = Field(ge=1, le=100)
search_space_id: int = Field(ge=1)
class CreateSubscriptionCheckoutRequest(BaseModel):
"""Request body for creating a subscription checkout session."""
plan_id: PlanId
class CreateSubscriptionCheckoutResponse(BaseModel):
"""Response containing the Stripe-hosted subscription checkout URL."""
checkout_url: str
class CreateCheckoutSessionResponse(BaseModel):
"""Response containing the Stripe-hosted checkout URL."""
checkout_url: str
class StripeStatusResponse(BaseModel):
"""Response describing Stripe page-buying availability."""
page_buying_enabled: bool
class PagePurchaseRead(BaseModel):
"""Serialized page-purchase record for purchase history."""
id: uuid.UUID
stripe_checkout_session_id: str
stripe_payment_intent_id: str | None = None
quantity: int
pages_granted: int
amount_total: int | None = None
currency: str | None = None
status: PagePurchaseStatus
completed_at: datetime | None = None
created_at: datetime
model_config = ConfigDict(from_attributes=True)
class PagePurchaseHistoryResponse(BaseModel):
"""Response containing the authenticated user's page purchases."""
purchases: list[PagePurchaseRead]
class StripeWebhookResponse(BaseModel):
"""Generic acknowledgement for Stripe webhook delivery."""
received: bool = True