Integración de Webhooks
Los webhooks permiten a Yastubo reaccionar a eventos que ocurren fuera de su sistema, como pagos exitosos, fallos de cobro o cancelaciones de suscripciones en Stripe. El sistema utiliza una arquitectura asíncrona e idempotente para asegurar que cada evento se procese exactamente una vez.
Core Benefits / Key Features
Section titled “Core Benefits / Key Features”- Procesamiento Idempotente: Garantizamos que el mismo evento no se procese dos veces gracias al registro de
StripeEvent. - Seguridad de Firma: Verificación automática de firmas para evitar ataques de suplantación.
- Transiciones de Estado Automáticas: La póliza cambia de estado (ej.
ACTIVE,IN_ARREARS) según los eventos de pago. - Conversión de Leads: Los prospectos se convierten automáticamente en clientes finales tras el primer pago exitoso.
Deep Dive Técnico: Manejo de Eventos
Section titled “Deep Dive Técnico: Manejo de Eventos”El controlador principal reside en app/modules/payments/webhook_handler.py.
Lógica de Procesamiento Segura
Section titled “Lógica de Procesamiento Segura”El flujo de trabajo para cada webhook recibido sigue estos pasos:
- Chequeo de Idempotencia: Buscamos el ID del evento en nuestra base de datos. Si ya existe, abortamos.
- Despacho por Tipo: Dependiendo del
event_type, delegamos a una lógica específica. - Persistencia de Evento: Al finalizar con éxito, marcamos el evento como procesado.
# Lógica clave de idempotencia en handle_stripe_eventres = await db.execute(select(StripeEvent).where(StripeEvent.event_id == event_id))if res.scalar_one_or_none(): logger.info(f"Stripe event {event_id} ya procesado. Ignorando.") returnEventos Principales Soportados
Section titled “Eventos Principales Soportados”| Evento | Acción en Yastubo |
|---|---|
payment_intent.succeeded | Marca la transacción como exitosa y activa la póliza. |
payment_intent.payment_failed | Incrementa el contador de intentos y notifica al cliente. |
customer.subscription.deleted | Cancela la suscripción y cambia la póliza a estado CANCELLED. |
invoice.payment_succeeded | Registra el pago recurrente de una suscripción activa. |
Ejemplo Práctico: Añadir un Nuevo Evento
Section titled “Ejemplo Práctico: Añadir un Nuevo Evento”Si deseas manejar el evento charge.refunded para gestionar reembolsos automáticos:
elif event_type == "charge.refunded": charge_id = data_obj.get("id") # Lógica para marcar transacción como reembolsada await process_refund(db, charge_id)
# Registrar el evento procesado db.add(StripeEvent(event_id=event_id, event_type=event_type)) await db.commit()Diagrama de Ciclo de Vida de Webhook
Section titled “Diagrama de Ciclo de Vida de Webhook”