from fastapi import APIRouter, Request, Header, HTTPException from backend.application.payment_hub import PaymentHub from typing import Dict, Optional, Tuple from common.config.app_settings import app_settings from decimal import Decimal from fastapi.responses import JSONResponse from fastapi.encoders import jsonable_encoder import stripe router = APIRouter() payment_hub = PaymentHub() # Web API # Create stripe account @router.get( "/create_stripe_account", operation_id="create_stripe_account", summary="Create stripe account", description="Create stripe account", ) async def create_stripe_account(): return await payment_hub.create_stripe_account() # Web API # Create account link @router.get( "/create_account_link/{account_id}", operation_id="create_account_link", summary="Create account link", description="Create account link", ) async def create_account_link(account_id: str, link_type: str = "account_onboarding"): return await payment_hub.create_account_link(account_id, link_type) # Web API # Can account receive payments @router.get( "/can_account_receive_payments/{account_id}", operation_id="can_account_receive_payments", summary="Can account receive payments", description="Can account receive payments", ) async def can_account_receive_payments(account_id: str): return await payment_hub.can_account_receive_payments(account_id) # Web API # Fetch transaction by id @router.get( "/fetch_transaction_by_id/{transaction_id}", operation_id="fetch_transaction_by_id", summary="Fetch transaction by id", description="Fetch transaction by id", ) async def fetch_transaction_by_id(transaction_id: str): return await payment_hub.fetch_transaction_by_id(transaction_id) # Web API # Fetch transaction by session id @router.get( "/fetch_transaction_by_session_id/{session_id}", operation_id="fetch_transaction_by_session_id", summary="Fetch transaction by session id", description="Fetch transaction by session id", ) async def fetch_transaction_by_session_id(session_id: str): return await payment_hub.fetch_transaction_by_session_id(session_id) # Web API # Fetch stripe transaction for milestone @router.get( "/fetch_stripe_transaction_for_milestone/", operation_id="fetch_stripe_transaction_for_milestone", summary="Fetch stripe transaction for milestone", description="Fetch stripe transaction for milestone", ) async def fetch_stripe_transaction_for_milestone(project_id: str, milestone_index: int): return await payment_hub.fetch_stripe_transaction_for_milestone( project_id, milestone_index ) # Web API # Create stripe transaction for milestone @router.post( "/create_stripe_transaction_for_milestone", operation_id="create_stripe_transaction_for_milestone", summary="Create stripe transaction for milestone", description="Create stripe transaction for milestone", ) async def create_stripe_transaction_for_milestone( project_id: str, milestone_index: int, currency: str, expected_payment: Decimal, from_user: str, to_user: str, to_stripe_account_id: str, ): res = await payment_hub.create_stripe_transaction_for_milestone( project_id, milestone_index, currency, expected_payment, from_user, to_user, to_stripe_account_id, ) return JSONResponse(content=jsonable_encoder(str(res))) # Web API # Create payment link @router.get( "/create_payment_link/{transaction_id}", operation_id="create_payment_link", summary="Create payment link", description="Create payment link", ) async def create_payment_link(transaction_id: str) -> Optional[str]: return await payment_hub.create_payment_link(transaction_id) # Web API # Create checkout session @router.post( "/create_checkout_session/{transaction_id}", operation_id="create_checkout_session", summary="Create checkout session", description="Create checkout session", ) async def create_checkout_session( transaction_id: str, ) -> Tuple[Optional[str], Optional[str]]: return await payment_hub.create_checkout_session(transaction_id) # Web API # Fetch payment link @router.get( "/fetch_payment_link/{transaction_id}", operation_id="fetch_payment_link", summary="Fetch payment link", description="Fetch payment link", ) async def fetch_payment_link(transaction_id: str) -> Optional[str]: return await payment_hub.fetch_payment_link(transaction_id) # Web API # Fetch checkout session id @router.get( "/fetch_checkout_session/{transaction_id}", operation_id="fetch_checkout_session", summary="Fetch checkout session", description="Fetch checkout session", ) async def fetch_checkout_session_id(transaction_id: str) -> Optional[str]: return await payment_hub.fetch_checkout_session_id(transaction_id) # Web API # Fetch checkout session url @router.get( "/fetch_checkout_session_url/{transaction_id}", operation_id="fetch_checkout_session_url", summary="Fetch checkout session url", description="Fetch checkout session url", ) async def fetch_checkout_session_url(transaction_id: str) -> Optional[str]: return await payment_hub.fetch_checkout_session_url(transaction_id) # Web API # Invoke checkout session webhook @router.post( "/invoke_checkout_session_webhook", operation_id="invoke_checkout_session_webhook", summary="Invoke checkout session webhook", description="Invoke checkout session webhook", ) async def invoke_checkout_session_webhook(event: dict): return await payment_hub.invoke_checkout_session_webhook(event) @router.post( "/webhook/account_signup", operation_id="stripe_account_webhook", summary="Handle Stripe account webhook events", ) async def handle_account_webhook( event: dict ): try: if event["type"] == 'account.updated': session = event["data"]["object"] return await payment_hub.handle_account_update( account_id=session["id"], details_submitted=session["details_submitted"], payouts_enabled=session["payouts_enabled"], charges_enabled=session["charges_enabled"] ) except Exception as e: raise HTTPException(status_code=400, detail=str(e)) return JSONResponse(content={"status": "success"}) # Web API # Detach payment method @router.delete( "/detach_payment_method/{payment_method_id}", operation_id="detach_payment_method", summary="Detach payment method from customer", description="Detach a payment method from a Stripe customer", ) async def detach_payment_method(payment_method_id: str): try: # Detach the payment method from Stripe stripe.PaymentMethod.detach(payment_method_id) return JSONResponse(content={"success": True, "message": "Payment method detached successfully"}) except Exception as e: return JSONResponse( status_code=400, content={"success": False, "message": f"Failed to detach payment method: {str(e)}"} )