La facturación electrónica en Colombia ya no es una opción, sino una obligación para la mayoría de contribuyentes. Desde la Resolución 000065 de 2022, la DIAN exige que los documentos soporten transacciones de venta en formato electrónico, con validez fiscal y jurídica. Sin embargo, para muchas empresas, especialmente pymes, el proceso manual de generación, validación y envío representa una carga operativa y riesgo de errores costosos.
Automatizar la factura electrónica permite reducir tiempos, eliminar errores humanos y garantizar cumplimiento normativo de manera sostenible. En esta guía exploraremos qué es la factura electrónica, qué elementos técnicos involucra, y cómo puedes implementar un flujo automático con herramientas accesibles y código Python. Ya seas gerente, contador o desarrollador, aquí encontrarás pasos concretos para transformar un requisito obligatorio en una ventaja competitiva.
Qué es la factura electrónica en Colombia y por qué automatizarla
La factura electrónica es un documento digital que representa una factura de venta, con el mismo valor legal que la factura física, pero generada, firmada, transmitida y almacenada en formato electrónico. En Colombia, la DIAN define reglas claras sobre el formato, la estructura y los servicios de validación. Cada factura debe cumplir con un esquema XML específico, contener la firma digital del emisor, y enviarse al sistema de la DIAN para su validación y asignación de un número oficial.
Automatizar este proceso significa eliminar tareas repetitivas como el ingreso manual de datos, la generación de archivos XML, la firma digital y la consulta de aceptación o rechazo. Un flujo automatizado reduce tiempos de emisión de horas a segundos, disminuye errores de digitación y proporciona trazabilidad completa. Además, facilita la integración con sistemas contables y ERP, actualiza inventarios en tiempo real y mejora la experiencia del cliente al emitir facturas de forma inmediata después de la transacción.
Requisitos técnicos para automatizar la factura electrónica
Antes de programar cualquier automatización, es fundamental entender los componentes técnicos que intervienen. La DIAN exige que cada factura electrónica cumpla con los siguientes elementos:
Esquema XML según la versión vigente (actualmente UBL 2.1 para Colombia). El XML debe incluir secciones como invoice, accountingSupplierParty, accountingCustomerParty y taxTotal, entre otras.
Firma digital basada en certificado X.509 emitido por una entidad autorizada. Este certificado garantiza la autenticidad e integridad del documento.
Transmisión a la DIAN mediante el servicio web de habilitación (pre-producción y producción). Los proveedores tecnológicos deben estar inscritos y aprobados.
Numeración consecutiva según el rango autorizado por la DIAN.
Almacenamiento electrónico del documento y su representación visual (PDF) durante el plazo legal.
Para automatizar, necesitarás acceso a un certificado digital, credenciales de conexión al servicio web de la DIAN y un entorno de desarrollo con librerías para manejar XML y firma. Es recomendable empezar en el ambiente de pruebas (habilitación) antes de pasar a producción.
Configuración inicial del entorno de desarrollo
Para generar y firmar facturas electrónicas en Colombia, utilizaremos Python por su amplio ecosistema de librerías para XML y criptografía. A continuación, se presenta una configuración básica que incluye la generación de un XML de factura simple, su firma digital con un certificado .p12 y la simulación de envío a un servicio web.
Primero, instala las dependencias necesarias:
pip install lxml signxml requests cryptography
La librería lxml permite construir y manipular XML de forma eficiente, signxml facilita la firma digital y requests se usa para enviar el documento al servicio web. También necesitarás un certificado digital emitido por una entidad autorizada en Colombia, como la Cámara de Comercio o una entidad de certificación abierta.
Generación y firma del XML de factura
El siguiente código muestra cómo crear una factura electrónica básica con las secciones obligatorias, firmarla con el certificado y generar el archivo listo para enviar a la DIAN:
from lxml import etree
from signxml import XMLSigner
from cryptography.hazmat.primitives import serialization
from datetime import datetime
import uuid
Configuración inicial
fecha_emision = datetime.now().strftime('%Y-%m-%d')
invoice_number = 'SETP990000001'
prefix = 'SETP'
uuid_invoice = str(uuid.uuid4())
Esquema base UBL 2.1 (simplificado para ejemplo)
invoice_xml = f'''<?xml version="1.0" encoding="UTF-8"?>
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
cbc:UBLVersionID2.1/cbc:UBLVersionID
cbc:CustomizationID10/cbc:CustomizationID
cbc:ProfileID2/cbc:ProfileID
cbc:ID{invoice_number}/cbc:ID
cbc:UUID{uuid_invoice}/cbc:UUID
cbc:IssueDate{fecha_emision}/cbc:IssueDate
cbc:InvoiceTypeCode01/cbc:InvoiceTypeCode
cbc:NoteFACTURA ELECTRONICA/cbc:Note
cbc:DocumentCurrencyCodeCOP/cbc:DocumentCurrencyCode
cac:AccountingSupplierParty
cac:Party
cac:PartyIdentification
800123456/cbc:ID
/cac:PartyIdentification
cac:PartyName
cbc:NameMi Empresa SAS/cbc:Name
/cac:PartyName
/cac:Party
/cac:AccountingSupplierParty
cac:AccountingCustomerParty
cac:Party
cac:PartyIdentification
1234567890/cbc:ID
/cac:PartyIdentification
cac:PartyName
cbc:NameCliente Ejemplo/cbc:Name
/cac:PartyName
/cac:Party
/cac:AccountingCustomerParty
cac:TaxTotal
19000.00/cbc:TaxAmount
/cac:TaxTotal
cac:LegalMonetaryTotal
100000.00/cbc:TaxExclusiveAmount
119000.00/cbc:TaxInclusiveAmount
119000.00/cbc:PayableAmount
/cac:LegalMonetaryTotal
'''
root = etree.fromstring(invoice_xml.encode('utf-8'))
Cargar certificado .p12
with open('certificado.p12', 'rb') as cert_file:
cert = serialization.pkcs12.load_pkcs12(cert_file.read(), b'password_certificado')
signer = XMLSigner(method=etree.tree.ElementTree.signature_method)
signed_root = signer.sign(root, key=cert.key, cert=cert.cert)
Guardar XML firmado
with open('factura_firmada.xml', 'wb') as f:
f.write(etree.tostring(signed_root, pretty_print=True, xml_declaration=True, encoding='UTF-8'))
print('Factura firmada generada: factura_firmada.xml')
Este código crea un XML con datos básicos, lo firma con el certificado y guarda el documento. Para un entorno productivo, deberías parametrizar todos los datos desde tu sistema de facturación (clientes, productos, impuestos, etc.). Además, es recomendable validar el XML contra el esquema oficial de la DIAN antes de firmarlo.
Integración con el servicio web de la DIAN
Una vez firmada la factura, el siguiente paso es enviarla al servicio web de la DIAN para validación. La DIAN ofrece un servicio de habilitación (pre-producción) y uno de producción. Para ambos, necesitas un usuario y contraseña proporcionados por la DIAN o por tu proveedor tecnológico autorizado.
El siguiente ejemplo muestra cómo enviar el XML firmado a un servicio web simulado y procesar la respuesta:
import requests
Configuración del servicio web (ambiente de pruebas)
url_service = 'https://vpfe.dian.gov.co/WcfDianCustomerServices.svc'
headers = {
'Content-Type': 'application/soap+xml; charset=utf-8',
'SOAPAction': 'http://tempuri.org/IDianCustomerServices/SendBill'
}
Construir el cuerpo SOAP con el XML firmado
with open('factura_firmada.xml', 'r', encoding='utf-8') as xml_file:
xml_content = xml_file.read()
soap_body = f'''
soap:Header/
soap:Body
{invoice_number}.xml
{xml_content}
/soap:Body
/soap:Envelope'''
Enviar la factura
response = requests.post(url_service, data=soap_body.encode('utf-8'), headers=headers, timeout=30)
if response.status_code == 200:
print('Factura enviada a la DIAN correctamente')
print('Respuesta:', response.text)
else:
print('Error en envío:', response.status_code, response.text)
En la práctica, el servicio web puede requerir autenticación adicional, como un token de seguridad o un usuario específico. También es importante manejar excepciones de red, tiempos de espera y validación de respuestas XML. Si la DIAN acepta el documento, retornará un código de confirmación y asignará un número oficial. Si hay errores, recibirás un mensaje detallado que debes analizar y corregir.
Manejo de estados y notificaciones automáticas
Después de enviar la factura, la DIAN puede cambiar su estado: aceptada, rechazada, en validación, etc. Para mantener un flujo automático completo, debes consultar periódicamente el estado de cada documento. La DIAN proporciona servicios de consulta, y también puedes implementar un sistema de notificaciones por correo electrónico o mensajería para informar al cliente y al área contable.
El siguiente ejemplo ilustra cómo consultar el estado de una factura ya enviada:
import requests
from lxml import etree
def consultar_estado_factura(numero_factura):
url_service = 'https://vpfe.dian.gov.co/WcfDianCustomerServices.svc'
headers = {
'Content-Type': 'application/soap+xml; charset=utf-8',
'SOAPAction': 'http://tempuri.org/IDianCustomerServices/GetStatusBill'
}
soap_body = f'''
soap:Header/
soap:Body
{numero_factura}
/soap:Body
/soap:Envelope'''
response = requests.post(url_service, data=soap_body.encode('utf-8'), headers=headers, timeout=30)
if response.status_code == 200:
# Parsear la respuesta XML para extraer el estado
root = etree.fromstring(response.content)
estado = root.find('.//{http://tempuri.org/}Status')
if estado is not None:
return estado.text
else:
return 'Sin estado'
else:
return f'Error: {response.status_code}'
Ejemplo de uso
estado = consultar_estado_factura(invoice_number)
print(f'Estado de la factura {invoice_number}: {estado}')
En un sistema real, esta consulta se ejecutaría automáticamente cada cierto tiempo (mediante un job programado) o mediante webhooks si la DIAN provee notificaciones push. Cuando el estado cambia a aceptada, puedes enviar un correo electrónico al cliente con el PDF adjunto y registrar el documento en tu sistema contable. Si es rechazada, el sistema debe alertar al área de facturación para corregir y reenviar.
Almacenamiento electrónico y generación del PDF
La DIAN exige que la factura electrónica se almacene durante cinco años, tanto el XML como la representación visual en PDF. Automatizar el almacenamiento implica guardar los archivos en un repositorio seguro, con respaldos periódicos y control de acceso. Para generar el PDF desde el XML firmado, puedes usar librerías como weasyprint o reportlab, combinadas con plantillas HTML.
Ejemplo simplificado de generación de PDF:
from weasyprint import HTML
Crear una representación HTML simple a partir de datos de la factura
html_content = f'''
Factura Electrónica {invoice_number}
Fecha: {fecha_emision}
Emisor: Mi Empresa SAS, NIT: 800123456
Receptor: Cliente Ejemplo, ID: 1234567890
Total COP: 119,000.00
'''
HTML(string=html_content).write_pdf(f'factura_{invoice_number}.pdf')
print('PDF generado:', f'factura_{invoice_number}.pdf')
Aunque este ejemplo es básico, en producción debes replicar exactamente el diseño y la información que exige la DIAN para la representación visual, incluyendo el código QR, el CUFE y el número de factura.
Buenas prácticas y errores comunes al automatizar
Automatizar la factura electrónica no se trata solo de escribir código; implica adoptar buenas prácticas que garanticen cumplimiento y seguridad. Aquí algunos puntos clave:
Mantén el certificado digital seguro: Almacénalo en un gestor de secretos o un hardware security module (HSM). Nunca lo incluyas en repositorios de código fuente.
Valida el XML antes de firmar: Usa los esquemas XSD oficiales de la DIAN para detectar errores estructurales antes de enviar.
Implementa reintentos y manejo de errores: Los servicios web pueden fallar por problemas de red o mantenimientos. Diseña tu código para reintentar de forma controlada.
Registra toda la comunicación: Guarda logs de envíos, respuestas y estados. Esto es esencial para auditorías.
Mantente actualizado: La DIAN puede modificar requisitos o plazos. Suscríbete a sus canales oficiales y prueba cambios en el ambiente de habilitación antes de produccion.
Uno de los errores más comunes es firmar el XML sin antes validar su estructura contra el esquema oficial. Otro es olvidar la codificación UTF-8, lo que genera caracteres ilegibles y rechazo automático. También es frecuente manejar incorrectamente los decimales en impuestos, lo que produce diferencias en las sumas y rechazo de la factura.
Escalando la automatización con un proveedor tecnológico
Si no cuentas con un equipo de desarrollo robusto, puedes apoyarte en proveedores tecnológicos que ofrecen APIs o SDKs para facturación electrónica en Colombia. Estos proveedores se encargan de la conexión con la DIAN, la validación, la firma y el almacenamiento, permitiéndote integrar la facturación en tu ERP o sistema de punto de venta mediante una interfaz sencilla.
Al evaluar un proveedor, verifica que esté inscrito en el registro de proveedores tecnológicos de la DIAN, que ofrezca soporte en caso de errores y que cumpla con los acuerdos de nivel de servicio (SLA). Integrar una API externa suele ser más rápido y seguro que construir todo desde cero, especialmente para empresas sin experiencia en criptografía o servicios web gubernamentales.
Ejemplo de integración con API REST de un proveedor
Supongamos que utilizas un proveedor que expone un endpoint REST para crear facturas. El flujo sería:
Autenticarte con tu API key.
Enviar un JSON con los datos de la factura.
El proveedor genera el XML, lo firma y lo envía a la DIAN.
Retorna el estado y el enlace al PDF.
Un ejemplo simplificado en Python:
import requests
API_KEY = 'tu_api_key_proveedor'
url = 'https://api.proveedortecnologico.com/v1/facturas'
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}
payload = {
"invoice_number": invoice_number,
"issue_date": fecha_emision,
"supplier_nit": "800123456",
"customer_id": "1234567890",
"tax_exclusive_amount": 100000.00,
"tax_amount": 19000.00,
"total_amount": 119000.00,
"currency": "COP"
}
response = requests.post(url, json=payload, headers=headers, timeout=30)
if response.status_code in (200, 201):
factura = response.json()
print('Factura creada:', factura['id'])
print('Estado:', factura['status'])
print('PDF:', factura['pdf_url'])
else:
print('Error:', response.status_code, response.text)
Este enfoque simplifica enormemente la implementación. Tu equipo solo debe preocuparse por recolectar los datos de la factura y enviarlos al proveedor, que se encarga de la complejidad técnica y normativa.
Conclusión y llamada a la acción
Automatizar la facturación electrónica en Colombia es una decisión estratégica que impacta la eficiencia operativa, el cumplimiento fiscal y la satisfacción del cliente. Ya sea que desarrolles tu propia solución con Python y herramientas open source, o que elijas un proveedor tecnológico confiable, el objetivo es transformar un proceso obligatorio en una ventaja competitiva.
Si buscas una forma rápida y segura de implementar facturación electrónica sin complicaciones, explora las soluciones en arenasaitools.com. Allí encontrarás herramientas diseñadas para automatizar procesos empresariales, adaptadas a las normativas colombianas y fáciles de integrar con tus sistemas actuales. Da el paso hacia la digitalización completa y elimina las tareas manuales que frenan tu crecimiento.
Top comments (0)