Doplax.Dev
← Volver a proyectos
TrackLap

Capacidades

  • Pasarela de pago
  • Back office
  • Email transaccional
  • Mapas interactivos

Frontend

AngularAngular
TypeScriptTypeScript
MaterialMaterial
LeafletLeaflet

Backend

NestJSNestJS
Node.jsNode.js
PostgreSQLPostgreSQL
StripeStripe
RedsysRedsys

TrackLap

En desarrollo

TrackLap es una plataforma completa para el ecosistema de las tandas de moto en circuito. Los organizadores publican eventos, configuran categorías por nivel, boxes, seguros y servicios, y cobran las inscripciones; los pilotos descubren circuitos, se inscriben, pagan online y consultan su historial. Angular 21 con Material y signals en el frontend, NestJS con TypeORM y PostgreSQL en el backend. El cobro está resuelto con dos pasarelas conviviendo: Stripe Connect y el TPV virtual Redsys del propio organizador.

El reto

Aquí la plataforma no vende: cobra en nombre de cada organizador y se queda una comisión. Eso obliga a resolver bien los pagos repartidos, a que ningún pago se confirme dos veces ni por un importe que no cuadre, y a que el organizador entienda exactamente cuánto se lleva Stripe y cuánto la plataforma. Y no todos los organizadores quieren lo mismo: unos prefieren la comodidad de Stripe, otros cobrar directamente en su banco con el TPV que ya tienen contratado, así que hubo que sostener dos pasarelas con garantías equivalentes.

Implementación

  • Stripe Connect con destination charges

    Cada organizador conecta su cuenta Standard mediante onboarding de Stripe; la plataforma procesa el cobro y transfiere al organizador con transfer_data.destination. La comisión (4% por defecto, configurable) se cobra por encima del precio: el piloto ve una línea de gastos de gestión y el organizador recibe el precio íntegro.

  • Segunda pasarela: el TPV Redsys del organizador

    Quien prefiere cobrar en su propio banco da de alta su TPV virtual (código de comercio, terminal y clave) y el dinero le entra directo, sin comisión de plataforma. La firma HMAC-SHA256 se genera en un dominio puro con node:crypto, sin SDK de terceros en el camino del dinero, y la clave del comercio se guarda cifrada con AES-256-GCM.

  • En Redsys, la firma es la autenticación

    El endpoint de notificación es público, así que la firma es lo único que autentica: se verifica en tiempo constante, se comprueban importe y divisa exactos, la transición a pagado es un UPDATE atómico a prueba de notificaciones simultáneas y solo se responde OK ante decisiones definitivas, para que Redsys reintente si algo falla. Un test de contrato compara nuestra firma byte a byte con la de la librería de referencia.

  • El webhook es el único que confirma un pago

    La URL de éxito no confirma nada. Solo el webhook, con firma verificada sobre el raw body, marca una inscripción como pagada: es idempotente y compara el importe cobrado con el esperado con tolerancia de un céntimo antes de dar nada por bueno.

  • Reembolsos que revierten la comisión

    El organizador o un admin pueden reembolsar una inscripción; el refund se emite con reverse_transfer y refund_application_fee, de modo que se deshace también la transferencia al organizador y la comisión de la plataforma.

  • Auditoría de comisiones reales

    El panel de finanzas expande el balance_transaction de cada cargo para leer lo que Stripe cobra de verdad, no solo la comisión propia. Con esos datos estima por mínimos cuadrados la parte variable y la fija de la tarifa y calcula el punto de equilibrio: por debajo de ese importe, una transacción da pérdidas.

  • Packs que generan códigos de descuento

    Un organizador vende bonos; al confirmarse el pago, el sistema genera automáticamente los códigos canjeables en sus circuitos. El consumo del código es un único UPDATE condicional, a prueba de concurrencia, y ocurre dentro de la transacción de inscripción para que un fallo de aforo no queme el código.

  • Sesión con refresh tokens rotatorios

    Autenticación por cookies HttpOnly con refresh tokens rotatorios hasheados en base de datos, guards por rol (piloto, organizador, admin) y API keys para integraciones.

  • Notificaciones desacopladas por eventos

    Un bus de eventos alimenta a la vez el email (plantillas Handlebars sobre Nodemailer) y las notificaciones in-app, sin que quien emite el evento sepa quién lo escucha. El front refresca el contador de no leídas por polling.

  • Frontend Angular 21 por áreas de rol

    Componentes standalone, carga perezosa por ruta, estado en signals y mapas de circuito con Leaflet, con layouts y guards separados para las áreas de piloto, organizador y administración.