Add subcription feature 3

This commit is contained in:
Urtzi Alfaro
2026-01-15 20:45:49 +01:00
parent a4c3b7da3f
commit b674708a4c
83 changed files with 9451 additions and 6828 deletions

View File

@@ -1122,6 +1122,88 @@ async def upgrade_subscription_plan(
detail="Failed to upgrade subscription plan"
)
# ============================================================================
# REGISTRATION ORCHESTRATION (SECURE 3DS FLOW)
# ============================================================================
@router.post("/registration-payment-setup")
async def registration_payment_setup(
user_data: Dict[str, Any],
payment_service: PaymentService = Depends(get_payment_service)
):
"""
Orchestrate initial payment setup for a new registration.
This creates the customer and SetupIntent for 3DS verification.
"""
try:
logger.info("Orchestrating registration payment setup",
email=user_data.get('email'))
result = await payment_service.complete_registration_payment_flow(user_data)
return result
except Exception as e:
logger.error("Registration payment setup orchestration failed",
email=user_data.get('email'),
error=str(e))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Registration payment setup failed: {str(e)}"
)
@router.post("/verify-and-complete-registration")
async def verify_and_complete_registration(
registration_data: Dict[str, Any],
payment_service: PaymentService = Depends(get_payment_service),
tenant_service: EnhancedTenantService = Depends(get_enhanced_tenant_service)
):
"""
Final step: Verify SetupIntent and create subscription + tenant.
Called after frontend confirms 3DS with Stripe.
"""
try:
setup_intent_id = registration_data.get('setup_intent_id')
user_data = registration_data.get('user_data', {})
logger.info("Verifying and completing registration",
email=user_data.get('email'),
setup_intent_id=setup_intent_id)
# 1. Complete subscription creation after verification
payment_result = await payment_service.complete_subscription_after_verification(
setup_intent_id, user_data
)
# 2. Create the bakery/tenant record
# Note: In a real flow, we'd use the payment result (customer_id, subscription_id)
# to properly link the new tenant.
bakery_registration = BakeryRegistration(
name=user_data.get('name', f"{user_data.get('full_name')}'s Bakery"),
subdomain=user_data.get('subdomain', user_data.get('email').split('@')[0]),
business_type=user_data.get('business_type', 'bakery'),
link_existing_subscription=True,
subscription_id=payment_result['subscription_id']
)
# We need the user_id from the auth service call
user_id = user_data.get('user_id')
if not user_id:
raise HTTPException(status_code=400, detail="Missing user_id in registration data")
tenant_result = await tenant_service.create_bakery(bakery_registration, user_id)
return {
"success": True,
"tenant": tenant_result,
"payment": payment_result
}
except Exception as e:
logger.error("Verify and complete registration failed",
error=str(e))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Registration completion failed: {str(e)}"
)
# ============================================================================
# PAYMENT OPERATIONS
# ============================================================================
@@ -1244,7 +1326,7 @@ async def register_with_subscription(
**result
}
except Exception as e:
logger.error("Failed to register with subscription", error=str(e))
logger.error(f"Failed to register with subscription: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to register with subscription"