AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 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

Sessão de checkout do Stripe criando vários clientes

  • 772

Estou configurando o Stripe para pagamentos no meu projeto e estou tendo alguns problemas para gerenciar clientes.

O que estou tentando fazer é criar um novo cliente e armazenar o ID do cliente do Stripe no meu banco de dados quando o usuário cria uma sessão de checkout. O problema é que, depois que o usuário conclui o pagamento, outro cliente está sendo criado.

@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") 

Após a conclusão de uma sessão de checkout e o pagamento bem-sucedido, quero atualizar meu banco de dados para dar ao usuário os créditos alocados. No entanto, estou recebendo um erro 404 usuário não encontrado.

@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")  

Eu tentei diferentes implementações para criar o cliente. No final, preciso atualizar meu banco de dados com o id do cliente, mas meu problema é que, como vários usuários estão sendo criados, há vários ids de clientes.

python
  • 1 1 respostas
  • 21 Views

1 respostas

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

    A primeira parte do seu código parece tentar recuperar um objeto Customer existente, se houver, e, de outra forma, criar um novo objeto Customer. Nesse ponto, você deve ter um cus_1234que é o id correspondente àquele cliente final específico que vai pagar você.

    Quando você cria a Checkout Session depois, você nunca dá ao Stripe o id do objeto Customer existente que você quer que eles usem. Então, em vez disso, eles criarão um novo para você. O que você deve fazer é passar o cus_1234id no customer parâmetro quando você cria essa Checkout Session.

    • 0

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve