Volver a casos de estudio
Fajo Group•Entretenimiento / Rifas y sorteos / E-commerce

Plataforma de rifas y sorteos Fajo Group

Sistema integral para gestionar rifas, notificaciones por WhatsApp (Meta), incluye tienda pública, panel de administración y API REST con arquitectura por capas.

El Problema

Situación que debíamos resolver

Se presentaba una operación manual y poco escalable, la gestión de rifas, números por serie, reservas, pagos y ganadores se llevaba a cabo con hojas de cálculo y procesos dispersos, lo que generaba errores y limitaba el crecimiento.

Además, existía el problema de las reservas sin pago, donde los números quedaban bloqueados indefinidamente si el comprador no completaba la transacción. Era necesario implementar un sistema que liberara automáticamente esos números y notificara al cliente por WhatsApp.

Otro reto era la trazabilidad y legalidad, se debía garantizar que cada sorteo quedara registrado de manera transparente (número ganador, persona ganadora, premio) y que las boletas fueran verificables mediante un código único o QR.

La comunicación postventa y post-sorteotambién resultaba ineficiente, ya que dependía de envíos manuales. Se requería un canal unificado que centralizara confirmaciones de compra, entrega de boletas, avisos de liberación de números y notificación de ganadores, preferiblemente a través de WhatsApp.

Finalmente, se necesitaba soportar múltiples canales de venta: tanto la tienda web como la posible integración con WhatsApp (Kapso), manteniendo una sola fuente de verdad para órdenes y números.

Requerimientos Clave

Lo que el proyecto necesitaba

1

Gestión de rifas con estados

Borrador, activa (venta web), solo visible (contacto WhatsApp), cerrada, finalizada.

2

Números por serie con estados

Disponible, reservado (con reserved_until), vendido, ganador.

3

Reservas con tiempo límite

Liberación automática (cron cada minuto) sin bloquear números indefinidamente.

4

Pagos asociados a órdenes.

5

Motor de boletas

Plantillas configurables, generación de imágenes (Sharp + QR), almacenamiento (S3) y envío por WhatsApp (tamaño/formatos válidos).

6

Contenido editable para la tienda (CMS)

Hero, marketing (barra, promo), “cómo funciona” (site content/CMS en backend).

7

Notificaciones WhatsApp

Confirmación, boleta, número liberado, ganador, etc., con plantillas y sanitización de parámetros (límites de Meta).

La Solución

Cómo abordamos el problema

El proyecto se construyó sobre un backend en NestJS, diseñado como una API REST versionada y organizada en módulos por dominio (rifas, sorteos, ganadores, órdenes, pagos, webhooks, flujos, motor de boletas, reportes, contenido del sitio, clientes, usuarios, permisos y auditoría). La lógica de negocio se orquesta en servicios de aplicación, mientras que el dominio define entidades clave como Raffle, Draw, Winner, Usery Permission. La infraestructura se apoya en PostgreSQLpara persistencia y S3para almacenamiento de archivos. En cuanto a las reservas, al crear una orden en estado PENDING se bloquean números con estado RESERVED y un tiempo límite (reserved_until). Un proceso programado (cron cada minuto) detecta reservas vencidas sin pago, elimina ítems de la orden, cancela órdenes vacías, libera los números a AVAILABLE y envía una notificación automática por WhatsApp informando que el número fue liberado. Los sorteos se gestionan mediante el DrawExecutionService, que determina el número ganador según formato y serie, valida que pertenezca a la rifa y comprueba si está vendido (orden CONFIRMED). Luego inserta el resultado en la tabla de ganadores, actualiza el estado del número a WINNER y envía notificaciones al ganador. En caso de que el número no esté vendido, se contempla la opción de un reroll.

El motor de boletas se implemento con TicketGeneratorService, que genera imágenes mediante Sharp, con zonas configurables y códigos QR.

Decisiones Técnicas

Por qué elegimos este enfoque

El backend se diseñó siguiendo una arquitectura por capas, que favorece la evolución y las pruebas en cada nivel:

  • Domain: entidades y reglas de negocio.
  • Application: servicios y jobs que orquestan la lógica.
  • Infrastructure: base de datos PostgreSQL, almacenamiento en S3 e integración con Kapso.
  • Interfaces: controladores HTTP que exponen la API.

Las operaciones críticas —como reclamar números, liberar reservas o ejecutar sorteos— se ejecutan dentro de transacciones PostgreSQL, garantizando consistencia y atomicidad en la gestión de órdenes y números.
El frontend, desarrollado en Next.js con App Router, utiliza Server Components por defecto para cargar datos de hero, rifas y marketing directamente desde el servidor. Además, se emplea Suspense para ofrecer una carga progresiva en la página principal, mejorando la experiencia del usuario.

Resultados

Impacto medible del proyecto

85%
Reducción de trabajo manual
Notificaciones WhatsApp automáticas (confirmación, boleta, número liberado, ganador) reducen envíos manuales.
99%
Escalabilidad operativa
Un solo sistema para varias rifas, múltiples sorteos por rifa y venta web + canal WhatsApp.

Stack Tecnológico

Herramientas y por qué las elegimos

NestJSBackend
NextjsFrontend
PostgrestDevOps
RedisDevOps