from typing import Dict, Optional from backend.services.project.models import ProjectDoc from backend.services.payment.models import IncomeProfileDoc from datetime import datetime from common.log.module_logger import ModuleLogger class PaymentManager: def __init__(self) -> None: self.module_logger = ModuleLogger(sender_id=PaymentManager) async def fetch_wechat_qr_code(self, project_id: str) -> Optional[Dict[str, any]]: project = await ProjectDoc.get(project_id) proposer = project.proposer_id income_profile = await IncomeProfileDoc.find_one( IncomeProfileDoc.user_id == proposer ) if income_profile: return income_profile.bank_account.money_collecting_methods[ 0 ].wechat_qr_code return None async def fetch_stripe_account_id(self, user_id: str) -> Optional[str]: income_profile = await IncomeProfileDoc.find_one(IncomeProfileDoc.user_id == user_id) if income_profile: return income_profile.bank_account.money_collecting_methods[ 0 ].stripe_account_id return None async def update_stripe_account_status( self, stripe_account_id: str, setup: bool, verified: bool ) -> bool: try: # Should use IncomeProfileDoc to be consistent with other methods payment_profile = await IncomeProfileDoc.find_one( {"bank_account.money_collecting_methods": { "$elemMatch": { "stripe_account_id": stripe_account_id } }} ) if not payment_profile: await self.module_logger.log_warning( warning="No payment profile found for Stripe account", properties={ "stripe_account_id": stripe_account_id, "action": "update_stripe_account_status" } ) return False # Update the stripe method status updated = False # Need to check if money_collecting_methods exists and is not empty if payment_profile.bank_account and payment_profile.bank_account.money_collecting_methods: for method in payment_profile.bank_account.money_collecting_methods: if method.stripe_account_id == stripe_account_id: method.setup = setup method.verified = verified method.last_update_time = int(datetime.now().timestamp()) updated = True break # Exit loop once found and updated if updated: await payment_profile.save() await self.module_logger.log_info( info="Successfully updated Stripe account status", properties={ "stripe_account_id": stripe_account_id, "user_id": payment_profile.user_id, "setup": setup, "verified": verified } ) return True # Log warning with more context await self.module_logger.log_warning( warning="Stripe account not found in payment methods", properties={ "stripe_account_id": stripe_account_id, "user_id": payment_profile.user_id if payment_profile else None, "has_bank_account": bool(payment_profile and payment_profile.bank_account), "has_methods": bool(payment_profile and payment_profile.bank_account and payment_profile.bank_account.money_collecting_methods) } ) return False except Exception as e: await self.module_logger.log_exception( exception=e, info="Failed to update Stripe account status", properties={ "stripe_account_id": stripe_account_id, "setup": setup, "verified": verified, "error": str(e) } ) return False