stripe-kraken-dev / funciones.py
Moibe's picture
Setup Future Usage Null
7e0ea75
import stripe
import globales
stripe.api_key = globales.llave
def create_checkout_session(price_id, customer_email=None, customer_id=None, firebase_user=None, unidades=None, mode=None):
"""
Crea una nueva Checkout Session para un pago 煤nico.
Busca o crea un cliente en Stripe si no se provee customer_id ni customer_email,
usando firebase_user como m茅todo de b煤squeda principal si est谩 disponible.
Args:
price_id (str): El ID del precio en Stripe para el art铆culo que se va a comprar.
customer_email (str, opcional): Email para pre-rellenar o asociar con un cliente existente.
customer_id (str, opcional): ID de un cliente existente en Stripe para asociar la sesi贸n.
firebase_user (str, opcional): ID de usuario de Firebase. Se usar谩 para buscar
un cliente de Stripe si customer_id/email no est谩n presentes.
Returns:
str: La URL de la Checkout Session, o None si hay un error.
"""
try:
# --- L贸gica para obtener o crear el Customer de Stripe ---
final_customer_id = customer_id # Empezamos con el customer_id si ya lo tenemos
if not final_customer_id: # Si no tenemos un customer_id directo, intentamos buscar/crear
found_customer = None
# Prioridad 1: Buscar por firebase_user en metadata
if firebase_user:
search_query = f"metadata['firebase_user']:'{firebase_user}'"
print(f"Buscando cliente por Firebase UID: {firebase_user}")
existing_customers_by_firebase = stripe.Customer.search(query=search_query, limit=1)
if existing_customers_by_firebase.data:
found_customer = existing_customers_by_firebase.data[0]
print(f"Cliente encontrado por Firebase UID: {found_customer.id}")
final_customer_id = found_customer.id
# Prioridad 2: Si no se encontr贸 por firebase_user, y tenemos un email, buscar por email
if not final_customer_id and customer_email:
print(f"Cliente no encontrado por Firebase UID. Buscando por email: {customer_email}")
existing_customers_by_email = stripe.Customer.list(email=customer_email, limit=1)
if existing_customers_by_email.data:
found_customer = existing_customers_by_email.data[0]
print(f"Cliente encontrado por email: {found_customer.id}")
final_customer_id = found_customer.id
# Opcional: Si lo encontraste por email pero falta el firebase_user, actual铆zalo
if firebase_user and (not found_customer.metadata or found_customer.metadata.get('firebase_user') != firebase_user):
print(f"Actualizando firebase_user para cliente {found_customer.id}")
updated_metadata = found_customer.metadata.copy() if found_customer.metadata is not None else {}
updated_metadata['firebase_user'] = firebase_user
stripe.Customer.modify(found_customer.id, metadata=updated_metadata)
# Si despu茅s de las b煤squedas, todav铆a no tenemos un customer_id, y tenemos email, creamos uno nuevo
if not final_customer_id and customer_email:
print(f"Cliente no encontrado. Creando nuevo cliente con email: {customer_email}")
customer_metadata = {}
if firebase_user:
customer_metadata['firebase_user'] = firebase_user
new_customer = stripe.Customer.create(
email=customer_email,
metadata=customer_metadata if customer_metadata else None # Asegura que no se env铆e un diccionario vac铆o si no hay metadata
)
final_customer_id = new_customer.id
print(f"Nuevo cliente creado: {final_customer_id}")
elif not final_customer_id and not customer_email and firebase_user:
# Si no hay email, pero hay firebase_user, tambi茅n podr铆amos crear un cliente
# Esto es menos com煤n pero posible si el email no es obligatorio para ti.
print(f"Cliente no encontrado. Creando nuevo cliente (sin email) con Firebase UID: {firebase_user}")
customer_metadata = {'firebase_user': firebase_user}
new_customer = stripe.Customer.create(
metadata=customer_metadata
)
final_customer_id = new_customer.id
print(f"Nuevo cliente creado (sin email): {final_customer_id}")
# Nota: Si no hay customer_id, customer_email, ni firebase_user, final_customer_id seguir谩 siendo None
# y la sesi贸n de checkout se crear谩 sin un cliente asociado expl铆citamente. Stripe puede crearlo
# autom谩ticamente en el checkout si se recopila el email.
print("Estoy por entrar y el mode es: ", mode)
# --- Par谩metros de la Checkout Session ---
session_params = {
'line_items': [{
'price': price_id,
'quantity': 1, #maneja cantidades cuando es subscription
}],
'mode': mode, #payment o subscription
#'payment_method_types': ['card'],
'success_url': 'https://app.splashmix.ink/',
'cancel_url': 'https://app.splashmix.ink/buy',
'locale': 'auto',
# 'client_reference_id': 'HERC',
'metadata': {
'imagenes': unidades
},
'payment_intent_data': {
'setup_future_usage': None # En Python usamos None en lugar de null
}
}
# Asociar el cliente encontrado/creado a la sesi贸n
if final_customer_id:
session_params['customer'] = final_customer_id
session_params['metadata']['stripe_customer_id'] = final_customer_id # 脷til para webhooks
# Pre-rellenar el email si est谩 disponible y no se asoci贸 un customer_id directamente
# (Stripe recomienda usar 'customer' en lugar de 'customer_email' si ya tienes el ID del cliente)
elif customer_email:
session_params['customer_email'] = customer_email
# A帽adir firebase_user a la metadata de la sesi贸n si est谩 presente
if firebase_user:
session_params['metadata']['firebase_user'] = firebase_user
# Limpiar metadata si qued贸 vac铆a (Stripe no acepta diccionarios vac铆os)
if not session_params['metadata']:
del session_params['metadata']
session = stripe.checkout.Session.create(**session_params)
print(f"Checkout Session creada exitosamente. ID: {session.id}")
print(f"URL de redirecci贸n: {session.url}")
return session.url
except stripe.error.StripeError as e:
print(f"Error de Stripe al crear la Checkout Session: {e}")
return None
except Exception as e:
print(f"Ocurri贸 un error inesperado al crear la Checkout Session: {e}")
return None
def create_stripe_customer(email, firebase_user=None, site=None):
"""
Busca un cliente existente en Stripe, priorizando el Firebase User ID usando Customer.search.
Si el cliente no existe por Firebase User ID, intenta buscar por email.
Si el cliente tampoco existe por email, lo crea.
Args:
email (str): La direcci贸n de correo electr贸nico del cliente.
(Se usar谩 para buscar si el cliente ya existe si no se encuentra por Firebase UID).
firebase_user (str, opcional): El ID de usuario de Firebase. **Identificador principal para la b煤squeda.**
Se agregar谩 a 'metadata'.
site (str, opcional): El nombre del sitio de origen. Se agregar谩 a 'metadata'.
Returns:
tuple: (stripe.Customer, str) donde el string indica "found_by_firebase_user", "found_by_email" o "created".
None: Si ocurre un error.
"""
try:
customer_found_status = None
found_customer = None
# --- 1. Intentar buscar un cliente existente por firebase_user (PRIORIDAD ALTA con Customer.search) ---
if firebase_user:
# Usamos stripe.Customer.search para buscar en metadata.
# Aseg煤rate de escapar comillas si el firebase_user pudiera contenerlas,
# aunque los UIDs de Firebase no suelen tenerlas.
search_query = f"metadata['firebase_user']:'{firebase_user}'"
print(f"Buscando cliente con query: {search_query}") # Para depuraci贸n
# search retorna un StripeSearchResultObject, que se itera como una lista
existing_customers_by_firebase = stripe.Customer.search(query=search_query, limit=1)
if existing_customers_by_firebase.data:
found_customer = existing_customers_by_firebase.data[0]
customer_found_status = "found_by_firebase_user"
print(f"Cliente existente encontrado por Firebase User ID. ID: {found_customer.id}")
# --- 2. Si no se encontr贸 por firebase_user, intentar buscar por email ---
if not found_customer:
print(f"Cliente no encontrado por Firebase UID. Buscando por email: {email}") # Para depuraci贸n
existing_customers_by_email = stripe.Customer.list(email=email, limit=1)
if existing_customers_by_email.data:
found_customer = existing_customers_by_email.data[0]
customer_found_status = "found_by_email"
print(f"Cliente existente encontrado por email. ID: {found_customer.id}")
# Opcional: Si lo encontraste por email pero tiene un firebase_user nuevo o nulo, actual铆zalo
# o si el site difiere, tambi茅n actualizarlo.
updated_metadata = found_customer.metadata.copy() if found_customer.metadata is not None else {}
needs_update = False
if firebase_user and updated_metadata.get('firebase_user') != firebase_user:
updated_metadata['firebase_user'] = firebase_user
needs_update = True
if site and updated_metadata.get('site') != site:
updated_metadata['site'] = site
needs_update = True
if needs_update:
print(f"Actualizando metadata para cliente {found_customer.id}")
found_customer = stripe.Customer.modify(found_customer.id, metadata=updated_metadata)
# Si se encontr贸 un cliente (por cualquiera de los m茅todos), lo retornamos
if found_customer:
return found_customer, customer_found_status
# --- 3. Si el cliente no existe (ni por firebase_user ni por email), crearlo ---
print(f"Cliente con email '{email}' y/o firebase_user '{firebase_user}' no encontrado. Creando nuevo cliente...")
customer_params = {
'email': email,
}
customer_metadata = {}
if firebase_user:
customer_metadata['firebase_user'] = firebase_user
if site:
customer_metadata['site'] = site
if customer_metadata:
customer_params['metadata'] = customer_metadata
customer = stripe.Customer.create(**customer_params)
print(f"Nuevo cliente creado exitosamente. ID: {customer.id}")
return customer, "created"
except stripe.error.StripeError as e:
print(f"Error de Stripe al buscar o crear el cliente: {e}")
return None
except Exception as e:
print(f"Ocurri贸 un error inesperado: {e}")
return None