Screen · Recuperar contraseña
Recuperar contraseña — flujo de 3 pasos
Entrada desde el link ¿Olvidaste tu clave? del login (A2). Tres pasos: solicitud (celular) → verificación (OTP 6 dígitos, reuso de components-otp-input) → nueva clave (con confirmación y requisitos visibles). El copy de solicitud es anti-enumeración: nunca confirma que la cuenta exista. La pantalla de éxito comunica la consecuencia de seguridad del vault: se cierran las otras sesiones del titular — tono informativo, no punitivo.
/password-recovery
3 pasos · stepper
anti-enumeración
cierre de otras sesiones post-reset
forgot / reset-password
Layout anotado · paso 1 · solicitud
Mismo input de celular que el login (+57 readonly, 10 dígitos). El copy promete el condicional, no el hecho: "si existe una cuenta…" — así la respuesta es idéntica exista o no.
back + stepper 1/3
copy condicional · anti-enum
input celular · reuso A2
CTA · habilita con 10 dígitos
9:41
Recupera tu clave
Si existe una cuenta con este celular, te enviaremos un código de verificación por SMS.
Celular
🇨🇴 +57
312 456 7890
Enviar código
Composición
- Stepper 1/3Indicador mono discreto en el app bar (reuso de
components-stepper compacto). El back del paso 1 vuelve al login.
- Copy condicional"Si existe una cuenta con este celular…" — la pantalla siguiente es la misma exista o no la cuenta. Nunca "no encontramos este número".
- Input celular · reusoMismo componente de A2: prefijo
+57 readonly, 10 dígitos que empiezan por 3, teclado numérico, CTA disabled hasta válido.
- Tras enviarAvanza siempre al paso 2 con el mismo copy — si la cuenta no existe, el SMS simplemente no llega. Rate limit por IP y por número en backend.
Pasos 2 y 3 · OTP y nueva clave
El OTP reusa components-otp-input tal cual (6 cajas, auto-avance, reenvío con countdown). La nueva clave muestra sus requisitos siempre visibles, validados en vivo.
Paso 2 · verificación OTP
9:41
Ingresa el código
Enviamos un código de 6 dígitos por SMS al +57 ******7890.
482
Verificar
Reenviar código en 0:42
Paso 3 · nueva clave
9:41
Crea una clave nueva
La usarás para entrar a MiCapi. Que no sea la de otro servicio.
Mínimo 8 caracteres
Una mayúscula y una minúscula
Un número
No contiene tu celular
Guardar clave
Éxito · con aviso de seguridad
9:41
Clave actualizada
Ya puedes iniciar sesión con tu clave nueva.
Por tu seguridad, cerramos tus otras sesiones al cambiar la clave. Todo lo demás funciona normal: puedes comprar, vender y recibir.
Iniciar sesión
Regla del vault — aviso de consecuencia de seguridad. El aviso es obligatorio en la pantalla de éxito y se repite en una notificación (centro A-previo). Tono informativo, no punitivo: se explica como protección ("por tu seguridad") y se acota el alcance. Corregido a mano el 2026-08-11 (decisión de William) — mantener en el próximo re-export de Claude Design: el aviso decía «los retiros quedan pausados durante 48 horas», una pausa que no existía en ninguna capa (fichas BE-AUTH-0101 / APP-AUTH-0201) — afirmar en pantalla un control inexistente es información engañosa (Ley 1480 arts. 23-24). No se construyó porque la operación que pausaba (retiro on-chain, F5) no existe, y porque en el riel bancario el control correcto es la titularidad verificada del destino (BE-BANKING-0104), no una pausa. El candado sí está construido en el backend (columna withdrawals_locked_until, sello atómico en el reset, ventana de 48 h) con un centinela que pone el gate en rojo si alguien rutea el retiro sin imponerlo: el aviso de 48 h se restituye junto con F5, y ahí vuelve el contador con su fecha de fin.
Estados · error de OTP y offline
OTP incorrecto
9:41
Ingresa el código
Enviamos un código de 6 dígitos por SMS al +57 ******7890.
482917
Código incorrecto. Te quedan 2 intentos.
Offline · paso 1
9:41
Sin conexión. Intenta cuando vuelva la señal.
Recupera tu clave
Si existe una cuenta con este celular, te enviaremos un código por SMS.
Enviar código
Reglas de estado
- OTP · intentos y expiración3 intentos por código; contador visible desde el segundo fallo. Código expira a los 10 min → "Este código expiró. Pide uno nuevo." Reenvío con countdown 60s (reuso
components-otp-input).
- Anti-enumeración en paso 2Se llega al OTP aunque la cuenta no exista (el SMS no llega). "Reenviar" responde igual en ambos casos.
- Requisitos en vivoChecklist valida al escribir: check verde al cumplir, círculo neutro pendiente. La confirmación solo valida al perder foco → "Las claves no coinciden."
- LoadingCTAs con spinner inline + "Procesando…". El OTP verifica automáticamente al completar el sexto dígito.
Dark · 360dp
Dark · paso 3
9:41
Crea una clave nueva
La usarás para entrar a MiCapi. Que no sea la de otro servicio.
Mínimo 8 caracteres
Una mayúscula y una minúscula
Un número
No contiene tu celular
Guardar clave
Dark · éxito
9:41
Clave actualizada
Ya puedes iniciar sesión con tu clave nueva.
Por tu seguridad, cerramos tus otras sesiones al cambiar la clave. Todo lo demás funciona normal: puedes comprar, vender y recibir.
Iniciar sesión
Notas de implementación · Flutter
Flujo forgot / reset + candado de retiros (espera F5)
Endpoints
POST /v1/auth/forgot-password {phone} → 200 siempre (exista o no). POST /v1/auth/reset-password {phone, otp, new_password} → 200 + side-effect: withdrawals_locked_until = now + 48h.
OTP · reuso
Widget de components-otp-input: 6 cajas, auto-focus siguiente, pegar desde SMS (sms_autofill / user consent API en Android), verificación automática al sexto dígito.
Éxito · check dibujado
Check con stroke-dashoffset 420ms ease-standard (canon §4.18); con reduced-motion aparece dibujado. Sin confeti.
Candado de 48 h — construido, sin puerta todavía
El backend sella withdrawals_locked_until y lo expone en /v1/me, pero hoy ninguna operación lo consume: el retiro on-chain (POST /v1/withdrawals/crypto) está en el contrato con x-phase: F5 y no está ruteado. Por eso esta pantalla ya no anuncia la pausa (ver §redline). Cuando F5 exista, el flujo de retiro consume el campo y muestra la hora exacta de desbloqueo, y el aviso vuelve acá. Un centinela del backend pone el gate en rojo si alguien rutea el carril sin imponer el candado.
Sesiones
El reset revoca todas las sesiones activas (visible en A5). El copy de éxito no lo dice aquí para no sobrecargar; se comunica en la notificación de seguridad.
Anti-enumeración
Respuestas uniformes, mismos tiempos (el backend añade jitter). La UI nunca ramifica por existencia de cuenta. Rate limit: 3 solicitudes/hora por número.