Update payment micro-service to handle status update

This commit is contained in:
jetli 2025-01-22 00:21:54 -08:00
parent d47823124f
commit 9f5e0d1706
3 changed files with 127 additions and 2 deletions

View File

@ -84,3 +84,16 @@ class PaymentHub:
return await self.stripe_manager.invoke_checkout_session_webhook(
payload, stripe_signature
)
async def handle_account_update(
self,
account_id: str,
details_submitted: bool,
payouts_enabled: bool,
charges_enabled: bool
) -> bool:
return await self.payment_manager.update_stripe_account_status(
account_id,
setup=details_submitted,
verified=payouts_enabled and charges_enabled
)

View File

@ -1,11 +1,13 @@
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:
pass
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)
@ -26,3 +28,79 @@ class PaymentManager:
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

View File

@ -1,9 +1,10 @@
from fastapi import APIRouter
from fastapi import APIRouter, Request, Header
from backend.application.payment_hub import PaymentHub
from typing import Dict, Optional, Tuple
from decimal import Decimal
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
import stripe
router = APIRouter()
payment_hub = PaymentHub()
@ -184,3 +185,36 @@ async def fetch_checkout_session_url(transaction_id: str) -> Optional[str]:
)
async def invoke_checkout_session_webhook(payload: str, stripe_signature: str):
return await payment_hub.invoke_checkout_session_webhook(payload, stripe_signature)
@router.post(
"/webhook/account",
operation_id="stripe_account_webhook",
summary="Handle Stripe account webhook events",
)
async def handle_account_webhook(
request: Request,
stripe_signature: str = Header(None)
):
payload = await request.body()
try:
event = stripe.Webhook.construct_event(
payload,
stripe_signature,
app_settings.STRIPE_WEBHOOK_SECRET
)
# Handle account.updated event
if event.type == 'account.updated':
account = event.data.object
return await payment_hub.handle_account_update(
account_id=account.id,
details_submitted=account.details_submitted,
payouts_enabled=account.payouts_enabled,
charges_enabled=account.charges_enabled
)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
return JSONResponse(content={"status": "success"})