SIFENDE
Guías

Manejar Errores

Cómo interpretar y manejar errores de la API de Sifende y rechazos de SIFEN en tu integración.

Esta guía explica cómo distinguir los distintos tipos de error que recibís de Sifende, qué hacer con cada uno y cuándo (no) reintentar.

Dos fuentes de error muy distintas

Mezclarlas en un mismo catch es una de las primeras causas de bugs en integraciones SIFEN.

FuenteCuándo apareceCómo se ve
API SifendeInmediato, en el HTTP responseStatus 400/401/403/404/422 + Problem Details JSON
SIFEN (rechazo asíncrono)Después del polling, una vez que SIFEN procesa el loteestado: "RECHAZADO" + mensajeRechazo con código SIFEN

Errores de la API Sifende (síncronos)

Sigan el formato RFC 9457 Problem Details (excepto autenticación):

{
  "type": "https://sifende.com.py/probs/validation-error",
  "title": "Error de validación",
  "status": 400,
  "detail": "La solicitud contiene 2 error(es) de validación",
  "errores": {
    "receptor.numeroDocumento": "Número de documento es obligatorio",
    "items[0].precioUnitario": "El precio no puede ser negativo"
  }
}

Cómo manejarlos en código

const res = await fetch('https://api.sifende.com.py/api/v1/documento-electronico', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});

if (!res.ok) {
  const problem = await res.json();

  if (problem.type?.includes('validation-error')) {
    for (const [campo, mensaje] of Object.entries(problem.errores ?? {})) {
      console.error(`Campo inválido: ${campo} → ${mensaje}`);
    }
    throw new ValidacionError(problem);
  }

  if (problem.type?.includes('invalid-enum-value')) {
    console.error(`Valor inválido en ${problem.campo}. Aceptados:`, problem.valoresAceptados);
    throw new EnumError(problem);
  }

  throw new ApiError(problem);
}

const cdc = await res.text();

Tabla rápida de tipos

StatusTipoAcción
400validation-errorRevisar errores por campo, corregir y reenviar
400invalid-enum-valueUsar uno de valoresAceptados
400invalid-formatCorregir formato (fecha, RUC, CDC)
401(texto plano)API key inválida/expirada. Rotá la credencial desde el panel
403access-deniedEl usuario/key no tiene acceso a ese contribuyente
404*-not-foundRecurso inexistente. Verificar IDs
409duplicate-*Ya existe. Usar el existente o cambiar identificador
422documento-electronico-generation-errorError de compliance SIFEN al generar el XML

Catálogo completo en Errores.

Rechazos SIFEN (asíncronos)

Después de emitir, el documento queda en PENDIENTE o EN_LOTE. Una vez procesado, SIFEN devuelve un código con la respuesta. Los más frecuentes en producción:

Código SIFENSignificadoCómo corregirlo
1108Fecha fin de vigencia del timbrado incorrecta (timbrado vencido o mal configurado)Renová o corregí la fechaFin del timbrado en SET y actualizalo en Sifende
1302Falta tipoContribuyente del receptor para B2BCompletar tipoContribuyente: "CONTRIBUYENTE"
1303Tipo de contribuyente receptor inválido (informado cuando es NO_CONTRIBUYENTE)No incluyas tipoContribuyente en B2C no contribuyente
1304Falta numeroDocumento (RUC) para receptor contribuyenteCompletar el RUC del receptor
1305RUC del receptor no requerido (informado para NO_CONTRIBUYENTE)Eliminar numeroDocumento en B2C no contribuyente
1306RUC del receptor inexistente en Marangatu (RUC no registrado en SET)Confirmar el RUC con tu cliente
1309DV del RUC del receptor incorrectoVerificar digitoVerificador
2026CDC asociado no existe o no está aprobadoSolo emitir NCE/NDE sobre FE en estado APROBADO

Tabla completa: Rechazos SIFEN.

Cómo leer el rechazo

El campo mensajeRechazo del status response contiene el código y la descripción:

const resultado = await esperarResultadoSIFEN(cdc);

if (resultado.estado === 'RECHAZADO') {
  // Ej: "1108 - Timbrado vencido"
  const codigo = resultado.mensajeRechazo?.split(' ')[0];
  log.warn({ cdc, codigo, motivo: resultado.mensajeRechazo }, 'DE rechazado por SIFEN');
}

Cuándo reintentar (y cuándo no)

Situación¿Reintentar?Cómo
5xx temporal de la API SifendeBackoff exponencial (1s, 2s, 4s…), máximo 3 intentos
401 / 403Arreglá credenciales, no reintentes con la misma
400 validation-errorCorregí los datos antes de reenviar
404 documento-electronico-not-foundEl CDC no existe; no aparecerá reintentando
Rechazo SIFEN⚠️Emitir un DE nuevo con los datos corregidos. El original queda rechazado para siempre

Nunca reintentes el mismo request rechazado por SIFEN. Cada DE consume un número del rango de timbrado: el rechazado ya gastó ese número y no se recupera. Para evitar gastar números, Inutilizar Numeración.

Recomendaciones de logging

En tu integración, logueá siempre:

  • cdc, para correlacionar con tu sistema.
  • estado y mensajeRechazo cuando consultes status.
  • type, title, status y detail del Problem Details ante errores.
  • El request body completo en errores 4xx (excepto la API key); facilita reproducir el problema.
log.error({
  cdc,
  estado: resultado.estado,
  mensajeRechazo: resultado.mensajeRechazo,
}, 'DE rechazado');

Próximos pasos

On this page