Saltar al contenido principal

SIFEN — KuDE PDF (Documento Complementario)

Fecha: 2026-04-14 Sprint: 4.2 Endpoint: GET /api/sifen/dtes/{id}/kude Servicio: app/Domains/Sifen/Services/Kude/KudeGeneratorService.php Template: 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:

HeaderValor
Content-Typeapplication/pdf
Content-Dispositioninline; filename="KuDE_{CDC}.pdf"

Codigos:

  • 200 — PDF generado exitosamente
  • 404 — DTE no encontrado
  • 401 / 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)

CodigoDescripcionPrecio Unit.Cant.ExentasGrav. 5%Grav. 10%
Codigo del productoNombre del producto/servicioPrecio sin IVACantidadImporte si afecta exentoImporte si afecta 5%Importe si afecta 10%

Como se decide la columna:

  1. Si afectacion_iva = 3 o tasa_iva = 0 → Exentas
  2. Si afectacion_iva = 2 o tasa_iva = 5 → Grav. 5%
  3. 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) o https://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.

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 aproxQue controla
@page { margin: 15mm 10mm 10mm 10mm }Margenes de impresion (compatible con cualquier impresora)
.container { width: 700px }Ancho total de la pagina
.header-tableCabecera (logo + empresa + RUC)
.details-tableDatos del cliente
.items-tableTabla de items
Estilos inline en <table> (linea ~270)Tabla de totales (SUBTOTAL, TOTAL OP, etc.)
.qr-tableQR + CDC + mensaje legal
<table> finalFooter 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:

BordeMargenRazon
Superior15mmExtra para impresoras con tope alto
Izquierdo10mmEstandar
Derecho10mmEstandar
Inferior10mmEstandar

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-dompdf v3) — Conversion HTML a PDF.
  • php-qrcode (chillerlan/php-qrcode v6) — Generacion QR local sin APIs externas.

Ambas en composer.json.


Servicio interno

KudeGeneratorService::generate(SifenDte $dte): string

Pipeline:

  1. Cargar relaciones del DTE (items, emitter, eventos).
  2. Generar QR base64 con la URL de consulta SIFEN.
  3. Cargar logo del emisor base64 (si tiene).
  4. Cargar logo branding Onnix base64.
  5. Detectar si el DTE esta cancelado (para el watermark).
  6. Renderizar template Blade sifen.kude.factura con todos los datos.
  7. Generar PDF con DomPDF (A4, portrait).
  8. 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:

EstadoWatermarkNotas
draftNingunoAun sin firmar
signedNingunoFirmado pero no enviado
sentNingunoEnviado, esperando respuesta
approvedNingunoAprobado por SIFEN — listo para imprimir
rejectedNingunoRechazado por SIFEN
cancelledCANCELADO rojo en diagonalCancelado via evento

Archivos

ArchivoDescripcion
app/Domains/Sifen/Services/Kude/KudeGeneratorService.phpServicio principal de generacion
resources/views/sifen/kude/factura.blade.phpTemplate HTML/CSS
app/Http/Controllers/Api/SifenController.php (downloadKude())Endpoint API
database/migrations/*_add_logo_path_to_sifen_emitters.phpCampo logo_path en BD
storage/app/private/sifen/logos/Logos por emisor
storage/app/private/sifen/branding/onnix-powered-by.pngLogo Onnix fijo

Referencias