Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/zato-csm-backend/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from routes import auth, products, inventory, sales, layouts
from routes import auth, products, inventory, sales, layouts, stripe_credentials

# Import middleware registry
from middleware.middleware import register_middlewares
Expand Down Expand Up @@ -49,6 +49,7 @@ def custom_openapi():
app.include_router(inventory.router)
app.include_router(sales.router)
app.include_router(layouts.router)
app.include_router(stripe_credentials.router)


@app.get("/")
Expand Down
15 changes: 15 additions & 0 deletions backend/zato-csm-backend/models/stripe_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from pydantic import BaseModel
from datetime import datetime
from typing import Optional


class StripeCredentialsModel(BaseModel):
id: Optional[str]
user_id: str
stripe_pub_key: str
stripe_sec_key: str
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None

class Config:
orm_mode = True
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from fastapi import HTTPException
from supabase import Client
from typing import Optional


class StripeCredentialsRepository:
def __init__(self, supabase: Client):
self.supabase = supabase
self.table = "stripe_credentials"

def create_for_user(self, user_id: str, stripe_pub_key: str, stripe_sec_key: str):
payload = {
"user_id": user_id,
"stripe_pub_key": stripe_pub_key,
"stripe_sec_key": stripe_sec_key,
}
resp = self.supabase.table(self.table).upsert(payload).execute()
data = getattr(resp, "data", None)
if not data:
raise HTTPException(
status_code=400, detail="Error saving stripe credentials"
)
return data[0]

def get_by_user(self, user_id: str) -> Optional[dict]:
resp = (
self.supabase.table(self.table)
.select("*")
.eq("user_id", user_id)
.maybe_single()
.execute()
)
data = getattr(resp, "data", None)
if not data:
return None
return data

def update_for_user(self, user_id: str, updates: dict):
updates.pop("id", None)
resp = (
self.supabase.table(self.table)
.update(updates)
.eq("user_id", user_id)
.execute()
)
data = getattr(resp, "data", None)
if not data:
raise HTTPException(status_code=404, detail="Stripe credentials not found")
return data[0]

def delete_for_user(self, user_id: str):
resp = self.supabase.table(self.table).delete().eq("user_id", user_id).execute()
data = getattr(resp, "data", None)
if not data:
raise HTTPException(status_code=404, detail="Stripe credentials not found")
return data[0]
85 changes: 85 additions & 0 deletions backend/zato-csm-backend/routes/stripe_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from typing import Optional
from config.supabase import supabase_client
from services.stripe_credentials_service import StripeCredentialsService
from repositories.stripe_credentials_repositories import StripeCredentialsRepository
from utils.dependencies import get_auth_service
from routes.auth import get_current_user_from_token

router = APIRouter(prefix="/api/stripe-credentials", tags=["stripe_credentials"])


class CreateStripeCredentialsPayload(BaseModel):
stripe_pub_key: str
stripe_sec_key: str


class UpdateStripeCredentialsPayload(BaseModel):
stripe_pub_key: Optional[str] = None
stripe_sec_key: Optional[str] = None


def get_stripe_service():
repo = StripeCredentialsRepository(supabase_client)
return StripeCredentialsService(repo)


@router.post("/")
def save_credentials(
payload: CreateStripeCredentialsPayload,
service: StripeCredentialsService = Depends(get_stripe_service),
current_user: dict = Depends(get_current_user_from_token),
):
try:
user_id = current_user.id
return service.save_credentials(
user_id, payload.stripe_pub_key, payload.stripe_sec_key
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@router.get("/")
def get_credentials(
service: StripeCredentialsService = Depends(get_stripe_service),
current_user: dict = Depends(get_current_user_from_token),
):
try:
user_id = current_user.id
return service.get_credentials(user_id)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@router.put("/")
def update_credentials(
payload: UpdateStripeCredentialsPayload,
service: StripeCredentialsService = Depends(get_stripe_service),
current_user: dict = Depends(get_current_user_from_token),
):
try:
user_id = current_user.id
return service.update_credentials(
user_id, payload.stripe_pub_key, payload.stripe_sec_key
)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@router.delete("/")
def delete_credentials(
service: StripeCredentialsService = Depends(get_stripe_service),
current_user: dict = Depends(get_current_user_from_token),
):
try:
user_id = current_user.id
return service.delete_credentials(user_id)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
51 changes: 51 additions & 0 deletions backend/zato-csm-backend/services/stripe_credentials_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from fastapi import HTTPException
from repositories.stripe_credentials_repositories import StripeCredentialsRepository


class StripeCredentialsService:
def __init__(self, repo: StripeCredentialsRepository):
self.repo = repo

def save_credentials(self, user_id: str, stripe_pub_key: str, stripe_sec_key: str):
if not user_id or not stripe_pub_key or not stripe_sec_key:
raise HTTPException(status_code=400, detail="Missing fields")

return self.repo.create_for_user(user_id, stripe_pub_key, stripe_sec_key)

def get_credentials(self, user_id: str):
if not user_id:
raise HTTPException(status_code=400, detail="Missing user id")
creds = self.repo.get_by_user(user_id)
if not creds:
raise HTTPException(status_code=404, detail="Credentials not found")
pub = creds.get("stripe_pub_key")
if pub:
try:
creds["stripe_pub_key"] = "****" + str(pub)[-4:]
except Exception:
creds["stripe_pub_key"] = "****"

sec = creds.get("stripe_sec_key")
if sec:
try:
creds["stripe_sec_key"] = "****" + str(sec)[-4:]
except Exception:
creds["stripe_sec_key"] = "****"
return creds

def update_credentials(
self, user_id: str, stripe_pub_key: str | None, stripe_sec_key: str | None
):
updates = {}
if stripe_pub_key is not None:
updates["stripe_pub_key"] = stripe_pub_key
if stripe_sec_key is not None:
updates["stripe_sec_key"] = stripe_sec_key
if not updates:
raise HTTPException(status_code=400, detail="No updates provided")
return self.repo.update_for_user(user_id, updates)

def delete_credentials(self, user_id: str):
if not user_id:
raise HTTPException(status_code=400, detail="Missing user id")
return self.repo.delete_for_user(user_id)