Stripe 结帐会话创建多个客户

问题描述 投票:0回答:1

我正在项目中设置 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 stripe-payments
1个回答
0
投票

代码的第一部分似乎要么尝试检索现有的 Customer 对象(如果有),要么创建一个全新的 Customer 对象。此时,您应该有一个

cus_1234
,它是与将向您付款的特定最终客户相对应的 ID。

当您随后创建 Checkout Session 时,尽管您从未向 Stripe 提供您希望他们使用的现有 Customer 对象的 id。因此,他们将为您创建一个新的。您应该做的是在创建结帐会话时在

cus_1234
parameter
中传递 customer id。

© www.soinside.com 2019 - 2024. All rights reserved.