--- id: "US-AUTH-009" title: "Autenticacion con WhatsApp" type: "User Story" status: "To Do" priority: "Media" epic: "OQI-001" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-AUTH-009: Autenticación con WhatsApp **Version:** 1.0.0 **Fecha:** 2025-12-05 **Estado:** Pendiente **Story Points:** 3 **Prioridad:** P2 (Media) **Épica:** [OQI-001](../_MAP.md) --- ## Historia de Usuario **Como** usuario de Trading Platform **Quiero** poder registrarme e iniciar sesión recibiendo el código por WhatsApp **Para** usar una aplicación que ya tengo instalada y me resulta más familiar que SMS --- ## Criterios de Aceptación ### AC-001: Opción de WhatsApp **Dado** que estoy en la pantalla de ingreso de teléfono **Cuando** ingreso mi número **Entonces** debería ver dos opciones: - "Enviar por SMS" - "Enviar por WhatsApp" **Y** debería poder seleccionar mi preferencia ### AC-002: Validación de WhatsApp **Dado** que seleccioné la opción de WhatsApp **Cuando** hago click en "Enviar código" **Entonces** el sistema debería: 1. Verificar que el número tiene WhatsApp activo 2. Si no tiene WhatsApp, mostrar mensaje y ofrecer SMS 3. Si tiene WhatsApp, enviar el código ### AC-003: Mensaje de WhatsApp **Dado** que solicité código por WhatsApp **Cuando** recibo el mensaje **Entonces** debería tener el formato: ``` ¡Hola! 👋 Tu código de verificación de Trading Platform es: *123456* Válido por 10 minutos. No compartas este código con nadie. Trading Platform - Inversiones Inteligentes ``` ### AC-004: Código recibido **Dado** que recibí el código por WhatsApp **Cuando** vuelvo a la app e ingreso el código **Entonces** debería funcionar igual que con SMS **Y** completar el registro o login ### AC-005: WhatsApp no disponible **Dado** que mi número no tiene WhatsApp activo **Cuando** intento usar la opción de WhatsApp **Entonces** debería ver un mensaje: - "Este número no tiene WhatsApp activo" **Y** debería ver botón "Enviar por SMS" ### AC-006: Fallback a SMS **Dado** que seleccioné WhatsApp pero el envío falló **Cuando** ocurre un error en WhatsApp **Entonces** debería: 1. Ver mensaje "No pudimos enviar por WhatsApp" 2. Ver opción "Enviar por SMS" 3. Poder continuar con SMS sin reingresar el número ### AC-007: Preferencia guardada **Dado** que usé WhatsApp exitosamente **Cuando** vuelvo a hacer login **Entonces** WhatsApp debería ser la opción preseleccionada ### AC-008: Rate limiting compartido **Dado** que solicité códigos por SMS y WhatsApp **Cuando** sumo los intentos **Entonces** debería contar ambos hacia el límite de 5 por hora --- ## Mockup ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ 🌟 Ingresa con tu número de teléfono │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Número de teléfono │ │ │ │ ┌────────┐ ┌──────────────────────────────────────┐ │ │ │ │ │ 🇺🇸 +1 ▾│ │ (555) 123-4567 │ │ │ │ │ └────────┘ └──────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ¿Cómo quieres recibir el código? │ │ │ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │ │ 📱 SMS │ │ 💬 WhatsApp │ │ │ └─────────────────────────┘ └─────────────────────────┘ │ │ (Recomendado - más rápido) │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Enviar código │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ Mensaje de WhatsApp: ┌─────────────────────────────────────────────────────────────┐ │ WhatsApp 🔍 ⋮ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ◀ Trading Platform ✓✓ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ ¡Hola! 👋 │ │ │ │ │ │ │ │ Tu código de verificación de Trading Platform es: │ │ │ │ │ │ │ │ *123456* │ │ │ │ │ │ │ │ Válido por 10 minutos. │ │ │ │ No compartas este código con nadie. │ │ │ │ │ │ │ │ Trading Platform - Inversiones Inteligentes │ │ │ └──────────────────────────────────────────────────────┘ │ │ 15:42 │ │ │ └─────────────────────────────────────────────────────────────┘ Pantalla si WhatsApp no disponible: ┌─────────────────────────────────────────────────────────────┐ │ │ │ ⚠️ WhatsApp no disponible │ │ │ │ Este número no tiene WhatsApp activo. │ │ ¿Quieres recibir el código por SMS? │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Enviar por SMS │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ← Cambiar número │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Tareas Técnicas ### Database (DB) - [ ] Agregar campo a tabla `users`: ```sql ALTER TABLE users ADD COLUMN preferred_auth_channel VARCHAR(20) DEFAULT 'sms'; -- Valores: 'sms', 'whatsapp' ``` - [ ] Agregar campo a `phone_verification_codes`: ```sql ALTER TABLE phone_verification_codes ADD COLUMN channel VARCHAR(20) DEFAULT 'sms'; -- Valores: 'sms', 'whatsapp' ``` ### Backend (BE) - [ ] Configurar WhatsApp Business API o Twilio WhatsApp - [ ] Endpoint `POST /api/v1/auth/phone/send-code` (modificar) - Agregar parámetro `channel: 'sms' | 'whatsapp'` - Verificar si número tiene WhatsApp (usando Twilio Lookup) - Enviar por canal seleccionado - [ ] Service `WhatsAppService` - `hasWhatsApp(phoneNumber)` - `sendVerificationCode(phoneNumber, code)` - `formatMessage(code)` - [ ] Librería: `twilio` SDK (WhatsApp support) - [ ] Fallback automático a SMS si WhatsApp falla - [ ] Tests unitarios (8 casos) - [ ] Tests de integración con mock ### Frontend (FE) - [ ] Modificar `PhoneAuth.tsx` - Agregar selector de canal (SMS/WhatsApp) - Mostrar logo de WhatsApp - Manejo de error si WhatsApp no disponible - [ ] Recordar preferencia del usuario - [ ] Tests con React Testing Library ### Testing (QA) - [ ] E2E: Registro con WhatsApp - [ ] E2E: WhatsApp no disponible (fallback a SMS) - [ ] E2E: Error en WhatsApp (fallback a SMS) - [ ] E2E: Preferencia guardada - [ ] Test de integración con Twilio WhatsApp Sandbox - [ ] Mock de Twilio Lookup API --- ## Dependencias - **Bloqueantes:** - US-AUTH-008: Infraestructura de SMS ya implementada - Twilio WhatsApp habilitado (requiere aprobación de Meta) - WhatsApp Business Profile aprobado - **Alternativa:** - Usar Twilio WhatsApp Sandbox para desarrollo - Solicitar WhatsApp Business API access para producción --- ## Definition of Ready (DoR) - [ ] Twilio WhatsApp configurado - [ ] WhatsApp Business Profile creado - [ ] Message templates aprobados por Meta (para producción) - [ ] Mockups aprobados - [ ] API contract definido --- ## Definition of Done (DoD) - [ ] Código implementado y revisado - [ ] Tests unitarios con 80%+ cobertura - [ ] Tests de integración pasando - [ ] Tests E2E implementados - [ ] Twilio WhatsApp configurado en todos los ambientes - [ ] Fallback a SMS funcional - [ ] Documentación actualizada - [ ] Logs y monitoring - [ ] QA aprobado en staging - [ ] Deploy a producción exitoso --- ## Notas Técnicas ### WhatsApp vs SMS **Ventajas de WhatsApp:** - Más familiar para usuarios - Gratis para el usuario - Mayor tasa de apertura - Confirmación de entrega y lectura - Soporte para rich media **Desventajas:** - Requiere número verificado de WhatsApp Business - Proceso de aprobación de Meta - Templates deben ser pre-aprobados (producción) - No todos tienen WhatsApp ### Twilio WhatsApp Integration ```typescript import twilio from 'twilio'; const client = twilio(accountSid, authToken); // Verificar si número tiene WhatsApp const lookup = await client.lookups.v2 .phoneNumbers(phoneNumber) .fetch({ fields: 'line_type_intelligence' }); const hasWhatsApp = lookup.lineTypeIntelligence?.type === 'whatsapp'; // Enviar mensaje por WhatsApp await client.messages.create({ body: `¡Hola! 👋\n\nTu código de verificación de Trading Platform es:\n\n*${code}*\n\nVálido por 10 minutos.\nNo compartas este código con nadie.\n\nTrading Platform - Inversiones Inteligentes`, from: 'whatsapp:+14155238886', // Twilio WhatsApp number to: `whatsapp:${phoneNumber}` }); ``` ### Environment Variables ```env TWILIO_WHATSAPP_NUMBER=whatsapp:+14155238886 TWILIO_WHATSAPP_ENABLED=true ``` ### Development: WhatsApp Sandbox Para desarrollo, Twilio ofrece un Sandbox que no requiere aprobación: 1. Usuario debe enviar un mensaje join code a Twilio Sandbox 2. Luego puede recibir mensajes 3. Útil para testing pero no para producción ### Production: WhatsApp Business API Para producción: 1. Solicitar WhatsApp Business API access 2. Crear WhatsApp Business Profile 3. Verificar número de teléfono 4. Crear y aprobar message templates 5. Esperar aprobación de Meta (puede tardar días) ### Message Templates (Producción) En producción, WhatsApp requiere templates pre-aprobados: ``` Template Name: verification_code Category: AUTHENTICATION Language: es Body: ¡Hola! 👋 Tu código de verificación de Trading Platform es: *{{1}}* Válido por 10 minutos. No compartas este código con nadie. Trading Platform - Inversiones Inteligentes ``` ### Fallback Strategy ```typescript async function sendVerificationCode(phone, code, channel) { try { if (channel === 'whatsapp') { // Verificar si tiene WhatsApp const hasWhatsApp = await whatsappService.hasWhatsApp(phone); if (!hasWhatsApp) { // Automáticamente usar SMS return await smsService.sendCode(phone, code); } // Intentar enviar por WhatsApp return await whatsappService.sendCode(phone, code); } else { // Usar SMS return await smsService.sendCode(phone, code); } } catch (error) { // Si WhatsApp falla, fallback a SMS logger.warn('WhatsApp failed, falling back to SMS', { phone, error }); return await smsService.sendCode(phone, code); } } ``` ### Cost Comparison - SMS: ~$0.0075 USD por mensaje - WhatsApp: ~$0.005 USD por mensaje (más barato) - WhatsApp también tiene mejor deliverability ### Security Considerations - Mismo código puede usarse para SMS o WhatsApp - Rate limiting compartido entre canales - Validar que el canal solicitado sea válido - Logs separados por canal para auditoría - Fallback automático mantiene seguridad --- ## Requerimientos Relacionados - [RF-AUTH-004: Autenticación por Teléfono](../requerimientos/RF-AUTH-004-phone.md) ## Especificaciones Relacionadas - [ET-AUTH-002: JWT Tokens](../especificaciones/ET-AUTH-002-jwt.md) - [ET-AUTH-005: Phone Authentication](../especificaciones/ET-AUTH-005-phone.md)