Auditoría
Tienda Streaming
Análisis completo de productos-dropi.php (1,151 líneas) y cuentas-streaming.php (583 líneas).
Evaluación de seguridad, rendimiento, arquitectura de checkout y SEO.
Resumen Ejecutivo
La tienda de streaming es principalmente un escaparate de productos con checkout vía WhatsApp (sin pasarela de pago integrada).
Se detecta un buen uso de htmlspecialchars() para escape de salida y PDO con prepared statements cuando la base de datos está disponible.
Sin embargo, el flujo de compra completo depende de un redirect a WhatsApp, sin carrito, sin rastreo de órdenes y sin confirmación de pago automatizada.
Hallazgos Críticos 4 CRÍTICOS
El checkout es un redirect a wa.me. No existe Order ID, no hay confirmación de pago, no hay reducción de inventario al comprar.
Esto hace imposible el seguimiento de ingresos, permite duplicación de órdenes y no ofrece protección contra fraude.
Los productos se obtienen de la API externa de Dropi sin fallback de cache local. Si la API está caída, el catálogo completo aparece vacío para el usuario. No hay lógica de reintento, no hay cache local y no hay mensaje de error amigable.
Los parámetros GET son tomados directamente: $selectedCategory = trim($_GET['cat']) y $search = trim($_GET['q']).
Aunque GET es menos riesgoso que POST, los parámetros son reflejados en links href sin sanitización completa en todos los contextos,
abriendo posibles vectores de XSS reflejado.
El mapeo de campos sell_price y provider_price hace suposiciones con 5 nombres de campo alternativos.
No hay test unitario que garantice la precisión del precio. Un cambio en la API de Dropi podría mostrar precios incorrectos silenciosamente.
Hallazgos Medios 5 MEDIOS
Query SELECT * FROM dropshipping_products WHERE is_active = 1 sin LIMIT.
Con catálogos grandes, carga todos los registros en memoria en cada request.
Riesgo de OOM y timeouts con >500 productos.
cuentas-streaming.php muestra cuentas disponibles públicamente sin login gate.
Cualquier visitante puede ver el inventario de cuentas, precios internos y disponibilidad.
Requiere autenticación mínima.
Los productos favoritos se almacenan únicamente en localStorage. Se pierden al limpiar el navegador, cambiar de dispositivo o usar modo incógnito.
No hay sincronización server-side, lo que afecta la experiencia de usuario recurrente.
Las imágenes de productos provienen de CDN externo sin loading="lazy" en todos los <img> y sin srcset para responsive.
Esto impacta el LCP (Largest Contentful Paint) en móvil con catálogos grandes.
No se generan <meta name="description"> dinámicas por producto ni <script type="application/ld+json"> con schema Product.
Esto excluye los productos del rich snippet de Google Shopping y reduce el CTR orgánico significativamente.
Para un e-commerce, la ausencia de structured data es un costo directo de adquisición.
Fortalezas 4 POSITIVOS
htmlspecialchars() aplicado a toda la salida de usuario (línea 11 y a lo largo del archivo).
Protección efectiva contra XSS persistente y reflejado en el 95% de contextos de output.
Cuando la base de datos está disponible, se usa PDO con prepared statements correctamente. Protección efectiva contra inyección SQL en las consultas de catálogo y filtros de búsqueda.
Los links wa.me incluyen mensaje pre-formateado con nombre del producto, precio y categoría.
Reduce fricción en el proceso de consulta y mejora la tasa de conversación inicial con el vendedor.
Layout mobile-first con Tailwind CSS correctamente configurado. Las tarjetas de producto se adaptan bien a distintos breakpoints. La experiencia móvil es funcional y estéticamente coherente.
Recomendaciones 6 ACCIONES
Integrar MercadoPago o Wompi para Colombia. Agrega tracking de órdenes, confirmación de pago automática y certeza de ingresos.
Implementar tabla orders con estado, monto, y referencia de transacción. Reducir dependencia total de WhatsApp para cierre.
Agregar cache con TTL 30 minutos para los datos de Dropi. Si Redis no está disponible, usar cache en archivo (/tmp/dropi_cache.json).
Implementar graceful degradation: mostrar últimos productos conocidos con banner "actualizando catálogo…" en lugar de página vacía.
Agregar LIMIT 24 OFFSET ? a la query principal del catálogo. Implementar UI de paginación o infinite scroll.
Objetivo: máximo 24 productos por página para controlar memoria y tiempos de respuesta.
Agregar loading="lazy" a todos los <img> de productos y decoding="async".
Si el CDN de Dropi soporta parámetros de redimensionado, generar srcset para 400w, 800w y 1200w.
Mejora estimada en LCP: 40–60% en móvil.
Agregar <script type="application/ld+json"> con schema Product incluyendo
name, description, price, image y offers.
Habilita rich snippets en Google, mejora CTR orgánico y es requisito para Google Shopping gratuito.
Migrar favoritos de localStorage a cookie firmada o tabla DB user_favorites con identificador de sesión.
Permite que los favoritos persistan entre dispositivos y sesiones, mejorando la retención de usuarios recurrentes.
Plan de Acción Priorizado
urlencode() consistente en todos los parámetros reflejados en hrefloading="lazy" + decoding="async" en todas las imágenesorders y notificaciones IPNcuentas-streaming.php