Phone verification: trazas completas entre envío y verificación
Para depurar fallos de código de verificación en juegos, cada intento debe rastrearse como una única traza con estados claros y auditable.

Para depurar un intento fallido de verificación de teléfono en un flujo de recuperación de cuentas de juego, la recomendación es tratar cada intento como una traza única que abarca envío, entrega y verificación, y auditar cada transición.\n\nLa traza debe iniciarse con un registro de intento que incluya un attemptId aleatorio, un hash de teléfono normalizado, una hora de expiración y un estado inicial. Los estados mínimos son: created, send_accepted, send_rejected, verified, expired, locked. Se añaden eventos de transición con marca de tiempo, actor (servidor, carrier_receipt o jugador) y motivo anonimizado; la fila actual sirve para lecturas rápidas, mientras que la serie de eventos explica el camino.\n\nUn envelope de solicitud típico:
type VerificationEvent = {
attemptId: string;
requestId: string;
phase: "send" | "delivery" | "verify";
outcome: "accepted" | "rejected" | "delivered" | "failed";
code?: string;
occurredAt: string;
};
El requestId debe generarse en el edge y propagarse a través de colas, adaptadores de proveedor y almacenamiento. Si se produce un reintento, se conserva el mismo attemptId pero se registra un nuevo requestId.\n\nPara aislar fallos, usa los límites de fase como checklist:
- No hay evento
created: el pedido nunca llegó al servicio de autenticación. send_rejected: la llamada de envío devolvió una clasificación de rechazo; verifica políticas de destino y límites de tasa.send_acceptedsin evento de entrega: el mensaje fue aceptado, pero no se recibió confirmación de entrega; revisa el feed de recibos y latencia del carrier.deliveredconverify_rejected: el código llegó, pero no se autenticó; compara ID de intento, expiración, recuento de reintentos y versión de código.verified: el chequeo de posesión pasó; procede con rotación de sesión y registro de auditoría. \nEs importante no inferir un fallo de envío por la ausencia de verificación. Cada fase debe ser evaluada de forma independiente.\n\nEl esquema de error debe ser pequeño y estable:invalid_destination,rate_limited,expired_code,mismatch,already_used. Evita copiar mensajes de vendors directamente, ya que cambian y pueden contener datos sensibles.\n\nDos fallos sutiles comunes:
- Desfase horaria: el worker de envío puede marcar expiración con su reloj, mientras que el servicio de verificación usa otro. Usa una expiración emitida por el servidor y compáralo con una fuente de tiempo autorizada. Un código de cinco minutos no lo será si los relojes difieren 90 segundos.
- Estado de UI obsoleto: un jugador solicita un segundo código, recibe el primero, pero envía el primero de la sugerencia de autocompletar. La API debe devolver un fallo genérico al jugador, pero el evento de auditoría puede marcar
superseded_attempt.\n\nOWASP aconseja que las respuestas de autenticación eviten señales de enumeración de cuentas; esto aplica también a flujos de recuperación. En resumen, la clave es preservar evidencia y diseñar la traza con estados y eventos claramente definidos.

