Saltar al contenido principal
Migo Docs

Manejo de errores

Cada API de Migo devuelve respuestas envueltas en un envelope CustomResponse<T>.

La forma del envelope es:

interface CustomResponse<T> {
success: boolean;
message?: string;
data?: T;
errors?: { code: string; message: string }[];
}

Nota que code es un string (p. ej. "7100"), y errors es un array de objetos { code, message }. No existe campo statusCode, error.name ni error.detail en el payload del wire — el name (p. ej. USER_NOT_FOUND) es la clave interna de MigoNameErrors, no parte del body de la respuesta.

Éxito

{
"success": true,
"message": "ok",
"data": { "...": "..." }
}

Error

{
"success": false,
"message": "Validation failed",
"errors": [
{
"code": "7100",
"message": "User not found in the system."
}
]
}

Mapeo de status codes

HTTP statusCuándo se devuelve
200 OKÉxito (incluyendo jobs asíncronos que devuelven un id de batch/job en el body)
201 CreatedRecurso creado (p. ej. creación de estado de cuenta aceptada)
204 No ContentÉxito, sin body
400 Bad RequestValidación de DTO falló
401 UnauthorizedJWT faltante / vencido / inválido
403 ForbiddenAutenticado pero permiso denegado
404 Not FoundEl recurso no existe
409 ConflictConflicto de estado del recurso
422 Unprocessable EntityValidación semántica falló (p. ej. tarjeta vencida)
500 Internal Server ErrorBug de Migo — repórtalo con el timestamp y los detalles de la solicitud
502 Bad GatewayProcesador upstream inalcanzable
503 Service UnavailableMantenimiento programado o caída parcial
504 Gateway TimeoutTimeout del procesador upstream

Rangos de códigos de error de negocio

Migo usa dos espacios distintos de códigos de error de negocio dependiendo de la API que estés llamando. El Wallet Gateway y el CMS Backoffice exponen un code string dentro del array errors[]; el Middleware usa un envelope separado con un ownCode. Los rangos numéricos no se traslapan y los nombres de los campos difieren.

Wallet Gateway, CMS Backoffice — 7000–8099

Estos códigos aparecen como string en cada entrada del array errors del envelope estándar CustomResponse mostrado arriba (p. ej. "code": "7100").

RangoSignificado
7000–7099General / validación / terminal-procesador
7100–7199Usuarios (incl. OTP, FCM, password, auth-user)
7200–7299Tarjetas (incl. tarjetas de terceros, view tokens)
7300–7399Transferencias y pagos en terminal
7400–7499Terminales, negocios y sucursales
7500–7599Liquidaciones y régimen fiscal
7600–7699Clientes, auth, roles, permisos, archivos y redes sociales
7700–7799Configuración de proyecto e integridad de app
8000–8099App / móvil (proceso, balance, permisos)

Los rangos 7800–7899 y 7900–7999 actualmente no se usan.

Lista completa en el Catálogo de errores.

El Middleware usa un envelope separado (ErrorResponseDto) y lleva el error de negocio dentro de un objeto error anidado, donde ownCode es un valor numérico pequeño (p. ej. "2002", "2007", "5000", "5004"). La forma es:

interface ErrorResponseDto {
message?: string;
error?: {
code?: number; // status HTTP asociado al error
ownCode?: string; // código de error de negocio de Migo
message?: string; // descripción legible
};
}

Estos no chocan con el espacio 7000–8099 porque viven en un envelope y ruta de campo diferentes (error.ownCode, no errors[].code).

RangoSignificado
2000–2099Creación de transacción / validación de negocio (usuario excluido, monto fuera de rango, etc.)
5000–5099Validación de DTO / configuración (campos faltantes, slug de cliente desconocido)

Lista completa en Catálogo de errores → ownCodes de Payment Link / Middleware.

Cuando envuelvas llamadas a ambas superficies en el mismo cliente, ramifica por ruta de campo:

const code = response?.errors?.[0]?.code ?? response?.error?.ownCode;

Semántica de reintentos

Clase de error¿Reintentar?Estrategia
Network timeoutExponential backoff
500 / 502 / 504Exponential backoff, máximo 3 reintentos
503Exponential backoff con techo amplio (hasta 5 min)
400 / 422NoCorrige la solicitud
401No (refresca en su lugar)Refresca el token, luego reintenta
403 / 404 / 409NoNo reintentes

Patrón cliente

async function call<T>(fn: () => Promise<T>, attempt = 0): Promise<T> {
try {
return await fn();
} catch (err) {
const status = err.response?.status;
if (status === 401) {
await refreshToken();
return call(fn, attempt + 1);
}
if ([500, 502, 503, 504].includes(status) && attempt < 3) {
const wait = 2 ** attempt * 500;
await new Promise(r => setTimeout(r, wait));
return call(fn, attempt + 1);
}
throw err;
}
}

Reportar incidentes

Al abrir un ticket de soporte incluye:

  • El timestamp de la solicitud en UTC (Migo lo correlaciona con la traza interna)
  • URL completa de la solicitud, método y headers (oculta el Bearer token)
  • Body de la solicitud (oculta PANs y CVVs)
  • Body completo de la respuesta