Skip to Content
WorkerReservaciones

Reservaciones

Los endpoints de reservaciones gestionan el ciclo de vida completo de una reservación de evento: creación, consulta, verificación y actualización de estado.

Todos los endpoints requieren autenticación (Authorization: Bearer <token>).


Estados de una reservación

pending ──► completed ──► failed ──► cancelled

Los estados completed, failed y cancelled son terminales — no admiten transición.


Endpoints

GET /api/reservations

Lista todas las reservaciones del usuario autenticado, incluyendo datos del evento.

Respuesta exitosa (200):

{ "data": [ { "id": "uuid", "status": "completed", "paypalOrderId": "PAYPAL-ORDER-ID", "amountPaid": 800, "currency": "MXN", "reservedAt": "2025-06-01T20:00:00Z", "paidAt": "2025-06-01T20:05:00Z", "event": { "title": "Retiro de Yoga — Verano 2025", "eventDate": "2025-07-15T10:00:00Z", "slug": "retiro-verano-2025", "priceAmount": 800 } } ] }

POST /api/reservations

Crea una nueva reservación o reactiva una cancelada/fallida.

Body:

{ "eventSlug": "retiro-verano-2025", "fullName": "Ana García", "email": "ana@email.com" }

Respuesta: 201 (nueva) o 200 (reactivada).

Lógica de upsert:

  1. Resuelve el event_id desde el slug
  2. Hace upsert del usuario en la tabla users (por clerk_user_id)
  3. Si existe una reservación en estado cancelled, failed o pending: la reactiva a pending
  4. Si no existe: inserta nueva reservación

Error 409: Ya existe una reservación activa (completed o pending nuevo) para este evento/usuario.


GET /api/reservations/check?slug=<slug>

Verifica si el usuario autenticado tiene una reservación activa para el evento indicado.

Parámetro: slug (query string) — slug del evento.

Respuesta exitosa (200):

{ "data": { "hasReservation": true, "status": "pending", "reservationId": "uuid" } }

El frontend usa este endpoint al abrir el modal de reservación para determinar si ir directo al paso de pago.


PATCH /api/reservations/:id

Actualiza el estado de una reservación. Valida que la transición sea permitida.

Body:

{ "status": "completed", "paypalOrderId": "PAYPAL-ORDER-ID", "amountPaid": 800, "currency": "MXN", "paidAt": "2025-06-01T20:05:00Z" }

Solo status es requerido. Los demás campos son opcionales y se incluyen al completar un pago.

Error 422: Transición no permitida (ej. intentar volver a pending desde completed).


Integración con el frontend

El ReservationModal llama a estos endpoints en este orden:

1. Abrir modal → GET /api/reservations/check?slug=... ↳ hasReservation: false → mostrar formulario ↳ status: "pending" → ir directo al paso de pago ↳ status: "completed" → mostrar mensaje "ya reservado" 2. Submit form → POST /api/reservations ↳ guarda reservationId en estado local 3. PayPal → POST /api/paypal/create-order (ver sección PayPal) 4. Captura → POST /api/paypal/capture-order ↳ actualiza la reservación a "completed" internamente
Last updated on