You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Stripe Webhook中调用FastAPI异步函数,现有方案是否有误?

错误根本原因

  1. 依赖注入机制误用:FastAPI的Depends()只有在框架处理HTTP请求时才会自动解析注入对应实例,你手动调用get_current_user()路由函数时,authorize参数拿到的是原始的Depends对象,不是实例化后的AuthJWT对象,因此触发属性不存在报错。
  2. 业务逻辑错误:Stripe webhook请求是Stripe官方服务器发送的,不会携带你站点用户的JWT凭证,就算解决依赖问题也无法拿到当前登录用户ID,这个实现逻辑从根上就不成立。

正确实现方案

核心思路

创建Stripe验证会话时,通过metadata字段绑定当前发起验证的用户ID,webhook收到验证成功事件时,直接从事件数据中取出用户ID更新对应的字段即可,不需要依赖用户登录态。

修改后代码示例

1. 创建验证会话时绑定用户ID

@app.post('/create-verification-session')
# 新增依赖获取当前登录用户ID
async def create_verification_session(request: Request, authorize: AuthJWT = Depends()):
    authorize.jwt_required()
    current_user_id = authorize.get_jwt_subject()
    verification_session = stripe.identity.VerificationSession.create(
        type='document',
        # 将用户ID存入会话元数据,后续webhook事件会携带该信息
        metadata={
            "user_id": current_user_id
        }
    )
    return verification_session.client_secret

2. 抽离用户验证状态更新逻辑

# 不要把更新逻辑写为路由,封装为接收用户ID参数的通用函数
async def update_user_verification_status(user_id: str):
    await UserModel.filter(id=user_id).update(id_verified = True)

3. 调整webhook处理逻辑

@app.post('/verification-session-webhook')
async def webhook(request: Request ):
    webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET')
    data = await request.body()
    signature = request.headers.get('stripe-signature')
    try:
        event = stripe.Webhook.construct_event(
            payload=data,
            sig_header=signature,
            secret=webhook_secret
        )
        event_data = event['data']['object']
    except stripe.error.SignatureVerificationError as e:
        print(str(e))
        return {'error': str(e)}
    event_type = event['type']
    
    if event_type == 'identity.verification_session.created':
        print("Started verification")
        print(event_data.url)
    if event_type == 'identity.verification_session.verified':
        print("All the verification checks passed")
        # 从事件元数据中取出关联的用户ID
        user_id = event_data.get('metadata', {}).get('user_id')
        if user_id:
            await update_user_verification_status(user_id)
    return {'status': "success"}

原来的/user、/user/verify路由如果有其他业务使用可以保留,不需要删除,只需保证webhook逻辑不直接调用带依赖注入的路由函数即可。

内容的提问来源于stack exchange,提问作者Jiman Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:45:03