main content

Cómo implementar un sistema de gestión de eventos y reservas online con calendario interactivo y pagos integrados en Drupal

Si tu web no permite reservar a las 23:47 de un domingo, estás perdiendo clientes. Esa franja de "fuera de horario" se ha convertido en la primera línea comercial de clínicas, escuelas de formación, espacios coworking y cualquier negocio que venda tiempo o aforo. Lo bueno es que no necesitas montar una herencia tecnológica de cinco SaaS pegados con cinta americana: Drupal, en sus versiones 10 y 11, trae todo el andamiaje para construir esto en casa, con tus reglas y tus márgenes.

A lo largo de las siguientes secciones recorremos una implementación seria de gestión de eventos en Drupal: desde el modelo de datos hasta el cobro con 3DS2, pasando por listas de espera, paneles de organizador y los típicos sustos de rendimiento cuando se abre la inscripción de un curso popular.

Por qué Drupal y no otra cosa

Antes de ponernos a instalar módulos, conviene justificar la elección. Drupal no es la opción más rápida para salir con un MVP de fin de semana, pero sí la más sólida cuando hablas de aforo, disponibilidad en tiempo real y reglas de negocio que cambian cada trimestre.

Tres motivos pesan más que el resto. Primero, eres dueño del dato: nada de exportar reservas desde un panel ajeno cuando decidas migrar. Segundo, el modelo de entidades y campos te deja describir tu negocio tal como es —sesiones recurrentes, precios por perfil, descuentos por código, capacidad por sala— sin contorsionar la herramienta. Y tercero, la base Symfony te da una API REST y JSON:API listas para conectar el calendario interactivo con tu CRM, con Google Calendar o con un panel interno de operaciones.

Comparado con un WordPress lleno de plugins de pago anual o con un SaaS que cobra por reserva, el TCO a tres años suele jugar a favor de Drupal en cuanto el volumen pasa de unos pocos cientos de inscripciones al mes.

El modelo de datos manda

Aquí es donde se gana o se pierde el proyecto. Una mala arquitectura de contenidos te condena a parches eternos; una buena te permite añadir tipos de evento durante años sin tocar código.

Tipo de contenido Evento

El nodo central es Evento. Estos son los campos que casi siempre acaban siendo necesarios:

  • Título y descripción larga con CKEditor 5.
  • Fecha y hora de inicio/fin con Smart Date, que maneja recurrencias y zonas horarias mucho mejor que el campo Date clásico.
  • Capacidad máxima como entero, y un campo calculado de plazas disponibles que se actualiza vía hook o computed field.
  • Precio base, gestionado realmente desde Drupal Commerce (el nodo solo refleja el importe para mostrarlo).
  • Taxonomía de categorías y otra de modalidad (presencial, online, híbrido).
  • Media para el banner mediante el módulo Media core.
  • Referencia a una entidad Ubicación cuando reutilizas espacios.

Si los eventos tienen estructura interna compleja —agenda por horas, ponentes, materiales descargables—, la combinación de Paragraphs y Entity Reference Revisions evita reinventar la rueda.

Entidad Reserva

La inscripción debe vivir como entidad propia, no como subcampo del evento. Lo hacemos así para poder consultarla, filtrarla y exportarla sin sufrir. Campos típicos:

  • Referencia al evento y al usuario (o a un perfil de invitado anónimo).
  • Estado mediante el módulo Content Moderation del core: borrador, pendiente_pago, confirmada, lista_espera, cancelada, asistida.
  • Número de plazas, importe total, método de pago y referencia de la transacción.
  • Marcas de tiempo de cada cambio de estado, útiles para auditoría y soporte.

Modelar la reserva como entidad independiente te permite construir vistas administrativas potentes con Views, exportar a CSV con un par de clics y, sobre todo, montar la lógica de cupos sin volverte loco.

Los módulos que de verdad se usan

El catálogo de Drupal.org es enorme y no todo está al día. Estos son los que en proyectos reales sobreviven a la puesta en producción.

Drupal Commerce para el dinero

Drupal Commerce es el corazón comercial. Define la entrada como producto, gestiona variaciones (general, reducida, estudiante), aplica impuestos por país y conecta con pasarelas. El submódulo Commerce Promotion se encarga de cupones y descuentos por volumen, y Commerce Stock permite vincular el inventario de plazas al producto, descontando automáticamente cuando se confirma el cobro.

Para mercado español, Commerce Redsys integra con la mayoría de TPV bancarios y cumple PSD2 con autenticación 3DS2 sin que tengas que tocar nada del protocolo. Si vendes fuera de España, Commerce Stripe sigue siendo la opción más limpia y bien mantenida.

Booking y Event Platform

Para flujos puramente de reserva sin carrito, Booking System y Event Platform ofrecen tipos de contenido y vistas precocinados. Event Platform en concreto está muy orientado a conferencias multi-sesión con tracks y ponentes; si tu caso encaja, te ahorra semanas. Commerce Booking tiende un puente entre la reserva por franja horaria y el carrito de Commerce, útil para servicios profesionales o alquileres por horas.

Calendario visual con FullCalendar

Aquí la combinación ganadora son los módulos Calendar y FullCalendar View, que enchufan una Vista de Drupal directamente contra la librería JavaScript FullCalendar. Resultado: un calendario interactivo Drupal navegable por mes, semana y día, con filtros por categoría, indicadores de disponibilidad y popovers de ficha. La configuración se hace desde la UI de Views, sin escribir una línea de JS personalizado salvo que quieras estilo a medida.

Un consejo práctico: expón el calendario también vía JSON:API para reutilizarlo desde una app móvil o un widget embebido en otra web del cliente.

Formularios complejos con Webform

Cuando la reserva pide datos extra —restricciones alimentarias, talla de camiseta, nivel previo—, Webform sigue siendo la navaja suiza. Tiene lógica condicional, validaciones, anti-spam y handlers para empujar los datos a un CRM o a una hoja de cálculo. Lo conectas con la entidad Reserva mediante un handler personalizado y listo.

Pagos integrados sin sobresaltos

La parte de cobro es donde más proyectos se atascan, así que merece detalle. El flujo que montamos habitualmente con Drupal Commerce funciona así.

El usuario elige plazas y modalidad y aterriza en el checkout. Si está logado, los datos de facturación se autocompletan desde su perfil. Selecciona pasarela —Stripe para tarjeta internacional, Redsys para banca española, transferencia para clientes corporativos—. La autorización se hace siempre del lado de la pasarela: Drupal recibe un token, nunca el PAN de la tarjeta. Solo cuando el webhook de la pasarela confirma el cobro se crea la entidad Reserva en estado confirmada y se disparan los correos.

Para que esto sea fiable bajo carga, los webhooks de confirmación se procesan a través de Queue API y Advanced Queue. Así, si Stripe te lanza diez confirmaciones simultáneas durante el sold-out de un curso, no colapsas la base de datos ni dejas reservas a medio crear.

Las cancelaciones y reembolsos viven en el panel de pedidos de Commerce, con políticas configurables: reembolso íntegro hasta X días antes, parcial después, no reembolsable a partir de Y. Todo registrado y auditable.

Lista de espera que de verdad funciona

Cuando se llena el aforo, lo peor es perder al usuario. La lista de espera bien hecha convierte un "no" en un "quizá mañana". Cómo lo montamos:

  • El formulario detecta aforo completo y cambia el CTA a "Unirme a la lista de espera", capturando email y plazas deseadas.
  • Si alguien cancela, un servicio personalizado lanzado vía ECA (Event Condition Action, el sustituto moderno de Rules) notifica al primero de la cola con un enlace temporal de confirmación, típicamente con 12 o 24 horas de validez.
  • Si no confirma a tiempo, la plaza pasa al siguiente. Todo esto se ejecuta en background con la Queue API para que el usuario que cancela no espere a que terminen los avisos.

Es una lógica simple sobre el papel y diabólica en producción si no piensas bien los estados intermedios. Documenta cada transición.

El panel del organizador

El equipo interno necesita herramientas tan buenas como las del usuario final, o más. Lo mínimo decente incluye:

  • Vista de asistentes con filtros por estado y exportación a XLSX vía Views Data Export.
  • Indicadores de ocupación, ingresos y ritmo de inscripciones, idealmente con un bloque de Charts o un widget conectado a Metabase.
  • Envío de comunicaciones masivas a los inscritos de un evento concreto, integrado con Symfony Mailer y plantillas Twig.
  • Permisos granulares: cada organizador ve y edita solo sus eventos, gracias al módulo Group o a reglas de acceso por campo.

Este panel suele ser la diferencia entre que el cliente use el sistema o vuelva a la hoja de cálculo del año pasado.

Que no se caiga el día del lanzamiento

Un curso popular puede generar mil sesiones simultáneas en cinco minutos. Para llegar vivo a esa franja:

  • Cachea el calendario público y la página de listado, e invalida solo cuando cambia disponibilidad mediante cache tags bien definidos.
  • Refresca el contador de plazas con peticiones AJAX ligeras, no recargando toda la vista.
  • Indexa los campos de fecha, estado de reserva y referencia a evento; sin esos índices, una base con 50.000 reservas empieza a sufrir.
  • Pon una CDN delante (Cloudflare o similar) y configura Purge para invalidar cachés externas cuando se publica o agota un evento.
  • Monitoriza con New Relic o equivalente: detectar una query lenta antes del pico te ahorra el incidente.

Lo que sale mal en estos proyectos

Después de varios proyectos de gestión de eventos en Drupal, los errores se repiten. Tipos de contenido demasiado rígidos que no contemplan un evento híbrido o multi-sede. Integraciones de pago hechas contra la pasarela "fácil" sin pensar en el cliente español que exige Redsys. Notificaciones por correo enviadas de forma síncrona que tumban el checkout cuando el SMTP va lento. Y, casi siempre, una arquitectura de reservas que mezcla estados de pago con estados de asistencia, generando reportes imposibles de cuadrar.

Diseñar bien desde el principio cuesta unas semanas; rediseñarlo a los seis meses cuesta un trimestre.

Si estás valorando montar un sistema de eventos y reservas online sobre Drupal y quieres una segunda opinión sobre arquitectura, módulos o estrategia de pagos integrados, cuéntanos tu caso y te damos una propuesta concreta.