stripe-kraken-dev / funciones.py
Moibe's picture
Nuevos Parámetros incluídos en createSession
b45248f
raw
history blame
11.9 kB
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 a checar el customer id que es: ", final_customer_id)
# --- 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
'success_url': 'https://app.splashmix.ink/',
'cancel_url': 'https://app.splashmix.ink/',
'locale': 'auto',
'client_reference_id': 'HERC',
'metadata': {
'imagenes': unidades
} # Inicializamos metadata para añadir el customer_id y firebase_user si existen
}
# 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