AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79071071
Accepted
user27717667
user27717667
Asked: 2024-10-09 23:47:55 +0800 CST2024-10-09 23:47:55 +0800 CST 2024-10-09 23:47:55 +0800 CST

Stripe 结账会话创建多个客户

  • 772

我正在我的项目中设置 Stripe 用于付款,但在管理客户方面遇到了一些问题。

我试图做的是创建一个新客户,并在用户创建结帐会话时将条纹客户 ID 存储在我的数据库中。问题是,在用户完成付款后,正在创建另一个客户。

@app.post('/create-checkout-session')
async def create_checkout_session(request: Request):
  

    data = await request.json()

    price_id = data['price_id']
    user_id = data['user_id']
    base_url = data['base_url']
    stripe_customer_id = data.get('stripe_customer_id')

    try:
        if stripe_customer_id is not None:
            stripe_customer = stripe.Customer.retrieve(stripe_customer_id)

            if stripe_customer:
                print('stripe_customer', stripe_customer)
                return  
        else:
            print('request', request)
            stripe_customer = stripe.Customer.create(metadata={"user_id": user_id})
            customer_id = stripe_customer.id
            await update_user_with_stripe_customer_id(user_id, customer_id)  
        
        checkout_session = stripe.checkout.Session.create(
            customer=stripe_customer_id,
            line_items=[
                {
                    'price': price_id,
                    'quantity': 1,
                },
            ],
            mode='subscription',
            success_url=base_url + '/payment-success',
            cancel_url=base_url + '?canceled=true',
            client_reference_id=user_id,
        )
        
        logger.info(f"Checkout session created successfully: {checkout_session.id}")
        return JSONResponse(content={"url": checkout_session.url}, status_code=200)
    except stripe.error.StripeError as e:
        logger.error(f"Stripe error: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error creating checkout session: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

async def update_user_with_stripe_customer_id(user_id: str, stripe_customer_id: str):
    db = firestore.client()
    user_ref = db.collection('customers').where(filter=FieldFilter("user_id", "==", user_id))
    user_docs = user_ref.get()

    if user_docs:
        user_doc = user_docs[0]
        user_doc.reference.update({
            'stripe_customer_id': stripe_customer_id
        })
        print(f"Updated user {user_id} with Stripe customer ID {stripe_customer_id}")
    else:
        logger.error(f"User {user_id} not found in database")
        raise HTTPException(status_code=404, detail="User not found") 

结账会话完成且付款成功后,我想更新数据库以向用户提供分配的信用额度。但是我收到 404 未找到用户错误。

@app.post('/webhook')
async def webhook_received(request: Request):
    print("Webhook received!")
    payload = await request.body()
    sig_header = request.headers.get('stripe-signature')
    logger.info(f"Stripe signature: {sig_header}")

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, STRIPE_WEBHOOK_SECRET
        )
        print(f"Event constructed: {event['type']}")
    except ValueError as e:
        logger.info(f"Invalid payload: {str(e)}")
        raise HTTPException(status_code=400, detail='Invalid payload')
    except stripe.error.SignatureVerificationError as e:
        logger.info(f"Invalid signature: {str(e)}")
        raise HTTPException(status_code=400, detail='Invalid signature')

    if event['type'] == 'checkout.session.completed':
        logger.info("Checkout session completed event received")
        return
        session = event['data']['object']
        try:
            result = await handle_checkout_session_completed(session)
            return JSONResponse(content={"status": "success", "result": result}, status_code=200)
        except Exception as e:
            logger.error(f"Error handling checkout session: {str(e)}")
            return JSONResponse(content={"status": "error", "message": str(e)}, status_code=500)
    elif event['type'] =='invoice.paid':
        logger.info("Invoice paid event received")
        session = event['data']['object']
        try:
            result = await handle_invoice_paid(session)
            return JSONResponse(content={"status": "success", "result": result}, status_code=200)
        except Exception as e:
            logger.error(f"Error handling invoice paid: {str(e)}")
            return JSONResponse(content={"status": "error", "message": str(e)}, status_code=500)
    else:
        logger.info(f"Unhandled event type: {event['type']}")

async def handle_invoice_paid(session):
    print('session', session)
    credits = session.get('lines').data[0].plan.metadata.credits
    tier = session.get('lines').data[0].plan.metadata.tier
    stripe_customer_id = session.get('customer')
    print('credits', credits, tier, stripe_customer_id)

    if credits:
        db = firestore.client()
        user_ref = db.collection('customers').where(filter=FieldFilter("stripe_customer_id", "==", stripe_customer_id))
        user_docs = user_ref.get()

        if user_docs:
            user_doc = user_docs[0]
            user_doc.reference.update({
                'credits': credits,
                'current_subscription_tier': tier,
                'stripe_customer_id': stripe_customer_id
            })
            updated_user_doc = user_doc.reference.get()
            updated_user_data = updated_user_doc.to_dict()
            return JSONResponse(content={"updated_user": updated_user_data}, status_code=200)
        else:
            print(f"User document not found for user_id: {stripe_customer_id}")
            raise HTTPException(status_code=404, detail="User not found")
    else:
        print(f"credits: {credits} not found")  

我尝试过不同的方法来创建客户。最终我需要用客户 ID 来更新数据库,但我的问题是,由于要创建多个用户,因此有多个客户 ID。

python
  • 1 1 个回答
  • 21 Views

1 个回答

  • Voted
  1. Best Answer
    koopajah
    2024-10-10T00:02:45+08:002024-10-10T00:02:45+08:00

    代码的第一部分似乎要么尝试检索现有的 Customer 对象(如果有),要么创建一个全新的 Customer 对象。此时您应该有一个cus_1234对应于将要向您付款的特定最终客户的 ID。

    但是,当您随后创建结帐会话时,您永远不会向 Stripe 提供您希望他们使用的现有客户对象的 ID。因此,他们会为您创建一个新的。您应该做的是在创建该结帐会话时将 ID 传递到参数cus_1234中。customer

    • 0

相关问题

  • 如何将 for 循环拆分为 3 个单独的数据框?

  • 如何检查 Pandas DataFrame 中的所有浮点列是否近似相等或接近

  • “load_dataset”如何工作,因为它没有检测示例文件?

  • 为什么 pandas.eval() 字符串比较返回 False

  • Python tkinter/ ttkboostrap dateentry 在只读状态下不起作用

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve