Respi
Reserva de pistas · móvil y web
App para reservar pistas deportivas con pago integrado. Proyecto final de DAM en equipo de tres; mi parte, los pagos con Stripe de extremo a extremo.
El proyecto
Reservar una pista de un polideportivo desde el móvil, de principio a fin: ver la disponibilidad, elegir hora, pagar con tarjeta y presentar un código en la instalación. La administración lo gestiona todo desde su propio panel.
Respi conecta a los usuarios de un polideportivo con sus pistas: consultar disponibilidad, reservar, pagar y valorar. La administración tiene su propio panel para gestionar pistas, horarios, precios, reservas, usuarios y pagos.
Es el proyecto final de DAM de un equipo de tres personas. La aplicación está hecha con React Native y Expo, con una sola base de código para Android, iOS y web, y consume una API REST propia en NestJS con MariaDB, desplegada en un VPS.
Funcionalidades principales
- Disponibilidad de cada pista por franja horaria
- Reserva en tres pasos: pista, datos y confirmación
- Pago con tarjeta y reembolso al cancelar
- Código QR para validar la reserva en la instalación
- Panel de administración: pistas, horarios, precios, usuarios y pagos
- Una sola base de código para Android, iOS y web
Mi aportación
El repositorio lo lideró Christopher, autor de la mayor parte de la aplicación, con Javi y conmigo en áreas concretas. La mía fue acotada y de extremo a extremo: todo lo que tiene que ver con cobrar una reserva.
Pagos con Stripe en la API
El módulo de NestJS completo: creación del PaymentIntent, webhook con verificación de firma, confirmación de la reserva, reembolsos al cancelar y sus tests.
Pagos en la app
El hook de pago, con una implementación por plataforma tras la misma interfaz, y la pantalla de gestión de pagos del panel de administración.
Flujo de reserva
La lógica de creación de reservas (tipo de pista, pista, fecha, hora, duración y confirmación) y el historial con estados, cancelación y código de verificación.
Arranque de la API
Primeras entidades y relaciones de TypeORM, DTOs, seeders y documentación Swagger, en la fase inicial del proyecto.
Revisión final
Pasada de corrección antes de la entrega: modales propios en lugar de alertas nativas, etiquetas de accesibilidad y arreglos en autenticación, pagos y rutas de administración.
- commits de la app
- 56 / 493 (11 % del total)
- commits de la API
- 49 / 511 (10 % del total)
- tests propios de pagos y reservas
- 23
- personas en el equipo
- 3
Commits sin fusiones en la rama principal, según el historial de Git.
Decisiones técnicas
El importe lo fija el servidor
El PaymentIntent se crea en la API a partir del precio guardado de la reserva: el cliente nunca envía la cantidad. Y solo si la reserva pertenece al usuario autenticado; en otro caso, 403.
Un webhook que desconfía
La confirmación llega por webhook. El endpoint lee el cuerpo sin procesar, verifica la firma de Stripe con el secreto del webhook y rechaza todo lo que no la supere. Para entornos de demostración sin webhook hay una confirmación manual autenticada.
Idempotencia
Stripe puede reenviar un evento. Antes de tocar nada se comprueba el estado de la reserva: si ya está confirmada, el evento se ignora y el pago no se duplica. La misma regla impide crear un segundo PaymentIntent para una reserva pagada.
Un contrato, tres implementaciones
El hook
useStripePaymentexiste en tres ficheros y Metro elige por plataforma: hoja de pago nativa en móvil, Stripe.js en web y, en Expo Go, donde el módulo nativo no está disponible, una hoja simulada para seguir probando el flujo.Cancelar no depende del reembolso
Al cancelar una reserva confirmada se lanza el reembolso y se guardan su identificador e importe; si el pago no pasó por Stripe, solo se marca como reembolsado. La cancelación se completa aunque el reembolso falle. 23 tests cubren propiedad, firma inválida, idempotencia y reembolsos.
Evolución
Sep – Nov 2025
Arranque de la API: entidades, relaciones, DTOs, seeders y Swagger.
Mar – Abr 2026
Primeras pantallas de reserva y mejoras de la pantalla de inicio.
May 2026
Integración de Stripe en API y app, reembolsos, tests, pagos del panel de administración y revisión final.
Jul 2026
Entrega del proyecto final.
Stack
App
- React Native
- Expo Router
- TypeScript
- Zustand
- Axios
- i18next
- Stripe
API
- NestJS
- TypeORM
- MariaDB
- JWT
- Swagger
- Jest
Infraestructura
- Docker Compose
- PM2
- GitHub Actions
- VPS
Capturas
Segundo paso de la reserva, con hora, duración y total estimado. Historial con el estado de cada reserva y de su pago. Detalle de la reserva con el código de verificación. Pantalla de pagos del panel de administración.
Capturas de la versión web ejecutada en local con datos de demostración. El diseño visual de la app es trabajo del equipo; mi parte es la que se describe más arriba.


