SIFENDE
Guías

Consultar Estado de un Documento

Cómo verificar si un documento fue aprobado o rechazado por SIFEN usando el CDC, con la estrategia de polling recomendada.

Cuando emitís un documento electrónico, Sifende lo recibe al instante y te devuelve el CDC, pero el procesamiento real en SIFEN es asíncrono. Esta guía cubre cómo consultar el estado y cuándo dejar de hacer polling.

El endpoint

GET /api/v1/documento-electronico/status/:cdc
curl https://api.sifende.com.py/api/v1/documento-electronico/status/$CDC \
  -H "Authorization: Bearer $SIFENDE_API_KEY"

Respuesta (DocumentoElectronicoStatusDTO):

{
  "cdc": "01800123451001001000000122026042710000000006",
  "estado": "APROBADO",
  "iTiDe": 1,
  "numeroDocumento": 1,
  "fechaCreacion": "2026-04-27T10:30:00",
  "protocoloAutorizacion": "20260427103018987654",
  "mensajeRechazo": null
}
CampoTipoDescripción
cdcstringCDC del documento (44 caracteres)
estadoenumEstado actual (ver tabla abajo)
iTiDeintCódigo numérico del tipo de documento SIFEN
numeroDocumentoLongNúmero correlativo dentro del rango de timbrado (entero)
fechaCreacionstringFecha y hora en que Sifende registró el documento (ISO 8601)
protocoloAutorizacionstring | nullNúmero de protocolo SIFEN. Presente cuando el DE quedó registrado: APROBADO o APROBADO_OBSERVACION
mensajeRechazostring | nullDetalle de SIFEN en formato [código] mensaje, varias entradas separadas por |. Presente en RECHAZADO (motivo del rechazo) y en APROBADO_OBSERVACION (observaciones)

numeroDocumento es un entero (Long). Si necesitás el formato "NNN-NNN-NNNNNNN" para mostrar al usuario, usá el campo numeroFormateado que devuelve la respuesta de emisión (POST /documento-electronico). Son dos campos separados, no los confundas.

Estados posibles

EstadoSignificado¿Seguir consultando?
PENDIENTESifende lo recibió pero todavía no se asignó a un loteSí
EN_LOTEEstá agrupado en un lote, listo para enviar a SIFENSí
ENVIADOEl lote ya fue enviado a SIFEN, esperando respuestaSí
APROBADOSIFEN lo aprobó. El documento es válido y firmadoNo, terminado
APROBADO_OBSERVACIONSIFEN lo registró con observaciones. El documento es válido igual; leer mensajeRechazoNo, terminado
RECHAZADOSIFEN lo rechazó. Leer mensajeRechazoNo, terminado
ERRORFalla técnica en el envío o procesamientoNo, no reemitir; volvé a consultar o contactá a soporte
CANCELADOFue aprobado y luego cancelado vía eventoNo, terminado
DESCONOCIDOEstado no determinable (caso raro de inconsistencia con SIFEN)Consultar nuevamente

Estrategia de polling recomendada

  • Intervalo: entre 3 y 5 segundos. Más frecuente solo agrega carga sin reducir la latencia real.
  • Timeout: 5 minutos como máximo. Si no resuelve antes, hay un problema de procesamiento; revisá el panel de Sifende.
  • Detenete apenas el estado pase a APROBADO, APROBADO_OBSERVACION, RECHAZADO, ERROR o CANCELADO.

Implementación en TypeScript

type EstadoDE =
  | 'PENDIENTE'
  | 'EN_LOTE'
  | 'ENVIADO'
  | 'APROBADO'
  | 'APROBADO_OBSERVACION'
  | 'RECHAZADO'
  | 'ERROR'
  | 'CANCELADO'
  | 'DESCONOCIDO';

interface EstadoResponse {
  cdc: string;
  estado: EstadoDE;
  iTiDe: number;
  numeroDocumento: number; // Long en backend
  fechaCreacion: string;
  protocoloAutorizacion: string | null;
  mensajeRechazo: string | null;
}

async function esperarResultadoSIFEN(
  cdc: string,
  { intervaloMs = 5000, timeoutMs = 300_000 } = {}
): Promise<EstadoResponse> {
  const inicio = Date.now();

  while (Date.now() - inicio < timeoutMs) {
    const res = await fetch(
      `https://api.sifende.com.py/api/v1/documento-electronico/status/${cdc}`,
      { headers: { Authorization: `Bearer ${process.env.SIFENDE_API_KEY}` } }
    );

    if (!res.ok) {
      throw new Error(`Error consultando estado: ${res.status}`);
    }

    const data: EstadoResponse = await res.json();

    if (
      data.estado === 'APROBADO' ||
      data.estado === 'APROBADO_OBSERVACION' ||
      data.estado === 'RECHAZADO' ||
      data.estado === 'ERROR' ||
      data.estado === 'CANCELADO'
    ) {
      return data;
    }

    await new Promise(r => setTimeout(r, intervaloMs));
  }

  throw new Error(`Timeout esperando resultado SIFEN para CDC ${cdc}`);
}

Uso típico

const resultado = await esperarResultadoSIFEN(cdc);

switch (resultado.estado) {
  case 'APROBADO':
    // Descargá el KuDE, marcá la venta como facturada, mandá email al cliente
    break;
  case 'APROBADO_OBSERVACION':
    // Igual que APROBADO: el DE quedó registrado. Guardá la observación para revisarla.
    console.warn('SIFEN observó el DE:', resultado.mensajeRechazo);
    break;
  case 'RECHAZADO':
    // Logueá mensajeRechazo, alertá al equipo, corregí los datos
    console.error('SIFEN rechazó el DE:', resultado.mensajeRechazo);
    break;
  case 'CANCELADO':
    // El documento fue cancelado; usualmente esto no aparece en flujo de emisión
    break;
}

¿Qué hacer en cada estado final?

APROBADO

APROBADO_OBSERVACION

  • El documento quedó registrado en SIFEN y es legalmente válido, igual que un APROBADO. No lo reemitas.
  • mensajeRechazo trae la observación con el formato [código] mensaje. Guardala y corregí lo señalado en las próximas emisiones.
  • KuDE, cancelación y referencia desde NCE/NDE funcionan igual que con APROBADO.

RECHAZADO

  • El campo mensajeRechazo contiene el código y descripción de SIFEN (ej: [1108] Timbrado vencido).
  • Corregí los datos del documento o la configuración subyacente (timbrado, certificado, etc.). El documento rechazado no se reintenta tal cual; emitís uno nuevo.
  • Detalle paso a paso en Manejar Errores y Reintentar Rechazados.

CANCELADO

  • El documento fue aprobado y posteriormente cancelado mediante evento.
  • Este estado normalmente lo vas a ver al consultar un documento ya procesado, no como resultado del flujo de emisión.

Alternativa: webhooks

El polling es sencillo pero puede ser ineficiente a alto volumen. Configurá webhooks para recibir cambios de estado y mantené las consultas como respaldo operativo.

Próximos pasos

On this page