Esta sección describe la plataforma en su totalidad: las funcionalidades implementadas, los flujos de usuario, el sistema de notificaciones y cada módulo que contribuye a una experiencia coherente desde el descubrimiento de productos hasta la post-compra.
Es la funcionalidad estrella. Utiliza Fabric.js 5.3.1 como motor de canvas sobre la imagen del producto.
heic2any para fotos de iPhone).usuarios.diseno_en_progreso como JSON) para continuidad entre dispositivos.Más que una galería estática: el catálogo es completamente dinámico y gestionado desde la BD.
El carrito utiliza un sistema de persistencia dual que evita la pérdida de datos y permite continuidad entre dispositivos.
usuarios.carrito_guardado como JSON) para usuarios logueados.Proceso de compra optimizado con dos métodos de pago y protección anti-fraude en cada transacción.
?redirect=checkout).intl-tel-input (selector de país + formato internacional).Cada pedido sigue un ciclo de vida completo con estados definidos, historial de cambios y notificaciones automáticas.
pedido_historial con timestamp, estado anterior/nuevo y quién lo cambió.Dashboard personal que convierte la tienda en una herramienta para el usuario, no solo un punto de venta.
Todas las comunicaciones automáticas se envían vía PHPMailer con SMTP externo para máxima entregabilidad (ver sección Tecnología).
robots.txt con directivas de rastreo.$meta_title.noindex en páginas sensibles (ej. gracias.php).preconnect hints para recursos externos (CDNs, Google Fonts).user_direcciones).state parameter.file_get_contents).random_bytes(32)).destacado=1 en BD).1. NAVEGACIÓN: El usuario explora `productos.php` con filtros, búsqueda y paginación.
2. DETALLE: Entra en `producto.php` → galería, zoom, guía de tallas, selector de color/talla.
3. PERSONALIZACIÓN: Entra en `personalizar.php`. Se inicializa Fabric.js con el canvas.
4. DISEÑO: Añade texto (20 fuentes, 16 efectos) / imágenes (sube o desde biblioteca) / stickers / filtros.
El progreso se auto-guarda periódicamente vía `guardar_progreso.php` → BD (`diseno_en_progreso`).
5. PRECIO: Se recalcula en tiempo real según producto, talla y extras aplicados.
6. GUARDAR: Al pulsar "Añadir", `guardar_diseno.php` valida el diseño, guarda las imágenes
en el servidor con nombres seguros, recalcula precios en el backend y crea la entrada en el carrito.
7. CARRITO: `carrito.php` muestra items con preview de diseño, desglose de extras, controles de cantidad.
8. CHECKOUT: `checkout.php` → elige dirección (de BD o nueva) → acepta términos y condiciones.
9. PAGO:
a) BIZUM: pedido "Pendiente Pago" → email con instrucciones → WhatsApp preformateado.
b) PAYPAL: verificación completa del pago en servidor → pedido "Pagado" → email confirmación.
Ambos flujos terminan en `gracias.php` con animación de confetti.
10. POST-COMPRA: El admin cambia estados desde `admin_pedidos.php`, disparando emails automáticos
al cliente en cada transición (En Taller, Enviado con tracking, Entregado, Cancelado).
11. PERFIL: El usuario ve historial completo, descarga diseños de su biblioteca, gestiona direcciones.
| Evento | Destinatario | Asunto | Color |
|---|---|---|---|
| Registro | Cliente | Bienvenida con código de descuento 10% (BIENVENIDA10) | Rojo |
| Registro | Admin | Notificación de nuevo cliente | Verde |
| Recuperación contraseña | Cliente | Link de reseteo (válido 1h) | Púrpura |
| Pedido Bizum | Cliente | Confirmación con instrucciones de pago Bizum | Naranja |
| Pedido Bizum | Admin | Alerta de nueva venta Bizum | Naranja |
| Pedido PayPal | Cliente | Pago confirmado | Verde |
| Pedido PayPal | Admin | Nuevo pedido pagado | Verde |
| Estado: En Taller | Cliente | Pedido en producción | Amarillo |
| Estado: Enviado | Cliente | Pedido enviado con link de tracking | Azul |
| Estado: Entregado | Cliente | Pedido entregado + petición de tag en Instagram | Verde |
| Estado: Cancelado | Cliente | Notificación de cancelación | Rojo |
| Estado: Cancelado | Admin | Notificación de cancelación | Rojo |
| Newsletter suscripción | Cliente | Bienvenida al club | Rojo |
| Newsletter suscripción | Admin | Nuevo suscriptor | Verde |
| Newsletter baja | Cliente | Confirmación de baja | Gris |
| Formulario contacto | Admin | Nuevo mensaje de contacto | Rojo |
| Formulario contacto | Cliente | Confirmación de recepción | Rojo |
La seguridad es un pilar fundamental del proyecto. Se implementaron 18 capas de protección para asegurar la integridad de la plataforma, la confidencialidad de los datos de los usuarios y la disponibilidad del servicio. Cada capa aborda una amenaza específica y funciona de forma independiente, creando defensa en profundidad.
| # | Capa de Protección | Implementación | Amenaza Mitigada |
|---|---|---|---|
| 1 | Anti-SQL Injection | Uso exclusivo de Consultas Preparadas con PDO (EMULATE_PREPARES = false). |
Impide que un atacante inyecte comandos SQL maliciosos en formularios para robar, modificar o borrar la base de datos entera, incluyendo datos de clientes y pedidos. |
| 2 | Anti-CSRF | Tokens aleatorios únicos por sesión (random_bytes(32)), validados en cada petición POST. Comparación con hash_equals() en formularios sensibles. |
Evita que una página web maliciosa fuerce al navegador de un usuario logueado a ejecutar acciones no deseadas (cambiar contraseña, cancelar pedido) sin su consentimiento. |
| 3 | Anti-XSS | Sanitización estricta de todas las salidas HTML con wrapper h() (ejecuta htmlspecialchars()). strip_tags() para campos de texto libre. |
Previene la inyección de scripts maliciosos (JavaScript) que podrían robar cookies de sesión de otros usuarios o del administrador. |
| 4 | Hashing de Contraseñas | Algoritmo BCRYPT con password_hash() y password_verify(). Salt automático por cada contraseña. |
Si la BD fuese comprometida, las contraseñas no estarían en texto plano. BCRYPT es computacionalmente costoso, haciendo inviable la fuerza bruta sobre los hashes. |
| 5 | Protección Anti-Fraude en Pagos | Recálculo de precios en el servidor en cada pedido. Verificación S2S (Server-to-Server) de PayPal obteniendo el monto real desde la API. Flag "Revisión Fraudulenta" si hay discrepancia >0.01€. | Bloquea intentos donde un usuario modifica el precio en el HTML de su navegador. El servidor siempre usa su propio cálculo como fuente de verdad. |
| 6 | Rate Limiting | Registro y bloqueo temporal por IP en la tabla login_intentos (5 intentos fallidos = bloqueo 15 min). Rate limiting por sesión en formularios (contacto: 1/5min, registro: 5/hora, recovery: 3/hora, uploads: 15/hora, diseños: 20/hora). |
Mitiga ataques de fuerza bruta (adivinar contraseñas), spam masivo en formularios y abuso de subidas. |
| 7 | Mitigación de Bots | Google reCAPTCHA v2 en registro, contacto, newsletter, recuperación de contraseña. Campos Honeypot invisibles en contacto, newsletter, registro, footer. | Dificulta que bots creen cuentas falsas, inunden formularios o se suscriban masivamente. Los honeypots son campos que solo los bots rellenan, delatando su identidad. |
| 8 | Seguridad de la Sesión | Cookies con flags HttpOnly (no accesible por JS), Secure (solo HTTPS), SameSite=Lax (no cross-site). Modo estricto. Timeout de inactividad de 2 horas. Regeneración de ID en login (session_regenerate_id(true)). Vida útil de 24 horas. |
Endurece la protección contra robo de sesión por XSS, ataques de redirección y secuestro de cookies. |
| 9 | Protección de Archivos Sensibles | Reglas en .htaccess: deniega acceso a .env, .git, .sql, .bak, .log, config.php. Deshabilita listado de directorios (Options -Indexes). Directorio includes/ con denegación total. |
Evita que atacantes accedan a credenciales, configuración o backups a través del navegador web. |
| 10 | Registro de Auditoría | Tabla audit_log que registra: logins exitosos/fallidos, alertas de fraude, cambios de contraseña, registros, envíos de contacto, subidas de recursos. Cada entrada incluye user_id, acción, detalles, IP y timestamp. Auto-limpieza de entradas >30 días. |
Vital para análisis forense post-incidente. Permite identificar qué acciones se realizaron, desde qué IP y cuándo. |
| 11 | Seguridad de Subidas | Whitelist de extensiones (.jpg, .png, .webp). Verificación de MIME type con finfo (no solo extensión). Re-renderizado con GD library (destruye ataques polyglot, elimina metadata EXIF). Permisos 0644. .htaccess en uploads/ bloquea ejecución de scripts. Nombre seguro: prefix + random_bytes(8) + timestamp. |
Previene subida de webshells, scripts PHP maliciosos ocultos en imágenes, y ataques de ejecución de código arbitrario. |
| 12 | Anti-Path Traversal | basename() en TODAS las operaciones con rutas de archivo. Verificación de propiedad (WHERE user_id = ?) antes de eliminar recursos. |
Impide que un usuario acceda o elimine archivos fuera de su directorio autorizado mediante secuencias como ../../../etc/passwd. |
| 13 | Anti-Open Redirect | Whitelist de redirecciones permitidas: solo checkout, perfil, productos, carrito. Nunca redirige a URLs externas arbitrarias. |
Previene ataques de phishing donde un atacante usa la URL del sitio para redirigir a una página maliciosa. |
| 14 | Content Security Policy (CSP) | Header CSP que permite solo dominios conocidos: PayPal, Google (reCAPTCHA, OAuth, Fonts, Maps), CDNs (cdnjs, jsdelivr), Font Awesome, TikTok embeds, WhatsApp links. | Bloquea la ejecución de scripts de orígenes no autorizados, mitigando XSS incluso si un atacante inyecta código HTML. |
| 15 | HTTP Strict Transport Security | Header Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. Redirección 301 de HTTP a HTTPS. |
Fuerza que todas las conexiones sean por HTTPS, previniendo ataques de downgrade y man-in-the-middle. |
| 16 | Anti-DoS en Subidas | Límite de 15MB en payload base64 para diseños. Límite de 5MB para imágenes de biblioteca. Rate limiting: 15 subidas/hora/usuario y 20 guardados de diseño/hora/IP. | Previene ataques de denegación de servicio mediante subida masiva de archivos que saturen el almacenamiento o la memoria del servidor. |
| 17 | Anti-Spam | Honeypot fields en contacto, newsletter, registro y footer. reCAPTCHA v2 en registro, contacto, newsletter, recuperación. Rate limiting por sesión/IP. | Capa múltiple contra spam automatizado. Los honeypots son campos CSS-ocultos que solo los bots rellenan. |
| 18 | Cumplimiento GDPR/LOPD | Cookie consent banner con aceptar/rechazar (localStorage). Política de privacidad completa. Checkbox obligatorio de aceptación en registro. Permissions-Policy que bloquea FLoC, attribution reporting y ad auction. Opción de baja de cuenta. |
Cumple con la normativa europea de protección de datos, otorgando al usuario control sobre sus datos y cookies. |
Las operaciones críticas (creación de pedidos, pagos) utilizan transacciones atómicas con BEGIN/COMMIT/ROLLBACK. Si cualquier paso de la inserción falla (pedido, detalles, pago), la operación completa se revierte, evitando datos inconsistentes como pedidos sin detalles o pagos sin pedido asociado.
| Header | Valor | Propósito |
|---|---|---|
| X-Frame-Options | SAMEORIGIN | Previene clickjacking (el sitio no puede ser embebido en iframes externos) |
| X-Content-Type-Options | nosniff | Evita que el navegador "adivine" el tipo de contenido |
| Referrer-Policy | (configurado) | Controla qué información de referrer se envía |
| Permissions-Policy | browsing-topics=() | Bloquea FLoC y tracking de intereses del navegador |
| Strict-Transport-Security | max-age=31536000 | Fuerza HTTPS por 1 año |
La elección de tecnologías se basó en la robustez, el soporte de la comunidad y la adecuación a los requisitos de un e-commerce a medida. Se optó por un stack tradicional y probado, minimizando dependencias complejas para facilitar el mantenimiento.
PHP 8.x: Elegido por su madurez en el ecosistema web. La versión 8.x ofrece un rendimiento competitivo y características de lenguaje modernas. Permite una arquitectura simple sin la sobrecarga de un framework MVC, adecuada para este proyecto.
MariaDB (MySQL): Motor de base de datos relacional con soporte transaccional completo. Codificación utf8mb4 para compatibilidad total con cualquier carácter (incluidos emojis).
PDO: Capa de acceso a datos con prepared statements reales (EMULATE_PREPARES = false), manejo de excepciones y fetch asociativo.
Vanilla JavaScript: Sin framework pesado (React, Vue) para las páginas principales. Máxima velocidad de carga y simplicidad. JS puro para interacciones de UI, validaciones de formularios y llamadas AJAX.
Fabric.js 5.3.1: Única dependencia frontend "pesada". Motor del editor de diseño canvas. Provee API completa para manipulación de objetos, serialización a JSON, filtros de imagen y exportación a PNG.
CSS Responsive Propio: Grid layouts, mobile-first, skeleton loading, animaciones scroll reveal, efectos de cursor personalizado.
intl-tel-input: Input de teléfono internacional con selector de país y formato automático según región.
Hosting Compartido (Hostinger): Solución coste-efectiva. Panel hPanel para gestión de BD, dominios, Cron Jobs, archivos y certificados SSL.
Apache + .htaccess: URLs limpias (mod_rewrite), redirecciones, reglas de seguridad descentralizadas, configuración de PHP limits (64MB upload, 256MB memory, 300s execution).
SMTP Hostinger: Puerto 465 con SSL para entrega fiable de emails transaccionales vía PHPMailer.
includes/pricing.php (59 líneas): Funciones precioBaseCatalogo() y calcularPrecioPersonalizado(). Lógica de precios: doble cara +10€, nuca +3€, manga izq +3€, manga der +3€, azulejo fijo 9€.
includes/colors.php (56 líneas): Mapa centralizado de 50+ colores con valores hex y aliases para variantes heather/vintage. Usado en carrito, admin y páginas de producto.
includes/header.php (602 líneas): Navbar completa con logo, buscador, categorías, acciones de usuario (login/perfil/carrito), dropdown de admin, links a redes sociales, menú móvil responsive, cursor dot personalizado.
includes/footer.php (197 líneas): Formulario de newsletter (con honeypot + CSRF + reCAPTCHA), links del footer, iconos de redes sociales, cookie consent banner, sistema de toast notifications.
| Servicio / Librería | Uso Principal | Detalles de Implementación |
|---|---|---|
| PayPal SDK | Pasarela de pago | Smart Buttons en frontend para UX fluida. API REST en backend para verificación S2S: obtiene token OAuth, consulta orden en api-m.paypal.com (producción), extrae monto real pagado. Fundamental para anti-fraude. |
| Google reCAPTCHA v2 | Protección anti-bots | Widget en formularios de registro, contacto, newsletter y recuperación. Verificación server-side vía cURL a google.com/recaptcha/api/siteverify. |
| Google OAuth 2.0 | Login social | Flujo: redirect a accounts.google.com → callback en procesar_google.php → intercambio de code por token vía cURL → obtención de perfil desde googleapis.com. Protección CSRF con state parameter. |
| PHPMailer | Envío de emails | Wrapper enviarEmail() en config.php. SMTP Hostinger, puerto 465, SSL. Template HTML branded con barra de gradiente configurable, logo y footer con redes sociales. Superior a mail() en entregabilidad. |
| Fabric.js 5.3.1 | Editor de diseño canvas | CDN: cdnjs.cloudflare.com. Motor del editor interactivo. Maneja: renderizado de canvas, manipulación de objetos (texto, imagen, rect, circle), filtros, serialización JSON, exportación PNG, undo/redo. |
| heic2any | Conversión HEIC→PNG | CDN: cdn.jsdelivr.net. Convierte automáticamente fotos en formato HEIC (formato nativo de iPhone) a PNG visualizable en el navegador. Ejecución client-side. |
| intl-tel-input | Input teléfono internacional | CDN: cdnjs.cloudflare.com. Selector de país con banderas, formato automático del número según la región seleccionada. Usado en checkout y perfil. |
| canvas-confetti | Animación post-compra | CDN: cdn.jsdelivr.net. Efecto de confetti en colores de marca (rojo, verde, negro) en la página de agradecimiento gracias.php. |
| Font Awesome 6.5.1 | Iconografía | CDN: cdnjs.cloudflare.com. Iconos para navegación, acciones de usuario, botones de redes sociales, badges de estado, etc. |
| Google Fonts | Tipografías del editor | 20 fuentes tipográficas cargadas dinámicamente en el editor de diseño para ofrecer variedad creativa al usuario. |
| Google Maps | Ubicación de tienda | Embed estático en index.php y contacto.php. Links de Google Maps generados dinámicamente con la dirección del pedido para el admin. |
| WhatsApp Business | Comunicación directa | Links wa.me/34653851786 en contacto, cross-sell de producto, mensajes preformateados de pedidos Bizum y contacto rápido desde admin. |
| Prueba social | Enlaces en header, footer y email. Petición de tag en email de entrega. | |
| TikTok + Threads | Contenido social | Links en header, footer y página de contacto. |
| Parámetro | Valor | Propósito |
|---|---|---|
upload_max_filesize | 64MB | Permite subir imágenes y videos de alta calidad para productos |
post_max_size | 64MB | Permite envío de formularios con múltiples archivos adjuntos |
memory_limit | 256MB | Necesario para procesamiento de imágenes con GD library y re-renderizado |
max_execution_time | 300s | Tiempo suficiente para procesar pedidos complejos con múltiples diseños |
Se ha diseñado un esquema relacional normalizado de 11 tablas para garantizar la integridad, evitar la redundancia de datos y optimizar las consultas. El motor es MariaDB (MySQL) con codificación utf8mb4.
La tabla usuarios es la entidad central del sistema. Casi todas las demás tablas se relacionan directa o indirectamente con ella.
[usuarios] 1-N [pedidos] 1-N [pedidos_detalle]
| |
+-- 1-N [user_direcciones] +-- 1-N [pedido_historial]
| |
+-- 1-N [biblioteca_recursos] `-- 1-1 [pagos]
|
`-- (login_intentos se relaciona por IP, no por FK)
[productos] N-1 [pedidos_detalle]
[newsletter] (independiente - suscriptores)
[audit_log] (independiente - registro de auditoría)
usuariosEntidad central. Contiene autenticación, perfil y datos persistentes del usuario.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del usuario |
nombre | VARCHAR | Nombre completo |
email | VARCHAR UNIQUE | Email para login (único en el sistema) |
password | VARCHAR | Hash BCRYPT de la contraseña |
rol | ENUM('cliente','admin') | Rol del usuario en el sistema |
telefono | VARCHAR | Número de teléfono con prefijo internacional |
direccion | TEXT | Dirección postal principal |
ciudad | VARCHAR | Ciudad |
cp | VARCHAR(5) | Código postal (validado: 5 dígitos) |
fecha_registro | DATETIME | Fecha de creación de la cuenta |
carrito_guardado | JSON | Carrito persistido en BD para usuarios logueados (sync multi-dispositivo) |
diseno_en_progreso | JSON | Estado serializado del editor Fabric.js (auto-guardado de progreso) |
reset_token | VARCHAR | Token para recuperación de contraseña (se destruye tras uso) |
reset_expires | DATETIME | Fecha de expiración del token de reset (1 hora) |
google_id | VARCHAR | ID de Google para login social OAuth 2.0 |
pedidosCabecera de cada orden de compra. Contiene la información general del pedido.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del pedido |
id_pago | VARCHAR | Referencia externa de pago (PayPal order ID o código Bizum) |
user_id | INT FK → usuarios | Usuario que realizó el pedido |
productos | TEXT | Resumen de productos del pedido |
total | DECIMAL | Monto total del pedido (calculado en servidor) |
direccion_completa | TEXT | Dirección de envío completa |
estado | VARCHAR | Estado actual: Pendiente Pago, Pagado, En Taller, Enviado, Entregado, Cancelado, Revisión Fraudulenta |
fecha | DATETIME | Fecha y hora de creación del pedido |
tracking_url | VARCHAR | URL de seguimiento del envío (añadida por admin al marcar como Enviado) |
payment_id | VARCHAR | ID interno del registro de pago asociado |
pedidos_detalleTabla más crítica para el negocio. Cada fila es un producto dentro de un pedido. Aquí se almacena la personalización.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del detalle |
pedido_id | INT FK → pedidos | Pedido al que pertenece |
producto_id | VARCHAR FK → productos | Producto del catálogo (o "CUSTOM_PROD" para personalizados) |
nombre | VARCHAR | Nombre del producto en el momento de la compra |
talla | VARCHAR | Talla seleccionada (S, M, L, XL, etc.) |
color | VARCHAR | Nombre del color seleccionado |
imagen_custom | VARCHAR | Ruta al PNG del diseño frontal generado |
imagen_espalda | VARCHAR | Ruta al PNG del diseño de espalda |
logos_extras | JSON | Rutas a PNGs de zonas extra (nuca, manga izq, manga der) |
extras_descripcion | TEXT | Descripción de los extras aplicados (doble cara, nuca, etc.) |
notas | TEXT | Notas del cliente sobre el diseño (sanitizadas con strip_tags) |
cantidad | INT | Unidades de este producto+variante |
precio_unitario | DECIMAL | Precio por unidad (calculado en servidor, no confiar en cliente) |
pagosRegistro de cada transacción monetaria. Fundamental para contabilidad y verificación anti-fraude.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del pago |
pedido_id | INT FK → pedidos | Pedido asociado |
paypal_order_id | VARCHAR | ID de la transacción en PayPal (o referencia Bizum) |
payer_id | VARCHAR | ID del pagador en PayPal (para chargeback protection) |
payer_email | VARCHAR | Email del pagador en PayPal |
payer_name | VARCHAR | Nombre del pagador en PayPal |
amount | DECIMAL | Monto real verificado (de PayPal API, no del cliente) |
currency_code | VARCHAR(3) | Moneda (EUR) |
status | VARCHAR | COMPLETED, FAILED, PENDING |
payment_method | VARCHAR | PAYPAL o BIZUM |
captured_at | DATETIME | Fecha de captura del pago |
chargeback | BOOLEAN | Flag de chargeback/disputa |
chargeback_reason | TEXT | Razón del chargeback si aplica |
productosCatálogo completo. Cada producto puede tener galería de imágenes, videos y ser destacado.
| Columna | Tipo | Descripción |
|---|---|---|
id | VARCHAR PK | Identificador único del producto (ej: "prod_a1b2c3d4_1710000000") |
nombre | VARCHAR | Nombre del producto |
descripcion | TEXT | Descripción detallada |
precio | DECIMAL | Precio base del producto |
imagen_url | VARCHAR | Ruta a la imagen principal |
imagenes_galeria | JSON | Array de rutas a imágenes adicionales |
video_delante | VARCHAR | Ruta al video frontal del producto |
video_detras | VARCHAR | Ruta al video trasero |
video_como_se_hace | VARCHAR | Ruta al video del proceso de fabricación |
categoria | VARCHAR | Categoría: camisetas, sudaderas, tazas, cuadros |
destacado | BOOLEAN | Si aparece en la sección de destacados del index |
destacado_at | DATETIME | Fecha en que fue marcado como destacado |
biblioteca_recursosImágenes subidas por los usuarios para usar en el editor de diseño.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del recurso |
user_id | INT FK → usuarios | Propietario del recurso |
ruta_imagen | VARCHAR | Ruta al archivo de imagen en el servidor |
fecha | DATETIME | Fecha de subida |
user_direccionesLibreta de direcciones del usuario. Permite múltiples direcciones con una predeterminada.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único de la dirección |
user_id | INT FK → usuarios | Propietario de la dirección |
alias | VARCHAR | Nombre identificador ("Casa", "Oficina") |
nombre | VARCHAR | Nombre del destinatario |
direccion | TEXT | Línea de dirección |
ciudad | VARCHAR | Ciudad |
cp | VARCHAR(5) | Código postal (5 dígitos) |
telefono | VARCHAR | Teléfono de contacto para envío |
predeterminada | BOOLEAN | Si es la dirección principal del usuario |
pedido_historialAuditoría de cambios de estado. Permite reconstruir el timeline completo de cualquier pedido.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del registro |
pedido_id | INT FK → pedidos | Pedido afectado |
estado_anterior | VARCHAR | Estado antes del cambio |
estado_nuevo | VARCHAR | Estado después del cambio |
cambiado_por | INT | ID del admin que realizó el cambio |
fecha | DATETIME | Fecha y hora del cambio |
audit_log"Caja negra" del sistema. Registra eventos de seguridad para análisis forense post-incidente.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único del evento |
user_id | INT | Usuario involucrado (NULL si no autenticado) |
action | VARCHAR | Tipo de evento: login_success, login_fail, csrf_fail, registration, password_change, contact_submit, fraud_alert, upload, etc. |
details | TEXT | Información adicional del evento |
ip | VARCHAR | Dirección IP del cliente |
timestamp | DATETIME | Fecha y hora del evento |
Auto-limpieza: El panel de admin borra automáticamente entradas mayores a 30 días en cada carga.
login_intentosProtección anti-fuerza bruta. Registra intentos fallidos de login por IP.
| Columna | Tipo | Descripción |
|---|---|---|
ip | VARCHAR UNIQUE PK | Dirección IP del cliente |
intentos | INT | Número de intentos fallidos consecutivos |
ultima_falla | DATETIME | Timestamp del último intento fallido |
Lógica: Si intentos >= 5 y ultima_falla hace menos de 15 minutos, se bloquea el acceso. Se resetea tras un login exitoso.
newsletterSuscriptores del boletín. Fuente para envíos masivos del admin.
| Columna | Tipo | Descripción |
|---|---|---|
id | INT PK AUTO_INCREMENT | Identificador único |
email | VARCHAR UNIQUE | Email del suscriptor (único) |
fecha_registro | DATETIME | Fecha de suscripción |
El proyecto adopta un enfoque clásico de PHP sin frameworks. La separación es: presentación (HTML+PHP), lógica de negocio (scripts procesadores) y configuración (includes/). Más de 50 archivos PHP y 15,000+ líneas de código.
/
├── includes/ # Ficheros de inclusión global
│ ├── config.php # 510 líneas. El cerebro: BD, sesiones, CSRF, headers
│ │ # seguridad, funciones globales (h(), auditLog(),
│ │ # enviarEmail(), validarRecaptcha(), getClientIP(),
│ │ # esAdmin(), formatPrecio(), esMovil())
│ ├── header.php # 602 líneas. Navbar completa, buscador, categorías,
│ │ # acciones de usuario, admin dropdown, redes sociales,
│ │ # menú móvil, cursor dot personalizado
│ ├── footer.php # 197 líneas. Newsletter (honeypot+CSRF+reCAPTCHA),
│ │ # links footer, iconos sociales, cookie consent banner,
│ │ # sistema de toast notifications
│ ├── pricing.php # 59 líneas. precioBaseCatalogo(), calcularPrecioPersonalizado()
│ ├── colors.php # 56 líneas. Mapa de 50+ colores con hex y aliases
│ ├── .env # CRÍTICO. Credenciales: BD, PayPal, reCAPTCHA, SMTP, OAuth
│ ├── .htaccess # Denegación total de acceso web al directorio
│ └── PHPMailer/ # Librería externa para envío SMTP
│ ├── PHPMailer.php
│ ├── SMTP.php
│ ├── Exception.php
│ └── (archivos auxiliares)
│
├── uploads/ # Archivos subidos por usuarios
│ ├── .htaccess # Solo permite imágenes, bloquea ejecución de scripts
│ ├── custom/ # Diseños personalizados (PNGs generados por el editor)
│ ├── pedidos/ # Imágenes de pedidos procesados
│ └── recursos/ # Imágenes de la biblioteca personal de usuarios
│
├── admin/ # Scripts internos del panel de administración
│ ├── cambiar_estado.php # 170 líneas. Cambio de estado con emails automáticos,
│ │ # historial, validación de tracking URL
│ └── ver_pedido.php # 299 líneas. Detalle completo de pedido para admin
│
├── procesar_login.php # 200 líneas. Auth engine + rate limiting + cart fusion
├── procesar_registro.php # 166 líneas. Validación + BCRYPT + welcome email + auto-login
├── procesar_recuperar.php # 129 líneas. Token seguro + email recovery + rate limiting
├── procesar_nueva_clave.php # 75 líneas. Reset contraseña con destrucción de token
├── procesar_google.php # 195 líneas. OAuth 2.0 handler + auto-create + cart fusion
├── procesar_pedido.php # 404 líneas. Bizum: anti-fraude + transacción + emails
├── procesar_pago.php # 496 líneas. PayPal S2S: verificación real + anti-fraude + emails
├── procesar_perfil.php # 236 líneas. CRUD perfil/direcciones/recursos con ownership
├── procesar_newsletter.php # 141 líneas. Suscripción/baja con honeypot + reCAPTCHA
├── carrito_accion.php # 154 líneas. Añadir al carrito con recálculo server-side
├── carrito_modificar.php # 86 líneas. Modificar cantidades con sync atómico
├── guardar_diseno.php # 339 líneas. Guardar diseño: validación, GD, cleanup
├── guardar_progreso.php # 50 líneas. Auto-save JSON del editor a BD
├── subir_recurso.php # 191 líneas. Upload seguro: MIME + GD re-render + cleanup
├── borrar_recurso.php # 121 líneas. Eliminar con anti-path-traversal + ownership
├── cancelar_pedido.php # 81 líneas. Cancelación con emails a cliente y admin
├── save-products.php # 165 líneas. Sync catálogo con protección anti-borrado masivo
├── upload.php # 120 líneas. Upload admin con whitelist + MIME verification
├── enviar_masivo.php # 105 líneas. Envío masivo para admin (clientes/newsletter)
├── obtener_productos.php # 15 líneas. API JSON: un producto base por categoría
├── obtener_recursos.php # 48 líneas. API JSON: últimos 20 recursos del usuario
├── logout.php # 39 líneas. Logout con persistencia de carrito en BD
├── baja.php # 124 líneas. Confirmación de baja de newsletter
│
├── index.php # 583 líneas. Landing: hero, categorías, destacados, mapa, reseñas
├── productos.php # 967 líneas. Catálogo: filtros, búsqueda, paginación, sorting
├── producto.php # 1100+ líneas. Detalle: galería, zoom, guía tallas, videos
├── personalizar.php # 7878 líneas. Editor Fabric.js: canvas multi-zona, texto,
│ # stickers, filtros, plantillas, undo/redo, auto-save
├── carrito.php # 577 líneas. Carrito: preview, extras breakdown, shipping bar
├── checkout.php # 587 líneas. Checkout: direcciones, PayPal buttons, Bizum
├── gracias.php # 198 líneas. Post-compra: confetti, timeline, WhatsApp CTA
├── perfil.php # 700+ líneas. Dashboard: pedidos, biblioteca, direcciones, seguridad
├── mi_pedido_detalle.php # 272 líneas. Detalle de pedido para el cliente
├── ver_detalles.php # 585 líneas. Detalle admin con centro de producción
├── login.php # 328 líneas. Login: rate limiting, Google OAuth, CSRF
├── registro.php # 307 líneas. Registro: strength meter, privacidad, reCAPTCHA
├── recuperar.php # 68 líneas. Petición de recuperación de contraseña
├── restablecer.php # 181 líneas. Reset de contraseña con validación de token
├── contacto.php # 973 líneas. Contacto premium: mapa, redes, formulario, reseñas
├── faq.php # 183 líneas. FAQ con acordeón por categorías
├── admin_pedidos.php # 1434 líneas. Dashboard: cleanup automático, stats, filtros, cambio estado
├── admin_productos.php # 2021 líneas. CRUD: upload imagen/video, galería, destacado
├── admin_pagos.php # 412 líneas. Auditoría: stats, filtros, chargebacks
├── lista_clientes_secreta.php # 557 líneas. Base de clientes con estadísticas
├── sitemap.php # 145 líneas. Sitemap visual para visitantes
├── sitemap_xml.php # 94 líneas. Sitemap XML dinámico (consulta BD)
├── aviso-legal.php # Legal: empresa (CAMIGLOBO SL, CIF B67479100), LSSI
├── politica-privacidad.php # Legal: GDPR/LOPD
├── terminos-condiciones.php # Legal: condiciones de venta
├── politica-envios.php # Legal: envíos (gratis >45€, 4.95€ resto)
├── politica-reembolso.php # Legal: devoluciones (personalizados: sin devolución)
│
├── .htaccess # 102 líneas. URLs limpias, HTTPS, HSTS, CSP, seguridad,
│ # caching, protección de archivos, Shopify redirects
├── robots.txt # Directivas de rastreo para buscadores
└── .env # Todas las credenciales (protegido por .htaccess)
| Patrón | Implementación | Propósito |
|---|---|---|
| Scripts procesadores | procesar_*.php, carrito_*.php, guardar_*.php |
Scripts "sin cabeza" que no producen HTML. Reciben datos del formulario, los procesan (validar, BD, emails) y redirigen. Separación clave para seguridad y organización. |
| Inclusión global | config.php incluido en cada página |
Configuración centralizada: BD, sesiones, funciones de seguridad. Evita duplicación y asegura consistencia. |
| Sync atómico de carrito | Lectura BD → merge sesión → escritura BD | Previene conflictos en multi-tab/multi-device. La BD es la fuente de verdad. |
| Precios server-side | Recálculo en cada operación de pedido/pago | Nunca confiar en el precio enviado por el cliente. El servidor consulta BD y calcula. |
| Transacciones atómicas | BEGIN/COMMIT/ROLLBACK en pedidos y pagos | Si cualquier paso falla, se revierte todo. Evita datos inconsistentes. |
| Cleanup periódico | En cada carga de admin_pedidos.php |
Limpia audit_log >30 días, biblioteca_recursos >60 días, archivos huérfanos >15 días. |
Vista general del proyecto Camiglobo Barcelona: una plataforma e-commerce completa de productos textiles personalizados con editor de diseño interactivo, doble pasarela de pago y panel de administración.
| Módulo | Funcionalidades | Archivos Clave |
|---|---|---|
| Editor de Diseño | Canvas Fabric.js, 5 zonas (frontal/espalda/nuca/mangas), 20 fuentes, 16 efectos de texto, stickers, filtros, plantillas, undo/redo, auto-guardado, biblioteca personal | personalizar.php, guardar_diseno.php, guardar_progreso.php |
| Catálogo | Productos dinámicos desde BD, filtros por categoría/búsqueda/precio, sorting, paginación, galería con zoom, guía de tallas, selector de color/talla, videos, productos relacionados | productos.php, producto.php, obtener_productos.php |
| Carrito | Persistencia dual (sesión+BD), sync multi-tab, fusionado guest→logueado, desglose de extras, preview de diseño, barra de envío gratuito | carrito.php, carrito_accion.php, carrito_modificar.php |
| Checkout & Pagos | Doble pasarela (PayPal Smart Buttons + Bizum), libreta de direcciones, anti-fraude server-side, verificación S2S PayPal, transacciones atómicas | checkout.php, procesar_pedido.php, procesar_pago.php |
| Gestión Pedidos | 6 estados (Pend. Pago→Pagado→En Taller→Enviado→Entregado/Cancelado), historial de cambios, tracking URL, cancelación por cliente, confetti post-compra | gracias.php, mi_pedido_detalle.php, cancelar_pedido.php |
| Autenticación | Login con rate limiting, registro con strength meter + reCAPTCHA, Google OAuth 2.0, recuperación segura con token (1h), auto-login post-registro, cart fusion | login.php, registro.php, procesar_google.php, recuperar.php |
| Perfil Usuario | 4 pestañas: pedidos, biblioteca de diseños, direcciones, seguridad. Cambio de contraseña con reCAPTCHA, CRUD direcciones con predeterminada | perfil.php, procesar_perfil.php |
| Emails | 17 emails transaccionales automáticos (registro, pedidos, estados, newsletter, contacto). PHPMailer + SMTP. Template branded con colores por tipo | config.php (función enviarEmail()) |
| Admin | Pedidos (filtros, cambio estado, WhatsApp), productos (CRUD + galería + videos), pagos (auditoría + chargebacks), clientes (stats), envío masivo, cleanup automático | admin_pedidos.php, admin_productos.php, admin_pagos.php |
| Contenido | Newsletter, contacto premium, FAQ, SEO (sitemap XML dinámico, canonical, OG tags), 5 páginas legales (GDPR/LSSI), cookie consent banner | contacto.php, faq.php, sitemap_xml.php, legales |
Explorar catálogo → Ver detalle → Personalizar (Fabric.js) → Añadir al carrito
→ Checkout (dirección + términos) → Pago (PayPal o Bizum) → Confirmación (confetti)
→ Admin gestiona (En Taller → Enviado con tracking → Entregado)
→ El usuario ve todo desde su perfil con historial y biblioteca de diseños
| Tabla | Propósito | Registros Típicos |
|---|---|---|
usuarios | Cuentas de cliente/admin con carrito y diseño persistidos | Clientes registrados |
productos | Catálogo con galería, videos y precios | Productos a la venta |
pedidos | Cabecera de cada orden (estado, total, dirección) | Un registro por pedido |
pedidos_detalle | Productos dentro de cada pedido + diseños custom | Varios por pedido |
pagos | Transacciones PayPal/Bizum verificadas | Uno por pedido |
user_direcciones | Libreta de direcciones del usuario | Varias por usuario |
biblioteca_recursos | Imágenes subidas por el usuario para el editor | Varias por usuario |
pedido_historial | Auditoría de cambios de estado de pedidos | Varios por pedido |
audit_log | Registro de eventos de seguridad (auto-limpia >30 días) | Creciente, se purga |
login_intentos | Protección anti-fuerza bruta por IP | Transitorio |
newsletter | Suscriptores del boletín | Emails suscritos |