SIFEN — KuDE PDF (Documento Complementario)
Fecha: 2026-04-14 Sprint: 4.2 Endpoint:
GET /api/sifen/dtes/{id}/kudeServicio:app/Domains/Sifen/Services/Kude/KudeGeneratorService.phpTemplate:resources/views/sifen/kude/factura.blade.php
Que es el KuDE
KuDE = Documento Complementario del Documento Electronico. Es la representacion grafica en PDF de un DTE (factura electronica). El DTE real es el XML firmado, pero el cliente recibe el KuDE PDF como comprobante visual.
Caracteristicas:
- No tiene valor fiscal por si solo — es una representacion del XML firmado.
- Incluye QR que apunta a la consulta oficial de SIFEN (e-kuatia).
- Lleva el CDC completo de 44 digitos para verificacion.
- Si el DTE fue cancelado, muestra un watermark "CANCELADO" semitransparente.
Endpoint
GET /api/sifen/dtes/{id}/kude
GET /api/sifen/dtes/96/kude
Authorization: Bearer <token>
Accept: application/pdf
Permiso: sifen:read
Respuesta:
| Header | Valor |
|---|---|
Content-Type | application/pdf |
Content-Disposition | inline; filename="KuDE_{CDC}.pdf" |
Codigos:
200— PDF generado exitosamente404— DTE no encontrado401/403— Sin auth o sin permiso
Ejemplo curl
curl -O -J http://localhost:8000/api/sifen/dtes/96/kude \
-H "Authorization: Bearer $TOKEN"
# -> KuDE_01801260060001001000100122026041017345886385.pdf
Ejemplo con tinker (sin pasar por la API)
php artisan tinker --execute='file_put_contents("/tmp/kude.pdf", app(\App\Domains\Sifen\Services\Kude\KudeGeneratorService::class)->generate(\App\Domains\Sifen\Models\SifenDte::find(97)));'
Estructura visual del KuDE
┌────────────────────────────────────────────────────┐
│ [LOGO] KuDE de FACTURA ELECTRONICA RUC: ... │
│ ONNIX TECNOLOGIA Y SERV. S.A. Timbrado: │
│ Direccion, telefono, email Vigencia:│
│ Factura: │
├────────────────────────────────────────────────────┤
│ Fecha emision: ... Cond. venta: Contado │
│ RUC/CI: ... Razon social: ... │
│ Moneda: PYG Direccion: ... │
├────────────────────────────────────────────────────┤
│ Codigo │ Descripcion │ Precio │ Cant │ Ex │ 5% │ 10%│
│ SRV-001│ ... │ X.XXX │ 1 │ - │ - │ X │
│ ... │ │ │ │ │ │ │
├────────────────────────────────────────────────────┤
│ SUBTOTAL: 900.000 1.550.000 6.050M│
│ TOTAL DE LA OPERACION: 8.500.000 │
│ TOTAL EN GUARANIES: 8.500.000 │
│ LIQUIDACION IVA: Exenta IVA 5% IVA 10% │
│ - 73.810 550.000 │
│ TOTAL IVA: 623.810 │
├────────────────────────────────────────────────────┤
│ [QR] Consulte la validez en: │
│ https://ekuatia.set.gov.py/consultas │
│ {CDC 44 digitos} │
│ ESTE DOCUMENTO ES UNA REPRESENTACION... │
└────────────────────────────────────────────────────┘
Documento generado por OnnixConnect Servicio proveido por [ONNIX]
Que se incluye en el PDF
Cabecera (3 columnas)
- Logo del emisor (desde
sifen_emitters.logo_path) - Datos de la empresa (razon social, actividad economica, direccion, telefono, email)
- Datos tributarios (RUC + DV, timbrado, inicio vigencia, numero de factura)
Datos del cliente
- Fecha de emision, condicion de venta, moneda
- RUC/CI del cliente, razon social, direccion, email
Tabla de items (10 filas minimo)
| Codigo | Descripcion | Precio Unit. | Cant. | Exentas | Grav. 5% | Grav. 10% |
|---|---|---|---|---|---|---|
| Codigo del producto | Nombre del producto/servicio | Precio sin IVA | Cantidad | Importe si afecta exento | Importe si afecta 5% | Importe si afecta 10% |
Como se decide la columna:
- Si
afectacion_iva = 3otasa_iva = 0→ Exentas - Si
afectacion_iva = 2otasa_iva = 5→ Grav. 5% - En otro caso → Grav. 10%
Totales
- SUBTOTAL por tipo IVA (suma de cada columna)
- TOTAL DE LA OPERACION (suma final)
- TOTAL EN GUARANIES (en moneda local)
- LIQUIDACION IVA desglosada (Exenta, IVA 5%, IVA 10%)
- TOTAL IVA (suma de los IVAs)
QR + CDC
- QR generado localmente con
chillerlan/php-qrcode v6(sin APIs externas) - URL del QR:
https://ekuatia.set.gov.py/consultas-test/qr?...(test) ohttps://ekuatia.set.gov.py/consultas/qr?...(prod) - CDC de 44 digitos en formato monoespaciado
Pie de pagina
- "Documento generado por OnnixConnect" (izquierda)
- "Servicio proveido por ONNIX" (derecha) con logo de Onnix
Watermark CANCELADO
Si el DTE esta en estado cancelled, se muestra un texto rojo semitransparente en diagonal:
CANCELADO
CANCELADO
CANCELADO
Implementacion: CSS position: fixed con transform: rotate(-45deg) y color: rgba(255, 0, 0, 0.12).
Probar con: cualquier DTE en estado cancelled (ej. DTE 96).
Personalizacion por emisor
Logo del emisor
Cada emisor tiene su propio logo en sifen_emitters.logo_path:
storage/app/private/sifen/logos/
├── emitter_1.png ← Logo del emisor 1
├── emitter_2.png ← Logo del emisor 2
└── ...
Subir un logo via API:
curl -X POST http://localhost:8000/api/sifen/emitters/1/logo \
-H "Authorization: Bearer $TOKEN" \
-F "logo=@/ruta/al/logo.png"
Acepta PNG, JPG, JPEG, SVG. Maximo 2 MB.
Logo de branding Onnix (footer)
Es fijo para todas las facturas de todos los emisores:
storage/app/private/sifen/branding/onnix-powered-by.png
Ya viene con fondo transparente (procesado con Python para eliminar el blanco).
Como modificar el diseño
El template es HTML/CSS estandar. Esta en:
resources/views/sifen/kude/factura.blade.php
Secciones del template
| Linea aprox | Que controla |
|---|---|
@page { margin: 15mm 10mm 10mm 10mm } | Margenes de impresion (compatible con cualquier impresora) |
.container { width: 700px } | Ancho total de la pagina |
.header-table | Cabecera (logo + empresa + RUC) |
.details-table | Datos del cliente |
.items-table | Tabla de items |
Estilos inline en <table> (linea ~270) | Tabla de totales (SUBTOTAL, TOTAL OP, etc.) |
.qr-table | QR + CDC + mensaje legal |
<table> final | Footer con "Documento generado por..." y branding Onnix |
Cambiar margenes de impresion
@page {
margin: 15mm 10mm 10mm 10mm;
/* top, right, bottom, left */
}
Cambiar el ancho de la pagina
.container {
width: 700px; /* Cambiar a 600px, 800px, etc. */
}
Cambiar tamaño del QR
.qr-cell-left img {
width: 150px;
height: 150px;
}
Cambiar colores del watermark CANCELADO
.watermark {
color: rgba(255, 0, 0, 0.12); /* rojo 12% opacidad */
font-size: 110px;
transform: rotate(-45deg);
}
Recompilar despues de cambios
# Generar un PDF de prueba
php artisan tinker --execute='file_put_contents("/tmp/kude.pdf", app(\App\Domains\Sifen\Services\Kude\KudeGeneratorService::class)->generate(\App\Domains\Sifen\Models\SifenDte::find(97)));'
# Copiar a Windows para verlo
cp /tmp/kude.pdf "/mnt/c/Users/nemartinez/Downloads/kude.pdf"
No requiere php artisan view:clear — Blade detecta cambios automaticamente.
Margenes para impresion
El KuDE usa margenes seguros para cualquier impresora:
| Borde | Margen | Razon |
|---|---|---|
| Superior | 15mm | Extra para impresoras con tope alto |
| Izquierdo | 10mm | Estandar |
| Derecho | 10mm | Estandar |
| Inferior | 10mm | Estandar |
La mayoria de impresoras tienen un area no imprimible de 5-7mm en los bordes. Con 10mm de margen estamos dentro del area segura.
Dependencias
- DomPDF (
barryvdh/laravel-dompdfv3) — Conversion HTML a PDF. - php-qrcode (
chillerlan/php-qrcodev6) — Generacion QR local sin APIs externas.
Ambas en composer.json.
Servicio interno
KudeGeneratorService::generate(SifenDte $dte): string
Pipeline:
- Cargar relaciones del DTE (
items,emitter,eventos). - Generar QR base64 con la URL de consulta SIFEN.
- Cargar logo del emisor base64 (si tiene).
- Cargar logo branding Onnix base64.
- Detectar si el DTE esta cancelado (para el watermark).
- Renderizar template Blade
sifen.kude.facturacon todos los datos. - Generar PDF con DomPDF (
A4,portrait). - Retornar el binario del PDF.
Tiempo tipico: 200-400ms (incluyendo lectura del logo y generacion del QR).
Codigos de estado del DTE en el KuDE
El KuDE muestra el estado actual del DTE:
| Estado | Watermark | Notas |
|---|---|---|
draft | Ninguno | Aun sin firmar |
signed | Ninguno | Firmado pero no enviado |
sent | Ninguno | Enviado, esperando respuesta |
approved | Ninguno | Aprobado por SIFEN — listo para imprimir |
rejected | Ninguno | Rechazado por SIFEN |
cancelled | CANCELADO rojo en diagonal | Cancelado via evento |
Archivos
| Archivo | Descripcion |
|---|---|
app/Domains/Sifen/Services/Kude/KudeGeneratorService.php | Servicio principal de generacion |
resources/views/sifen/kude/factura.blade.php | Template HTML/CSS |
app/Http/Controllers/Api/SifenController.php (downloadKude()) | Endpoint API |
database/migrations/*_add_logo_path_to_sifen_emitters.php | Campo logo_path en BD |
storage/app/private/sifen/logos/ | Logos por emisor |
storage/app/private/sifen/branding/onnix-powered-by.png | Logo Onnix fijo |
Referencias
docs/ROADMAP_EJECUCION_OC.md— Tarea 4.2- DomPDF docs
- chillerlan/php-qrcode docs