Facturación Electrónica

POST/v1/api/facturacion

Endpoint unificado — emite los 10 tipos de documento electrónico (FE, NC, ND, DS, NC-DS, Exportación, Contingencia T03/T04, POS, Nota Ajuste POS).

Modo Async disponible: Envía async: true para recibir una respuesta 202 Accepted inmediata. El documento se procesa en background con BullMQ y puedes consultar su estado via polling o WebSocket.

Request Body

CampoTipoRequeridoDescripción
id_tipo_documentointeger1=FE, 2=NC, 3=ND, 4=DS, 5=NC-DS, 6=Exportación, 7=Contingencia T03, 8=Contingencia T04, 9=POS, 10=Nota Ajuste POS
transmitbooleanNotrue para transmitir a DIAN inmediatamente
asyncbooleanNotrue = respuesta 202 Accepted + procesamiento en background con BullMQ. false (default) = síncrono.
customerobjectDatos del adquiriente (ver sub-tabla)
invoice_linesarrayLíneas del documento (FE y DS). Para NC usar credit_note_lines, para ND usar debit_note_lines
legal_monetary_totalsobjectNoTotales monetarios
tax_totalsarrayNoResumen de impuestos
payment_formobjectNoForma de pago
notesstringNoObservaciones
id_documento_referenciaintegerNoSolo NC/ND: ID del documento original al que aplica
id_concepto_notastringNoSolo NC/ND: Código del concepto/motivo
referencia_externastringNoReferencia única de tu sistema (ej: "ORD-001"). Previene duplicados — si ya existe, retorna 409

Customer Sub-table

CampoTipoRequeridoDescripción
identification_numberstringNIT o CC del cliente
namestringRazón social
emailstringCorreo para entrega del documento
type_document_identification.codestringNo13=CC, 31=NIT, 22=CE, 41=Pasaporte
type_organization.codestringNo1=Persona Jurídica, 2=Persona Natural
addressstringNoDirección
municipality.codestringNoCódigo DANE del municipio
municipality.namestringNoNombre del municipio

Invoice Lines Sub-table

CampoTipoRequeridoDescripción
descriptionstringDescripción del producto/servicio
invoiced_quantitynumberCantidad
line_extension_amountnumberSubtotal de la línea (sin impuestos)
price_amountnumberPrecio unitario
unit_measure.codestringNoCódigo unidad de medida (94=Unidad)
tax_totalsarrayNoImpuestos de esta línea

Request Example

JSON
{
  "id_tipo_documento": 1,
  "referencia_externa": "ORD-2026-001",
  "transmit": true,
  "async": false,
  "customer": {
    "identification_number": "900123456",
    "name": "Empresa XYZ SAS",
    "email": "facturacion@xyz.com",
    "type_document_identification": {
      "code": "31"
    },
    "type_organization": {
      "code": "1"
    },
    "address": "Calle 123 #45-67, Bogotá",
    "municipality": {
      "code": "11001",
      "name": "Bogotá D.C."
    }
  },
  "invoice_lines": [
    {
      "description": "Servicio de consultoría",
      "invoiced_quantity": 1,
      "line_extension_amount": 1000000,
      "price_amount": 1000000,
      "unit_measure": {
        "code": "94"
      },
      "tax_totals": [
        {
          "tax_code": "01",
          "tax_name": "IVA",
          "percent": 19,
          "taxable_amount": 1000000,
          "tax_amount": 190000
        }
      ]
    }
  ],
  "legal_monetary_totals": {
    "line_extension_amount": 1000000,
    "tax_exclusive_amount": 1000000,
    "tax_inclusive_amount": 1190000,
    "payable_amount": 1190000
  },
  "tax_totals": [
    {
      "tax_code": "01",
      "tax_name": "IVA",
      "percent": 19,
      "taxable_amount": 1000000,
      "tax_amount": 190000
    }
  ]
}

Respuesta Sync (200)

JSON
{
  "success": true,
  "message": "Factura Electrónica procesado exitosamente",
  "data": {
    "documento": {
      "id": 1,
      "prefijo": "SETT",
      "numero": "001",
      "cufe": "sha384...",
      "total": 1190000
    },
    "xml": "<Invoice>...</Invoice>",
    "cufe": "a1b2c3d4e5f6...",
    "cufe_scheme": "CUFE-SHA384",
    "qr_url": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=a1b2c3...",
    "transmission": {
      "isValid": true,
      "statusCode": "00",
      "statusDescription": "Procesado Correctamente",
      "errors": [],
      "zipKey": "uuid-track-id",
      "retryable": false
    }
  }
}

Respuesta Async (202)

JSON
{
  "success": true,
  "status": 202,
  "message": "Factura Electrónica en cola de transmisión",
  "data": {
    "documento": { "id": 1, "prefijo": "SETT", "numero": "001" },
    "cufe": "a1b2c3d4e5f6...",
    "cufe_scheme": "CUFE-SHA384",
    "qr_url": "https://catalogo-vpfe.dian.gov.co/...",
    "job_id": "bull-456",
    "poll_url": "/v1/api/facturacion/1/status?id_empresa=5"
  }
}
Ejemplos de Código
curl -X POST https://api.jcflow.com.co/v1/api/facturacion \
  -H "X-Api-Key: sk_test_tu_api_key_aqui" \
  -H "Content-Type: application/json" \
  -d '{"id_tipo_documento":1,"referencia_externa":"ORD-2026-001","transmit":true,"async":false,"customer":{"identification_number":"900123456","name":"Empresa XYZ SAS","email":"facturacion@xyz.com","type_document_identification":{"code":"31"},"type_organization":{"code":"1"},"address":"Calle 123 #45-67, Bogotá","municipality":{"code":"11001","name":"Bogotá D.C."}},"invoice_lines":[{"description":"Servicio de consultoría","invoiced_quantity":1,"line_extension_amount":1000000,"price_amount":1000000,"unit_measure":{"code":"94"},"tax_totals":[{"tax_code":"01","tax_name":"IVA","percent":19,"taxable_amount":1000000,"tax_amount":190000}]}],"legal_monetary_totals":{"line_extension_amount":1000000,"tax_exclusive_amount":1000000,"tax_inclusive_amount":1190000,"payable_amount":1190000},"tax_totals":[{"tax_code":"01","tax_name":"IVA","percent":19,"taxable_amount":1000000,"tax_amount":190000}]}'
Probar EndpointPOST /facturacion
⚙️ Reglas Automáticas en Producción (DIAN Anexo 1.8):
  • Transmisión Síncrona: En el ambiente de producción (o utilizando API keys de producción sk_live_...), la transmisión de los documentos se procesa siempre de forma síncrona (SendBillSync) para prevenir rechazos por falta de autorización para envíos por lotes asíncronos.
  • Supresión de Impuestos Vacíos: Para evitar advertencias restrictivas (como las notificaciones FAX05 y FAX14) en el portal oficial de la DIAN, el sistema suprime dinámicamente los bloques vacíos ICA (03) e INC (04) con base/porcentaje en 0.00 al operar en producción.
  • Alineación de Fechas y Firma: La fecha y hora de emisión del documento XML se auto-sincronizan en tiempo real con la marca de tiempo de la firma digital (con zona horaria Colombia -05:00), eliminando de raíz el rechazo por regla FAD09e.
  • Recálculo Transaccional del CUFE/CUDE: El código CUFE/CUDE se calcula e inyecta dinámicamente integrando el desfase horario oficial de -05:00 tanto en el cálculo matemático como en el tag IssueTime del XML, garantizando la consistencia exacta requerida.
✅ CUFE/CUDE (Verificado): Se genera con SHA-384 conforme al Anexo Técnico DIAN v1.8, Cap. 11.1.2. Verificado byte a byte contra el ejemplo oficial de la DIAN (CUFE: 8bb918b1...). CUFE para Facturas (clave técnica de resolución), CUDE para Notas y Contingencia (PIN software).
ℹ️ QR Code: La URL de verificación DIAN se genera automáticamente según el ambiente (habilitación/producción).
ℹ️ Validación Pre-emisión: El sistema valida automáticamente empresa, software DIAN, resolución (vigencia + rango), certificado digital, cliente y totales antes de generar el XML.
ℹ️ Email: El documento se envía automáticamente por correo al cliente con el XML adjunto.

Consultar Estado (Polling)

GET/v1/api/facturacion/:id/status

Consulta el estado actual de un documento. Útil para polling cuando usas modo async.

Query Parameters

CampoTipoRequeridoDescripción
id_empresaintegerID de la empresa (query param)
check_dianbooleanNotrue = Consultar DIAN GetStatus en vivo si el doc está En Cola
ambientestringNo1=Producción, 2=Habilitación (default: 2)

Estados del documento

CódigoEstadoDescripción
1BorradorGuardado, no transmitido
2Enviado/AceptadoDIAN aceptó el documento
3En ColaProcesándose en background (modo async)
4RechazadoDIAN rechazó el documento
5Esperando DIANCircuit Breaker abierto — DIAN no disponible. Se reenviará automáticamente.
6Dead LetterAgotó 5 reintentos. El Recovery Cron lo reencolará automáticamente cuando DIAN vuelva.
JSON
{
  "success": true,
  "data": {
    "id": 1,
    "prefijo": "SETT",
    "numero": "001",
    "id_tipo_documento": 1,
    "id_estado_documento": 2,
    "estado": "Enviado/Aceptado",
    "cufe": "a1b2c3d4e5f6...",
    "qr_url": "https://catalogo-vpfe.dian.gov.co/...",
    "dian_track_id": "uuid-zip-key",
    "dian_response": {
      "isValid": true,
      "statusCode": "00",
      "statusDescription": "Procesado Correctamente"
    },
    "total": 1190000,
    "fecha_emision": "2026-04-24",
    "created_at": "2026-04-24T10:30:00Z",
    "updated_at": "2026-04-24T10:30:05Z"
  }
}

Envío Masivo de Contingencia

POST/v1/api/facturacion/contingencia/enviar

Envía todos los documentos de contingencia (T03/T04) pendientes a la DIAN. Los documentos se encolan en BullMQ para procesamiento asíncrono.

Request Body

CampoTipoRequeridoDescripción
id_empresaintegerID de la empresa
documento_idsarrayNoIDs específicos a enviar. Si vacío, envía TODOS los pendientes.
JSON
{
  "success": true,
  "message": "15 documento(s) encolado(s) para transmisión.",
  "data": {
    "total_pendientes": 15,
    "total_encolados": 15,
    "total_errores": 0,
    "documentos": [
      { "id": 10, "prefijo": "SETT", "numero": "100", "job_id": "bull-789" },
      { "id": 11, "prefijo": "SETT", "numero": "101", "job_id": "bull-790" }
    ]
  }
}

Endpoints auxiliares

POST/v1/api/facturacion/reenviar/:id

Reenvía un documento en borrador o fallido a la DIAN. Regenera el XML, firma y transmite.

GET/v1/api/facturacion/consecutivo/:tipo

Obtiene el siguiente número consecutivo disponible para un tipo de documento.

GET/v1/api/facturacion/suscripcion

Consulta el estado de la suscripción: documentos usados, disponibles y límite.

🌐 Facturas de Exportación (Multidivisa & Incoterms)

Para emitir facturas de exportación (Tipo 02 / Operación 10), especifica la moneda extranjera (USD, EUR), la tasa de cambio TRM del día y los términos Incoterms (CIF, FOB, EXW, FCA, etc.):

JSON
{
  "id_tipo_documento": 2,
  "id_tipo_operacion": "10",
  "id_tipo_moneda": 149,
  "exchange_rate": {
    "source_currency": "USD",
    "target_currency": "COP",
    "calculation_rate": 4150.50,
    "date": "2026-08-29"
  },
  "delivery": {
    "delivery_terms": "FOB"
  },
  "customer": {
    "name": "Global Tech Logistics LLC",
    "identification_number": "US99887766",
    "country_code": "US",
    "type_document_identification": { "code": "41" },
    "type_organization": { "code": "1" },
    "email": "invoices@globaltech.us"
  },
  "invoice_lines": [
    {
      "description": "Exportación de Café Especial Colombiano (Sacos 70kg)",
      "invoiced_quantity": 50,
      "price_amount": 280.00,
      "line_extension_amount": 14000.00,
      "unit_measure": { "code": "KGM" }
    }
  ],
  "legal_monetary_totals": {
    "line_extension_amount": 14000.00,
    "tax_exclusive_amount": 14000.00,
    "tax_inclusive_amount": 14000.00,
    "payable_amount": 14000.00
  },
  "transmit": true
}

🏥 Facturación Sectorial (Salud RIPS, Transporte RNDC, Combustibles)

Sector Salud (RIPS)

Operación 11. Valida campos sectoriales de MinSalud, código de prestador, copagos y cuotas moderadoras.

Sector Transporte (RNDC)

Operación 12. Integra remesa de carga terrestre y manifiesto oficial del Ministerio de Transporte.

Combustibles (EDS)

Soporte automático para Impuesto Nacional a Combustibles (24), Sobretasa (25) y Sordicom (26).

Eventos WebSocket (Real-time)

facturacion:updateDocumento aceptado/rechazado por DIAN (estado, errores, zipKey)

facturacion:errorMáx reintentos agotados. El documento se marcará como recuperable y será reenviado automáticamente.

contingencia:batchInicio de envío masivo de contingencia

Rooms: empresa_{id}, user_{id}

🛡️ Motor de Resiliencia DIAN

El sistema protege contra caídas del Web Service de la DIAN con múltiples capas de resiliencia. Ningún documento se pierde — todos se reenvían automáticamente.
CapaMecanismoDetalle
Circuit BreakerDetección de caída5 fallos consecutivos → pausa envíos 60s → prueba automática → reanuda si DIAN responde
Exponential BackoffReintentos progresivos5 intentos: 10s → 20s → 40s → 80s → 160s
Dead Letter QueueCola de fallidosDespués de 5 intentos → estado 6 (recuperable automáticamente)
Recovery CronRecuperación automáticaCada 5 min busca docs en estado 5/6 y los reencola si DIAN está disponible
Rate LimiterControl de velocidadMáx 10 req/seg al WS DIAN, 3 workers concurrentes

Circuit Breaker

CLOSED ──(5 fallos)──▸ OPEN ──(60s)──▸ HALF_OPEN ──(2 éxitos)──▸ CLOSED
                         ▲                 │ fallo
                         └─────────────────┘ (timeout escala: 60s → 120s → 5min)

Estados del Documento

EstadoIDDescripción
Borrador1Generado, no transmitido a DIAN
Aceptado2DIAN aceptó y validó el documento
En Cola3En proceso vía BullMQ (modo async)
Rechazado4DIAN rechazó el documento (error de negocio)
Esperando DIAN5Circuit Breaker abierto — se reenviará automáticamente
Dead Letter6Agotó 5 reintentos — Recovery Cron lo reencolará
Sin pérdida de documentos: Los estados 5 y 6 son recuperables. El Recovery Cron (cada 5 min) reencola automáticamente todos los documentos pendientes cuando detecta que DIAN volvió a estar disponible.

📊 Rendimiento (Benchmark)

Resultados del stress test ejecutado en servidor local con 500 facturas electrónicas procesadas en ráfaga con 25 conexiones concurrentes (sin transmisión a DIAN).

100%
Éxito
281req/s
Throughput
75ms
Median Latency
162ms
P95 Latency

Distribución de Latencia

< 100ms87%
100–200ms13%
> 200ms0%
MétricaValor
Total requests500
Concurrencia25
Tiempo total1.78s
Throughput281 req/s
Avg Latency82ms
Median (P50)75ms
P95162ms
P99178ms
Max179ms
⚠️ Nota: En producción con transmit=true, la latencia de transmisión DIAN (1-5s) se procesa en background vía BullMQ. La respuesta al cliente sigue siendo ~150ms (202 Accepted).