Introducción
Esta API permite emitir documentos electrónicos válidos ante la SET (Subsecretaría de Estado de Tributación) de Paraguay a través del sistema SIFEN.
Cumplimiento Legal
100% conforme a Manual Técnico SIFEN v150 de la DNIT
Integración Simple
API REST con JSON, autenticación JWT, Swagger interactivo en /api/docs
Seguridad
Firma digital con certificado PKCS#12, core SIFEN como paquete privado en GitHub
Tiempo Real
Emisión síncrona individual y por lotes de hasta 50 documentos
Trazabilidad Completa
Cada documento y evento guarda XML, respuesta SIFEN, estado y metadata en la base de datos
Eventos SIFEN
Cancelación e inutilización de documentos con registro completo del XML y la respuesta
¿Qué es SIFEN?
SIFEN (Sistema Integrado de Facturación Electrónica Nacional) es el sistema oficial de la SET para la emisión de documentos electrónicos en Paraguay.
Documentos Soportados
| Tipo | Código | Descripción | Uso |
|---|---|---|---|
| Factura Electrónica | 1 | Documento de venta | Ventas de productos o servicios |
| Nota de Crédito | 5 | Anulación o devolución | Devoluciones, descuentos |
| Nota de Débito | 6 | Ajuste adicional | Intereses, gastos adicionales |
| Nota de Remisión | 7 | Traslado de mercadería | Movimiento de stock |
Componentes del Documento Electrónico
- XML: Documento estructurado según especificaciones SIFEN v150
- Firma Digital: Certificado digital válido (.pfx)
- CDC: Código de Control del Documento (44 dígitos único)
- QR: Código QR para validación pública
- Protocolo: Número de autorización de SIFEN
Endpoints de la API
Base URL: https://tu-dominio.com/invoicing
GET/companies
Obtiene la lista de empresas configuradas para facturación.
Respuesta:
[
{
"id": "abc-123-def",
"name": "Mi Empresa SRL",
"ruc": "80012345-6",
"business_name": "MI EMPRESA SOCIEDAD DE RESPONSABILIDAD LIMITADA"
}
]
POST/emit/invoice
Emite una factura electrónica y la envía a SIFEN.
Body (JSON):
{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"moneda": "PYG",
"indicadorPresencia": 1,
"cliente": {
"ruc": "80009735-1",
"razonSocial": "ANDE",
"tipoContribuyente": 2,
"tipoOperacion": 3,
"direccion": "Av. España",
"numeroCasa": "1234",
"email": "facturacion@ande.gov.py"
},
"items": [
{
"codigo": "PROD-001",
"descripcion": "Silla de Hierro",
"cantidad": 2,
"precioUnitario": 110000,
"ivaTipo": 10,
"unidadMedida": 77
},
{
"codigo": "PROD-002",
"descripcion": "Mesa de Madera",
"cantidad": 1,
"precioUnitario": 52500,
"ivaTipo": 5,
"unidadMedida": 77
}
],
"condicion": {
"tipo": 1,
"entregas": [
{
"tipo": 1,
"monto": 272500,
"moneda": "PYG"
}
]
}
}
Respuesta Exitosa:
{
"ns2:rRetEnviDe": {
"ns2:rProtDe": {
"ns2:dEstRes": "Aprobado",
"ns2:dProtAut": "12345678901234567890",
"ns2:gResProc": {
"ns2:dCodRes": "0260",
"ns2:dMsgRes": "Aprobado"
}
}
},
"cdc": "01800123456001001000104720241201000000011234567890",
"qr_url": "https://ekuatia.set.gov.py/consultas/qr?nVersion=150&Id=...",
"xml": "...",
"kude_pdf_base64": null,
"documento_id": "f3a2b1c0-1234-5678-abcd-ef0123456789"
}
- cdc: Código único del documento (guárdalo en tu base de datos)
- qr_url: URL del QR para validación pública
- xml: XML completo firmado (para imprimir o almacenar)
- documento_id: UUID del registro en la base de datos local
- dEstRes: Estado del documento ("Aprobado", "Rechazado")
POST/emit/credit-note
Emite una nota de crédito asociada a una factura.
Campos Adicionales Requeridos (además del body de factura):
{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"motivo": 1,
"documentoAsociado": {
"tipo": 1,
"cdc": "01800097351001001000000120260115191611126841"
},
"cliente": { ... },
"items": [ ... ],
"moneda": "PYG"
}
Motivos de Nota de Crédito:
| Código | Descripción |
|---|---|
| 1 | Devolución y anulación de factura |
| 2 | Devolución y anulación parcial |
| 3 | Descuento o bonificación |
| 4 | Ajuste de precio |
POST/emit/debit-note
Emite una nota de débito para ajustes adicionales.
Motivos de Nota de Débito:
| Código | Descripción |
|---|---|
| 1 | Interés por mora |
| 2 | Ajuste de precio |
| 3 | Gastos adicionales |
POST/emit/remission
Emite una nota de remisión para traslado de mercadería.
Ejemplo:
{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"moneda": "PYG",
"cliente": { ... },
"items": [
{
"codigo": "PROD-001",
"descripcion": "Silla de Oficina",
"cantidad": 5,
"unidadMedida": 77
}
],
"complementoRemision": {
"motivo": 1,
"responsableEmi": 1,
"tipoAccion": 1,
"fechaInicio": "2026-03-18",
"fechaFin": "2026-03-18",
"kilometros": 10,
"precioFlete": 0
}
}
POST/consult/ruc
Valida un RUC en el sistema SIFEN.
Body (JSON):
{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"ruc": "80009735-1"
}
Respuesta:
{
"ns2:rResEnviConsRUC": {
"ns2:xContRUC": {
"ns2:dRUC": "80009735-1",
"ns2:dRazSoc": "ADMINISTRACION NACIONAL DE ELECTRICIDAD",
"ns2:dNomFan": "ANDE",
"ns2:dEstRUC": "Activo"
}
}
}
POST/consult/document
Consulta el estado de un documento por su CDC.
Body (JSON):
{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"cdc": "01800097351001001000000120260115191611126841"
}
POST/emit/self-invoice
Emite una Autofactura Electrónica (iTiDE=4). Se usa cuando la empresa compra bienes o servicios a un proveedor que no es contribuyente (sin RUC). El campo cliente contiene los datos del vendedor/proveedor.
Body:
{
"company_id": "...",
"tipoTransaccion": 10,
"cliente": {
"razonSocial": "María González López",
"documentoTipo": 1,
"documentoNumero": "3456789",
"tipoContribuyente": 1,
"tipoOperacion": 2,
"direccion": "Compañía San Miguel",
"numeroCasa": "0"
},
"items": [...],
"condicion": { "tipo": 1 },
"moneda": "PYG"
}
POST/events/cancel
Cancela un documento electrónico emitido ante SIFEN. Registra el evento con XML firmado y respuesta SIFEN. Si el documento existe en la base de datos, su estado cambia a cancelado.
Body:
{
"company_id": "...",
"cdc": "01800123456001001000104720241201000000011234567890",
"motivo": "Error en datos del cliente"
}
Respuesta:
{
"rRetEnviEventoDe": { ... },
"evento_id": "uuid-del-evento-registrado"
}
POST/events/inutilizacion
Inutiliza un rango de números de documentos ante SIFEN (Evento tipo 2, Manual 150). Usar cuando se emitieron documentos con error y no fueron enviados a SIFEN, o para invalidar una secuencia de numeración.
Body:
{
"company_id": "...",
"tipoDocumento": 1,
"establecimiento": "001",
"punto": "001",
"nroDesde": 1,
"nroHasta": 3,
"motivo": "Documentos emitidos con error y no enviados a SIFEN",
"serie": null,
"timbradoNumero": null
}
Campos:
tipoDocumento— 1=Factura, 4=Autofactura, 5=NC, 6=ND, 7=NREnroDesde / nroHasta— rango de números a inutilizarserie— serie de 3 caracteres (opcional)timbradoNumero— usa el timbrado default si se omite
Respuesta:
{
"rRetEnviEventoDe": { ... },
"evento_id": "uuid-del-evento-registrado"
}
POST/kude
Genera el KuDE (Representación Gráfica del Documento Electrónico) en HTML a partir del XML firmado. El HTML puede renderizarse directamente en el navegador o convertirse a PDF. Incluye el logo de la empresa si está configurado en el admin.
Body:
{ "xml": "<?xml version=\"1.0\"...>" }
Respuesta:
HTML con el KuDE listo para imprimir (Content-Type: text/html).
Envío por Lotes (Batch)
SIFEN acepta hasta 50 documentos por lote. El flujo es asíncrono de 3 pasos. SIFEN tarda 5–10 minutos en procesar; no consultar el estado antes.
POST/batch/create
Crea un lote con hasta 50 documentos. Devuelve batch_id y estado pending.
{
"company_id": "...",
"documents": [ { ...doc1... }, { ...doc2... } ]
}
POST/batch/{batch_id}/process
Genera y firma todos los XMLs del lote, luego los envía a SIFEN. Estado pasa a sent y se obtiene el sifen_batch_number.
GET/batch/{batch_id}/status
Consulta el estado del lote en SIFEN y actualiza el estado de cada documento (approved / rejected).
GET/batch/{batch_id}
Detalle completo del lote con todos sus documentos.
GET/batch/list
Lista lotes con filtros opcionales: ?company_id=&status=&limit=
Consultas
Trazabilidad de Documentos
Cada operación queda registrada en la base de datos para auditoría y seguimiento completo.
DocumentoElectronico
Creado automáticamente en cada emisión individual (/emit/*). Guarda:
| Campo | Descripción |
|---|---|
cdc | Código de Control del Documento (44 chars) |
numero_doc | Número formateado EST-PTO-NRODOC (ej: 001-001-0000001) |
estado | pendiente → aprobado / rechazado / cancelado / error |
xml_generado | XML sin firmar generado por sifen-core |
xml_firmado | XML firmado con QR incrustado, listo para SIFEN |
payload_entrada | Request JSON original recibido por la API |
respuesta_sifen | Respuesta completa devuelta por SIFEN (JSON) |
error_mensaje | Detalle del error si el estado es error |
qr_url | URL del QR generado para el KuDE |
metadata | Timbrado, establecimiento, punto, ambiente (test/prod) |
El registro se crea antes de enviar a SIFEN. Si falla en cualquier etapa (generación, firma, envío), queda persistido con estado=error y el mensaje de excepción.
EventoElectronico
Creado en cada cancelación o inutilización. Guarda XML firmado, respuesta SIFEN, metadata del evento y FK al documento cancelado (si aplica).
Visualización en Admin Django
Todos los registros son visibles y filtrables desde /admin con badges de colores por estado, XMLs en secciones colapsables y links entre eventos y documentos.
Generación de XML SIFEN
La API genera automáticamente el XML según las especificaciones SIFEN v150.
Proceso de Generación
1. Validación
Valida todos los datos del request contra las reglas de SIFEN
2. Generación XML
Crea el XML estructurado con todos los campos requeridos
3. Firma Digital
Firma el XML con el certificado digital de la empresa
4. QR Code
Agrega el código QR al XML firmado
5. Envío a SIFEN
Envía el documento a SIFEN para validación
6. Respuesta
Retorna CDC, QR URL y XML completo
Ejemplo de XML Generado
<?xml version="1.0" encoding="UTF-8"?>
<rDE xmlns="http://ekuatia.set.gov.py/sifen/xsd">
<DE Id="01800123456001001000104720241201000000011234567890">
<dVerFor>150</dVerFor>
<gOpeDE>
<iTipEmi>1</iTipEmi>
<dDesTipEmi>Normal</dDesTipEmi>
<dCodSeg>669880626</dCodSeg>
</gOpeDE>
<gTimb>
<iTiDE>1</iTiDE>
<dDesTiDE>Factura electrónica</dDesTiDE>
<dNumTim>03970287</dNumTim>
<dEst>001</dEst>
<dPunExp>001</dPunExp>
<dNumDoc>0000001</dNumDoc>
<dFeIniT>2024-01-01</dFeIniT>
</gTimb>
<gDatGralOpe>
<dFeEmiDE>2024-12-01T10:30:00</dFeEmiDE>
</gDatGralOpe>
<gEmis>
<dRucEm>80012345-6</dRucEm>
<dRazSocEm>MI EMPRESA SRL</dRazSocEm>
...
</gEmis>
<gDatRec>
<dRucRec>80009735-1</dRucRec>
<dRazSocRec>ANDE</dRazSocRec>
...
</gDatRec>
<gDtipDE>
<gCamFE>
<gCamItem>
<dCodInt>PROD-001</dCodInt>
<dDesProSer>Silla de Oficina</dDesProSer>
<dCantProSer>1.0</dCantProSer>
<dPUniProSer>150000</dPUniProSer>
...
</gCamItem>
</gCamFE>
</gDtipDE>
</DE>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...firma digital...
</Signature>
<dCarQR>https://ekuatia.set.gov.py/consultas/qr?...</dCarQR>
</rDE>
Campos Automáticos
La API genera automáticamente los siguientes campos:
| Campo | Descripción |
|---|---|
| CDC | Código de Control del Documento (44 dígitos único) |
| Código de Seguridad | Número aleatorio de 9 dígitos |
| Número de Documento | Secuencial automático si no se especifica |
| Fecha de Emisión | Fecha/hora actual si no se especifica |
| Totales | Cálculo automático de subtotales, IVA y total |
Ejemplos de Uso
Python
import requests
url = "https://api.ejemplo.com/api/invoicing/emit/invoice"
headers = {
"Authorization": "Bearer <tu_token_jwt>",
"Content-Type": "application/json"
}
factura = {
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"moneda": "PYG",
"indicadorPresencia": 1,
"cliente": {
"ruc": "80009735-1",
"razonSocial": "ANDE",
"tipoContribuyente": 2,
"tipoOperacion": 3,
"direccion": "Av. España",
"numeroCasa": "1234",
"email": "facturacion@ande.gov.py"
},
"items": [{
"codigo": "PROD-001",
"descripcion": "Silla de Hierro",
"cantidad": 2,
"precioUnitario": 110000,
"unidadMedida": 77,
"ivaTipo": 10
}],
"condicion": {
"tipo": 1,
"entregas": [{"tipo": 1, "monto": 220000, "moneda": "PYG"}]
}
}
response = requests.post(url, headers=headers, json=factura)
result = response.json()
print(f"CDC: {result['cdc']}")
print(f"QR: {result['qr_url']}")
print(f"documento_id: {result['documento_id']}")
cURL
curl -X POST "https://api.ejemplo.com/api/invoicing/emit/invoice" \
-H "Authorization: Bearer <tu_token_jwt>" \
-H "Content-Type: application/json" \
-d '{
"company_id": "a7e9f084-d15c-4a8f-8b3d-0a7d5f24734a",
"moneda": "PYG",
"indicadorPresencia": 1,
"cliente": {
"ruc": "80009735-1",
"razonSocial": "ANDE",
"tipoContribuyente": 2,
"tipoOperacion": 3,
"direccion": "Av. España",
"numeroCasa": "1234",
"email": "facturacion@ande.gov.py"
},
"items": [{
"codigo": "PROD-001",
"descripcion": "Silla de Hierro",
"cantidad": 2,
"precioUnitario": 110000,
"unidadMedida": 77,
"ivaTipo": 10
}],
"condicion": {
"tipo": 1,
"entregas": [{"tipo": 1, "monto": 220000, "moneda": "PYG"}]
}
}'
Códigos de Error
Errores Comunes
| Error | Causa | Solución |
|---|---|---|
| Empresa no tiene certificado activo | Certificado digital no configurado | Cargar certificado .pfx válido |
| RUC inválido | Formato incorrecto de RUC | Usar formato: 80012345-6 (con DV) |
| Timbrado vencido | Timbrado fuera de vigencia | Renovar timbrado en la SET |
| Items sin precio | Falta precioUnitario o ivaTipo | Agregar precio e IVA a todos los items |
| Documento rechazado por SIFEN | Datos inválidos según SIFEN | Revisar mensaje de error de SIFEN |
Códigos de Respuesta SIFEN
| Código | Estado | Descripción |
|---|---|---|
| 0260 | Aprobado | Documento aprobado correctamente |
| 0261 | Pendiente | En proceso de validación |
| 0300-0399 | Rechazado | Error en datos del documento |
Esquema de Datos Completo
Cliente (ClientSchema)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
ruc |
string | Requerido | RUC con DV (ej: 80012345-6) |
razonSocial |
string | Requerido | Razón social o nombre completo |
direccion |
string | Requerido | Dirección del cliente |
numeroCasa |
string | Requerido | Número de casa |
tipoContribuyente |
int | Requerido | 1: Físico, 2: Jurídico |
tipoOperacion |
int | Requerido | 1: B2B, 2: B2C, 3: B2G |
email |
string | Requerido | Email del cliente |
documentoTipo |
int | Requerido | Tipo de documento (si no tiene RUC) |
documentoNumero |
string | Requerido | Número de documento (si no tiene RUC) |
Item (ItemSchema)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
codigo |
string | Requerido | Código del producto/servicio |
descripcion |
string | Requerido | Descripción del item |
cantidad |
float | Requerido | Cantidad |
precioUnitario |
float | Requerido* | Precio unitario |
ivaTipo |
int | Requerido* | 10, 5, o 0 (exento) |
unidadMedida |
int | Opcional | Código de unidad (default: 77) |
descuento |
float | Opcional | Descuento unitario |
* No requerido para notas de remisión
Tipos de IVA
| Código | Descripción | Uso |
|---|---|---|
| 10 | IVA 10% | Productos/servicios gravados al 10% |
| 5 | IVA 5% | Productos/servicios gravados al 5% |
| 0 | Exento | Productos/servicios exentos de IVA |