Saltar al contenido principal

SIFEN TYPES BIBLE

Contrato de Verdad Java → PHP 8.1+ / Laravel 12

Fuente: Análisis exhaustivo del ecosistema Java SIFEN Módulos escaneados: rshk-jsifen-maven, onnix-sifen-lib, onnix-sifen-driver SDK Version: 0.2.4 | SIFEN Version: 150 Namespace SET: http://ekuatia.set.gov.py/sifen/xsd Generado: 2026-03-03


ÍNDICE

  1. Catálogo de Enumeraciones
  2. Mapa de Estructuras POJO → DTO
  3. Reglas de Validación Criptográfica
  4. Guía de Implementación Laravel 12

1. CATÁLOGO DE ENUMERACIONES

Convención de nomenclatura Java SIFEN:

  • Prefijo Ti = Tipo Individual (int-backed, short val)
  • Prefijo Tc = Tipo Catálogo (puede ser string o int)
  • Prefijo Td = Tipo de Datos (int-backed)
  • Prefijo TT = Tipo de Tabla (int-backed)
  • CMondT, PaisType = string-backed (código ISO como nombre del enum)

GRUPO A: TIPOS DE DOCUMENTO

A.1 — TTiDE · Tipo de Documento Electrónico

Campo XML: iTiDE / dDesTiDE · Paquete: com.roshka.sifen.core.types

Constante Javaval (short)Descripción SIFEN
FACTURA_ELECTRONICA1Factura electrónica
FACTURA_ELECTRONICA_EXPORTACION2Factura electrónica de exportación
FACTURA_ELECTRONICA_IMPORTACION3Factura electrónica de importación
AUTOFACTURA_ELECTRONICA4Autofactura electrónica
NOTA_DE_CREDITO_ELECTRONICA5Nota de crédito electrónica
NOTA_DE_DEBITO_ELECTRONICA6Nota de débito electrónica
NOTA_DE_REMISION_ELECTRONICA7Nota de remisión electrónica
COMPROBANTE_RETENCION_ELECTRONICO8Comprobante de retención electrónico
<?php // app/Domains/Sifen/Enums/TipoDocumentoElectronico.php
namespace App\Domains\Sifen\Enums;

enum TipoDocumentoElectronico: int
{
case FacturaElectronica = 1;
case FacturaElectronicaExportacion = 2;
case FacturaElectronicaImportacion = 3;
case AutofacturaElectronica = 4;
case NotaDeCreditoElectronica = 5;
case NotaDeDebitoElectronica = 6;
case NotaDeRemisionElectronica = 7;
case ComprobanteRetencionElectronico = 8;

public function descripcion(): string
{
return match($this) {
self::FacturaElectronica => 'Factura electrónica',
self::FacturaElectronicaExportacion => 'Factura electrónica de exportación',
self::FacturaElectronicaImportacion => 'Factura electrónica de importación',
self::AutofacturaElectronica => 'Autofactura electrónica',
self::NotaDeCreditoElectronica => 'Nota de crédito electrónica',
self::NotaDeDebitoElectronica => 'Nota de débito electrónica',
self::NotaDeRemisionElectronica => 'Nota de remisión electrónica',
self::ComprobanteRetencionElectronico => 'Comprobante de retención electrónico',
};
}
}

A.2 — TiTIpoDoc · Tipo de Documento (para Doc. Asociado impreso)

Campo XML: iTIpoDoc · Nota: Este enum describe tipos de documentos físicos asociados.

Constante JavavalDescripción
FACTURA1Factura
NOTA_DE_CREDITO2Nota de crédito
NOTA_DE_DEBITO3Nota de débito
NOTA_DE_REMISION4Nota de remisión
COMPROBANTE_DE_RETENCION5Comprobante de retención
<?php // app/Domains/Sifen/Enums/TipoDocumentoAsociado.php
namespace App\Domains\Sifen\Enums;

enum TipoDocumentoAsociado: int
{
case Factura = 1;
case NotaDeCredito = 2;
case NotaDeDebito = 3;
case NotaDeRemision = 4;
case ComprobanteDeRetencion = 5;

public function descripcion(): string
{
return match($this) {
self::Factura => 'Factura',
self::NotaDeCredito => 'Nota de crédito',
self::NotaDeDebito => 'Nota de débito',
self::NotaDeRemision => 'Nota de remisión',
self::ComprobanteDeRetencion => 'Comprobante de retención',
};
}
}

A.3 — TiTipDocAso · Tipo de Documento Asociado (electrónico/impreso)

Campo XML: iTipDocAso

Constante JavavalDescripción
ELECTRONICO1Electrónico
IMPRESO2Impreso
CONSTANCIA_ELECTRONICA3Constancia Electrónica
<?php // app/Domains/Sifen/Enums/TipoDocumentoAsociadoFormato.php
namespace App\Domains\Sifen\Enums;

enum TipoDocumentoAsociadoFormato: int
{
case Electronico = 1;
case Impreso = 2;
case ConstanciaElectronica = 3;
}

A.4 — TiTipDocRec · Tipo de Documento del Receptor

Campo XML: iTipDocRec

Constante JavavalDescripción
CEDULA_PARAGUAYA1Cédula paraguaya
PASAPORTE2Pasaporte
CEDULA_EXTRANJERA3Cédula extranjera
CARNET_DE_RESIDENCIA4Carnet de residencia
INNOMINADO5Innominado
TARJETA_DIPLOMATICA6Tarjeta Diplomática de exoneración fiscal
OTRO9Otro
<?php // app/Domains/Sifen/Enums/TipoDocumentoReceptor.php
namespace App\Domains\Sifen\Enums;

enum TipoDocumentoReceptor: int
{
case CedulaParaguaya = 1;
case Pasaporte = 2;
case CedulaExtranjera = 3;
case CarnetDeResidencia = 4;
case Innominado = 5;
case TarjetaDiplomatica = 6;
case Otro = 9;
}

A.5 — TiTipDoc · Tipo de Documento del Contribuyente (Emisor)

Campo XML: iTipDoc (en gDatRec)

Constante JavavalDescripción
CEDULA_PARAGUAYA1Cédula paraguaya
PASAPORTE2Pasaporte
CEDULA_EXTRANJERA3Cédula extranjera
CARNET_DE_RESIDENCIA4Carnet de residencia
<?php // app/Domains/Sifen/Enums/TipoDocumentoContribuyente.php
namespace App\Domains\Sifen\Enums;

enum TipoDocumentoContribuyente: int
{
case CedulaParaguaya = 1;
case Pasaporte = 2;
case CedulaExtranjera = 3;
case CarnetDeResidencia = 4;
}

A.6 — TiTipIDRespDE · Tipo ID del Responsable del DE

Campo XML: iTipIDRespDE

Constante JavavalDescripción
CEDULA_PARAGUAYA1Cédula paraguaya
PASAPORTE2Pasaporte
CEDULA_EXTRANJERA3Cédula extranjera
CARNET_DE_RESIDENCIA4Carnet de residencia
OTRO9Otro
<?php // app/Domains/Sifen/Enums/TipoIdResponsableDE.php
namespace App\Domains\Sifen\Enums;

enum TipoIdResponsableDE: int
{
case CedulaParaguaya = 1;
case Pasaporte = 2;
case CedulaExtranjera = 3;
case CarnetDeResidencia = 4;
case Otro = 9;
}

GRUPO B: OPERACIÓN Y TRANSACCIÓN

B.1 — TTipEmi · Tipo de Emisión

Campo XML: iTipEmi / dDesTipEmi · Usado en TgOpeDE

Constante JavavalDescripción
NORMAL1Normal
CONTINGENCIA2Contingencia
<?php // app/Domains/Sifen/Enums/TipoEmision.php
namespace App\Domains\Sifen\Enums;

enum TipoEmision: int
{
case Normal = 1;
case Contingencia = 2;
}

B.2 — TiTiOpe · Tipo de Operación (B2B/B2C/B2G/B2F)

Campo XML: iTiOpe

Constante JavavalDescripción
B2B1Business To Business
B2C2Business To Consumer
B2G3Business To Government
B2F4Business To Freelancer
<?php // app/Domains/Sifen/Enums/TipoOperacion.php
namespace App\Domains\Sifen\Enums;

enum TipoOperacion: int
{
case B2B = 1;
case B2C = 2;
case B2G = 3;
case B2F = 4;

public function descripcion(): string
{
return match($this) {
self::B2B => 'Business To Business',
self::B2C => 'Business To Consumer',
self::B2G => 'Business To Government',
self::B2F => 'Business To Freelancer',
};
}
}

B.3 — TiCondOpe · Condición de la Operación

Campo XML: iCondOpe · Usado en TgCamCond

Constante JavavalDescripción
CONTADO1Contado
CREDITO2Crédito
<?php // app/Domains/Sifen/Enums/CondicionOperacion.php
namespace App\Domains\Sifen\Enums;

enum CondicionOperacion: int
{
case Contado = 1;
case Credito = 2;
}

B.4 — TTipTra · Tipo de Transacción

Campo XML: iTipTra / dDesTipTra

Constante JavavalDescripción
VENTA_MERCADERIA1Venta de mercadería
PRESTACION_SERVICIOS2Prestación de servicios
MIXTO3Mixto (Venta de mercadería y servicios)
VENTA_ACTIVO_FIJO4Venta de activo fijo
VENTA_DIVISAS5Venta de divisas
COMPRA_DIVISAS6Compra de divisas
PROMOCION_O_MUESTRAS7Promoción o entrega de muestras
DONACION8Donación
ANTICIPO9Anticipo
COMPRA_PRODUCTOS10Compra de productos
COMPRA_SERVICIOS11Compra de servicios
VENTA_CREDITO_FISCAL12Venta de crédito fiscal
MUESTRAS_MEDICAS13Muestras médicas (Art. 3 RG 24/2014)
<?php // app/Domains/Sifen/Enums/TipoTransaccion.php
namespace App\Domains\Sifen\Enums;

enum TipoTransaccion: int
{
case VentaMercaderia = 1;
case PrestacionServicios = 2;
case Mixto = 3;
case VentaActivoFijo = 4;
case VentaDivisas = 5;
case CompraDivisas = 6;
case PromocionOMuestras = 7;
case Donacion = 8;
case Anticipo = 9;
case CompraProductos = 10;
case CompraServicios = 11;
case VentaCreditoFiscal = 12;
case MuestrasMedicas = 13;
}

B.5 — TTipReg · Tipo de Régimen

Campo XML: iTipReg

Constante JavavalDescripción
REGIMEN_TURISMO1Régimen de Turismo
IMPORTADOR2Importador
EXPORTADOR3Exportador
MAQUILA4Maquila
LEY_60_905Ley Nº 60/90
REGIMEN_PEQUENO_PRODUCTOR6Régimen del Pequeño Productor
REGIMEN_MEDIANO_PRODUCTOR7Régimen del Mediano Productor
REGIMEN_CONTABLE8Régimen Contable
<?php // app/Domains/Sifen/Enums/TipoRegimen.php
namespace App\Domains\Sifen\Enums;

enum TipoRegimen: int
{
case RegimenTurismo = 1;
case Importador = 2;
case Exportador = 3;
case Maquila = 4;
case Ley6090 = 5;
case RegimenPequenoProductor = 6;
case RegimenMedianoProductor = 7;
case RegimenContable = 8;
}

B.6 — TiMotEmi · Motivo de Emisión (Nota de Crédito/Débito)

Campo XML: iMotEmi · Usado en TgCamNCDE

Constante JavavalDescripción
DEVOLUCION_Y_AJUSTES_DE_PRECIOS1Devolución y Ajuste de precios
DEVOLUCION2Devolución
DESCUENTO3Descuento
BONIFICACION4Bonificación
CREDITO_INCOBRABLE5Crédito incobrable
RECUPERO_DE_COSTO6Recupero de costo
RECUPERO_DE_GASTO7Recupero de gasto
AJUSTE_DE_PRECIO8Ajuste de precio
<?php // app/Domains/Sifen/Enums/MotivoEmision.php
namespace App\Domains\Sifen\Enums;

enum MotivoEmision: int
{
case DevolucionYAjusteDePrecios = 1;
case Devolucion = 2;
case Descuento = 3;
case Bonificacion = 4;
case CreditoIncobrable = 5;
case RecuperoDeCosto = 6;
case RecuperoDeGasto = 7;
case AjusteDePrecios = 8;
}

B.7 — TiNatRec · Naturaleza del Receptor

Campo XML: iNatRec

Constante JavavalDescripción
CONTRIBUYENTE1Contribuyente
NO_CONTRIBUYENTE2No Contribuyente
<?php // app/Domains/Sifen/Enums/NaturalezaReceptor.php
namespace App\Domains\Sifen\Enums;

enum NaturalezaReceptor: int
{
case Contribuyente = 1;
case NoContribuyente = 2;
}

B.8 — TiNatVen · Naturaleza del Vendedor (Autofactura)

Campo XML: iNatVen

Constante JavavalDescripción
NO_CONTRIBUYENTE1No contribuyente
EXTRANJERO2Extranjero
<?php // app/Domains/Sifen/Enums/NaturalezaVendedor.php
namespace App\Domains\Sifen\Enums;

enum NaturalezaVendedor: int
{
case NoContribuyente = 1;
case Extranjero = 2;
}

B.9 — TiTipCont · Tipo de Contribuyente

Campo XML: iTipCont

Constante JavavalDescripción
PERSONA_FISICA1Persona Física
PERSONA_JURIDICA2Persona Jurídica
<?php // app/Domains/Sifen/Enums/TipoContribuyente.php
namespace App\Domains\Sifen\Enums;

enum TipoContribuyente: int
{
case PersonaFisica = 1;
case PersonaJuridica = 2;
}

GRUPO C: IMPUESTOS Y IVA

C.1 — TTImp · Tipo de Impuesto

Campo XML: iTImp / dDesTImp

Constante JavavalDescripción
IVA1IVA
ISC2ISC
RENTA3Renta
NINGUNO4Ninguno
IVA_RENTA5IVA - Renta
<?php // app/Domains/Sifen/Enums/TipoImpuesto.php
namespace App\Domains\Sifen\Enums;

enum TipoImpuesto: int
{
case Iva = 1;
case Isc = 2;
case Renta = 3;
case Ninguno = 4;
case IvaRenta = 5;
}

C.2 — TiAfecIVA · Afectación Tributaria del IVA

Campo XML: iAfecIVA · Usado en TgCamIVA (por ítem)

Constante JavavalDescripción
GRAVADO1Gravado IVA
EXONERADO2Exonerado (Art. 83- Ley 125/91)
EXENTO3Exento
GRAVADO_PARCIAL4Gravado parcial (Grav- Exento)
<?php // app/Domains/Sifen/Enums/AfectacionIVA.php
namespace App\Domains\Sifen\Enums;

enum AfectacionIVA: int
{
case Gravado = 1;
case Exonerado = 2;
case Exento = 3;
case GravadoParcial = 4;

public function descripcion(): string
{
return match($this) {
self::Gravado => 'Gravado IVA',
self::Exonerado => 'Exonerado (Art. 83- Ley 125/91)',
self::Exento => 'Exento',
self::GravadoParcial => 'Gravado parcial (Grav- Exento)',
};
}
}

GRUPO D: CONDICIONES DE PAGO

D.1 — TiTiPago · Tipo de Pago

Campo XML: iTiPago · Usado en TgPaConEIni

Constante JavavalDescripción
EFECTIVO1Efectivo
CHEQUE2Cheque
TARJETA_DE_CREDITO3Tarjeta de crédito
TARJETA_DE_DEBITO4Tarjeta de débito
TRANSFERENCIA5Transferencia
GIRO6Giro
BILLETERA_ELECTRONICA7Billetera electrónica
TARJETA_EMPRESARIAL8Tarjeta empresarial
VALE9Vale
RETENCION10Retención
PAGO_POR_ANTICIPO11Pago por anticipo
VALOR_FISCAL12Valor fiscal
VALOR_COMERCIAL13Valor comercial
COMPENSACION14Compensación
PERMUTA15Permuta
PAGO_BANCARIO16Pago bancario
PAGO_MOVIL17Pago Móvil
DONACION18Donación
PROMOCION19Promoción
CONSUMO_INTERNO20Consumo Interno
PAGO_ELECTRONICO21Pago Electrónico
OTRO99Otro
<?php // app/Domains/Sifen/Enums/TipoPago.php
namespace App\Domains\Sifen\Enums;

enum TipoPago: int
{
case Efectivo = 1;
case Cheque = 2;
case TarjetaDeCredito = 3;
case TarjetaDeDebito = 4;
case Transferencia = 5;
case Giro = 6;
case BilleteraElectronica = 7;
case TarjetaEmpresarial = 8;
case Vale = 9;
case Retencion = 10;
case PagoPorAnticipo = 11;
case ValorFiscal = 12;
case ValorComercial = 13;
case Compensacion = 14;
case Permuta = 15;
case PagoBancario = 16;
case PagoMovil = 17;
case Donacion = 18;
case Promocion = 19;
case ConsumoInterno = 20;
case PagoElectronico = 21;
case Otro = 99;
}

D.2 — TiCondCred · Condición del Crédito

Campo XML: iCondCred · Usado en TgPagCred

Constante JavavalDescripción
PLAZO1Plazo
CUOTA2Cuota
<?php // app/Domains/Sifen/Enums/CondicionCredito.php
namespace App\Domains\Sifen\Enums;

enum CondicionCredito: int
{
case Plazo = 1;
case Cuota = 2;
}

D.3 — TiCondAnt · Condición del Anticipo

Campo XML: iCondAnt

Constante JavavalDescripción
ANTICIPO_GLOBAL1Anticipo Global
ANTICIPO_POR_ITEM2Anticipo por Ítem
<?php // app/Domains/Sifen/Enums/CondicionAnticipo.php
namespace App\Domains\Sifen\Enums;

enum CondicionAnticipo: int
{
case AnticipoGlobal = 1;
case AnticipoporItem = 2;
}

D.4 — TiForProPa · Forma de Procesamiento del Pago con Tarjeta

Campo XML: iForProPa

Constante JavavalDescripción
POS1POS
PAGO_ELECTRONICO2Pago Electrónico
OTRO9Otro
<?php // app/Domains/Sifen/Enums/FormaProcesamientoPago.php
namespace App\Domains\Sifen\Enums;

enum FormaProcesamientoPago: int
{
case Pos = 1;
case PagoElectronico = 2;
case Otro = 9;
}

D.5 — TiDenTarj · Denominación de la Tarjeta

Campo XML: iDenTarj

Constante JavavalDescripción
VISA1Visa
MASTERCARD2Mastercard
AMERICAN_EXPRESS3American Express
MAESTRO4Maestro
PANAL5Panal
CABAL6Cabal
OTRO99Otro
<?php // app/Domains/Sifen/Enums/DenominacionTarjeta.php
namespace App\Domains\Sifen\Enums;

enum DenominacionTarjeta: int
{
case Visa = 1;
case Mastercard = 2;
case AmericanExpress = 3;
case Maestro = 4;
case Panal = 5;
case Cabal = 6;
case Otro = 99;
}

GRUPO E: PRESENCIA Y NATURALEZA

E.1 — TiIndPres · Indicador de Presencia

Campo XML: iIndPres / dDesIndPres · Usado en TgCamFE

Constante JavavalDescripción
OPERACION_PRESENCIAL1Operación presencial
OPERACION_ELECTRONICA2Operación electrónica
OPERACION_TELEMARKETING3Operación telemarketing
VENTA_A_DOMICILIO4Venta a domicilio
OPERACION_BANCARIA5Operación bancaria
OPERACION_CICLICA6Operación cíclica
OTRO9Otro
<?php // app/Domains/Sifen/Enums/IndicadorPresencia.php
namespace App\Domains\Sifen\Enums;

enum IndicadorPresencia: int
{
case OperacionPresencial = 1;
case OperacionElectronica = 2;
case OperacionTelemarketing = 3;
case VentaADomicilio = 4;
case OperacionBancaria = 5;
case OperacionCiclica = 6;
case Otro = 9;
}

GRUPO F: MERCADERÍA E ÍTEMS

F.1 — TcUniMed · Unidad de Medida

Campo XML: cUniMed · Usado en TgCamItem

⚠️ Tipo especial: Tiene tanto abreviatura (string, va al XML) como val (short numérico). En PHP se recomienda usar string-backed con la abreviatura.

Abreviatura (nombre enum / XML)val (código SET)Descripción
m87Metros
CPM2366Costo Por Mil
UI2329Unidad Internacional
M3110Metros cúbicos
UNI77Unidad
g86Gramos
LT89Litros
MG90Miligramos
CM91Centímetros
CM292Centímetros cuadrados
CM393Centímetros cúbicos
PUL94Pulgadas
MM296Milímetros cuadrados
kg/m279Kilogramos s/ metro cuadrado
AA97Año
ME98Mes
TN99Tonelada
Hs100Hora
Mi101Minuto
DET104Determinación
Ya103Yardas
MT108Metros
M2109Metros cuadrados
MM95Milímetros
Se666Segundo
Di102Día
kg83Kilogramos
ML88Mililitros
Km625Kilómetros
ml660Metro lineal
GL885Unidad Medida Global
pm891Por Milaje
ha869Hectáreas
ración569Ración

⚠️ Nota: La abreviatura kg/m2 y ración contienen caracteres especiales. En PHP se puede usar el valor val como backing int o mapear a constantes sanitizadas.

<?php // app/Domains/Sifen/Enums/UnidadMedida.php
namespace App\Domains\Sifen\Enums;

enum UnidadMedida: int
{
case m = 87;
case CPM = 2366;
case UI = 2329;
case M3 = 110;
case UNI = 77;
case g = 86;
case LT = 89;
case MG = 90;
case CM = 91;
case CM2 = 92;
case CM3 = 93;
case PUL = 94;
case MM2 = 96;
case KgM2 = 79; // kg/m2
case AA = 97;
case ME = 98;
case TN = 99;
case Hs = 100;
case Mi = 101;
case DET = 104;
case Ya = 103;
case MT = 108;
case M2 = 109;
case MM = 95;
case Se = 666;
case Di = 102;
case kg = 83;
case ML = 88;
case Km = 625;
case ml = 660;
case GL = 885;
case pm = 891;
case ha = 869;
case Racion = 569; // ración

/** Devuelve la abreviatura exacta que espera el XML de la SET */
public function abreviatura(): string
{
return match($this) {
self::KgM2 => 'kg/m2',
self::Racion => 'ración',
default => $this->name,
};
}
}

F.2 — TcRelMerc · Relación de Mercadería (merma/quiebra)

Campo XML: cRelMerc · Usado en TgCamItem

Constante JavavalDescripción
TOLERANCIA_DE_QUIEBRA1Tolerancia de quiebra
TOLERANCIO_DE_MERMA2Tolerancia de merma
<?php // app/Domains/Sifen/Enums/RelacionMercaderia.php
namespace App\Domains\Sifen\Enums;

enum RelacionMercaderia: int
{
case ToleranciaDeQuiebra = 1;
case ToleranciaDeMerma = 2;
}

F.3 — TcCondNeg · Condición de Negociación (INCOTERMS)

Campo XML: cCondNeg · Usado en exportaciones

⚠️ Tipo especial: String-backed. El nombre del enum es el código que va al XML.

Código (nombre enum)Descripción
CFRCosto y flete
CIFCosto, seguro y flete
CIPTransporte y seguros pagados hasta
CPTTransporte pagado hasta
DAPEntregada en el lugar convenido
DATEntregada en terminal
DDPEntregada derechos pagados
EXWEn fábrica
FASFranco al costado del buque
FCAFranco transportista
FOBFranco a bordo
<?php // app/Domains/Sifen/Enums/CondicionNegociacion.php
namespace App\Domains\Sifen\Enums;

enum CondicionNegociacion: string
{
case CFR = 'CFR';
case CIF = 'CIF';
case CIP = 'CIP';
case CPT = 'CPT';
case DAP = 'DAP';
case DAT = 'DAT';
case DDP = 'DDP';
case EXW = 'EXW';
case FAS = 'FAS';
case FCA = 'FCA';
case FOB = 'FOB';

public function descripcion(): string
{
return match($this) {
self::CFR => 'Costo y flete',
self::CIF => 'Costo, seguro y flete',
self::CIP => 'Transporte y seguros pagados hasta',
self::CPT => 'Transporte pagado hasta',
self::DAP => 'Entregada en el lugar convenido',
self::DAT => 'Entregada en terminal',
self::DDP => 'Entregada derechos pagados',
self::EXW => 'En fábrica',
self::FAS => 'Franco al costado del buque',
self::FCA => 'Franco transportista',
self::FOB => 'Franco a bordo',
};
}
}

F.4 — TdCondTiCam · Condición del Tipo de Cambio

Campo XML: dCondTiCam

Constante JavavalDescripción
GLOBAL1Global
POR_ITEM2Por ítem
<?php // app/Domains/Sifen/Enums/CondicionTipoCambio.php
namespace App\Domains\Sifen\Enums;

enum CondicionTipoCambio: int
{
case Global = 1;
case PorItem = 2;
}

GRUPO G: TRANSPORTE Y LOGÍSTICA

G.1 — TiModTrans · Modalidad de Transporte

Campo XML: iModTrans

Constante JavavalDescripción
TERRESTRE1Terrestre
FLUVIAL2Fluvial
AEREO3Aéreo
MULTIMODAL4Multimodal
<?php // app/Domains/Sifen/Enums/ModalidadTransporte.php
namespace App\Domains\Sifen\Enums;

enum ModalidadTransporte: int
{
case Terrestre = 1;
case Fluvial = 2;
case Aereo = 3;
case Multimodal = 4;
}

G.2 — TiMotivTras · Motivo del Traslado (Nota de Remisión)

Campo XML: iMotivTras

Constante JavavalDescripción
TRASLADO_POR_VENTAS1Traslado por ventas
TRASLADO_POR_CONSIGNACION2Traslado por consignación
EXPORTACION3Exportación
TRASLADO_POR_COMPRA4Traslado por compra
IMPORTACION5Importación
TRASLADO_POR_DEVOLUCION6Traslado por devolución
TRASLADO_ENTRE_LOCALES7Traslado entre locales de la empresa
TRASLADO_BIENES_TRANSFORMACION8Traslado de bienes por transformación
TRASLADO_BIENES_REPARACION9Traslado de bienes para reparación
TRASLADO_POR_EMISOR_MOVIL10Traslado por emisor móvil
EXHIBICION_O_DEMOSTRACION11Exhibición o Demostración
PARTICIPACION_EN_FERIAS12Participación en ferias
TRASLADO_DE_ENCOMIENDAS13Traslado de encomienda
DECOMISO14Decomiso
OTRO99Otro
<?php // app/Domains/Sifen/Enums/MotivoTraslado.php
namespace App\Domains\Sifen\Enums;

enum MotivoTraslado: int
{
case TrasladoPorVentas = 1;
case TrasladoPorConsignacion = 2;
case Exportacion = 3;
case TrasladoPorCompra = 4;
case Importacion = 5;
case TrasladoPorDevolucion = 6;
case TrasladoEntreLocales = 7;
case TrasladoBienesTransformacion = 8;
case TrasladoBienesReparacion = 9;
case TrasladoPorEmisorMovil = 10;
case ExhibicionODemostracion = 11;
case ParticipacionEnFerias = 12;
case TrasladoDeEncomiendas = 13;
case Decomiso = 14;
case Otro = 99;
}

G.3 — TiTTrans · Tipo de Transporte (Propio/Tercero)

Campo XML: iTTrans

Constante JavavalDescripción
PROPIO1Propio
TERCERO2Tercero
<?php // app/Domains/Sifen/Enums/TipoTransporte.php
namespace App\Domains\Sifen\Enums;

enum TipoTransporte: int
{
case Propio = 1;
case Tercero = 2;
}

G.4 — TiRespFlete · Responsable del Flete

Campo XML: iRespFlete

⚠️ Sin descripcion en Java. Solo tiene val.

Constante JavavalDescripción (inferida)
EMISOR_FACTURA_ELECTRONICA1Emisor de la FE
RECEPTOR_FACTURA_ELECTRONICA2Receptor de la FE
TERCERO3Tercero
AGENTE_INTERMEDIARIO4Agente intermediario
TRANSPORTE_PROPIO5Transporte propio
<?php // app/Domains/Sifen/Enums/ResponsableFlete.php
namespace App\Domains\Sifen\Enums;

enum ResponsableFlete: int
{
case EmisorFacturaElectronica = 1;
case ReceptorFacturaElectronica = 2;
case Tercero = 3;
case AgenteIntermediario = 4;
case TransportePropio = 5;
}

G.5 — TiCarCarga · Tipo de Característica de Carga

Campo XML: iCarCarga

Constante JavavalDescripción
MERCADERIA_CON_CADENA_DE_FRIO1Mercaderías con cadena de frío
CARGA_PELIGROSA2Carga peligrosa
OTRO3Otro
<?php // app/Domains/Sifen/Enums/CaracteristicaCarga.php
namespace App\Domains\Sifen\Enums;

enum CaracteristicaCarga: int
{
case MercaderiaConCadenaDeFrio = 1;
case CargaPeligrosa = 2;
case Otro = 3;
}

G.6 — TiRespEmiNR · Responsable de Emisión Nota de Remisión

Campo XML: iRespEmiNR

Constante JavavalDescripción
EMISOR_FACTURA1Emisor de la factura
POSEEDOR_FACTURA_Y_BIENES2Poseedor de la factura y bienes
EMPRESA_TRANSPORTISTA3Empresa transportista
DESPACHANTE_DE_ADUANAS4Despachante de Aduanas
AGENTE_DE_TRANSPORTE_O_INTERMEDIARIO5Agente de transporte o intermediario
<?php // app/Domains/Sifen/Enums/ResponsableEmisionNR.php
namespace App\Domains\Sifen\Enums;

enum ResponsableEmisionNR: int
{
case EmisorFactura = 1;
case PoseedorFacturaYBienes = 2;
case EmpresaTransportista = 3;
case DespachantDeAduanas = 4;
case AgenteDeTransporteOIntermediario = 5;
}

G.7 — TdTipIdenVeh · Tipo de Identificación del Vehículo

Campo XML: dTipIdenVeh

Constante JavavalDescripción
NRO_IDENTIFICACION1Número de identificación del vehículo
NRO_MATRICULA2Número de matrícula del vehículo
<?php // app/Domains/Sifen/Enums/TipoIdentificacionVehiculo.php
namespace App\Domains\Sifen\Enums;

enum TipoIdentificacionVehiculo: int
{
case NroIdentificacion = 1;
case NroMatricula = 2;
}

G.8 — TiTipOpVN · Tipo de Operación Venta Vehículo Nuevo

Campo XML: iTipOpVN

Constante JavavalDescripción
VENTA_A_REPRESENTANTE1Venta a representante
VENTA_AL_CONSUMIDOR_FINAL2Venta al Consumidor final
VENTA_AL_GOBIERNO3Venta a gobierno
VENTA_A_FLOTA_DE_VEHICULOS4Venta a flota de vehículos
<?php // app/Domains/Sifen/Enums/TipoOperacionVehiculoNuevo.php
namespace App\Domains\Sifen\Enums;

enum TipoOperacionVehiculoNuevo: int
{
case VentaARepresentante = 1;
case VentaAlConsumidorFinal = 2;
case VentaAlGobierno = 3;
case VentaAFlotaDeVehiculos = 4;
}

G.9 — TiTipCom · Tipo de Combustible

Campo XML: iTipCom

⚠️ Bug en Java: DIESEL, ETANOL, GNV y FLEX comparten val=2. Solo GASOLINA=1 y OTRO=9 son únicos.

Constante JavavalDescripción
GASOLINA1Gasolina
DIESEL2Diésel
ETANOL2 ⚠️Etanol
GNV2 ⚠️GNV
FLEX2 ⚠️Flex
OTRO9Otro
<?php // app/Domains/Sifen/Enums/TipoCombustible.php
namespace App\Domains\Sifen\Enums;

// NOTA: Los valores 2 son duplicados en el código Java fuente.
// Se implementa con string-backing para preservar semántica correcta.
enum TipoCombustible: string
{
case Gasolina = 'gasolina';
case Diesel = 'diesel';
case Etanol = 'etanol';
case Gnv = 'gnv';
case Flex = 'flex';
case Otro = 'otro';

/** Código SIFEN (val) para serializar en XML */
public function val(): int
{
return match($this) {
self::Gasolina => 1,
self::Diesel, self::Etanol, self::Gnv, self::Flex => 2,
self::Otro => 9,
};
}
}

GRUPO H: EVENTOS Y CONFORMIDAD

H.1 — TdMotEv · Motivo del Evento (Nota de Remisión Electrónica)

Campo XML: dMotEv

Constante JavavalDescripción
CAMBIO_LOCAL_ENTREGA1Cambio del local de la entrega
CAMBIO_CHOFER2Cambio del chofer
CAMBIO_TRANSPORTISTA3Cambio del transportista
CAMBIO_VEHICULO4Cambio de vehículo
<?php // app/Domains/Sifen/Enums/MotivoEvento.php
namespace App\Domains\Sifen\Enums;

enum MotivoEvento: int
{
case CambioLocalEntrega = 1;
case CambioChofer = 2;
case CambioTransportista = 3;
case CambioVehiculo = 4;
}

H.2 — TiTipConf · Tipo de Conformidad

Campo XML: iTipConf

Constante JavavalDescripción
CONFORMIDAD_TOTAL1Conformidad Total del DTE
CONFORMIDAD_PARCIAL2Conformidad Parcial del DTE
<?php // app/Domains/Sifen/Enums/TipoConformidad.php
namespace App\Domains\Sifen\Enums;

enum TipoConformidad: int
{
case ConformidadTotal = 1;
case ConformidadParcial = 2;
}

H.3 — TdTipCons · Tipo de Constancia

Campo XML: dTipCons

Constante JavavalDescripción
CONSTANCIA_NO_CONTRIBUYENTE1Constancia de no ser contribuyente
CONSTANCIA_MICROPRODUCTORES2Constancia de microproductores
<?php // app/Domains/Sifen/Enums/TipoConstancia.php
namespace App\Domains\Sifen\Enums;

enum TipoConstancia: int
{
case ConstanciaNoContribuyente = 1;
case ConstanciaMicroproductores = 2;
}

GRUPO I: GEOGRAFÍA Y MONEDAS

I.1 — TDepartamento · Departamentos del Paraguay

Campo XML: cDepEnt / cDepRes · Usado en TgCamEnt

Constante JavavalDescripción
CAPITAL1CAPITAL
CONCEPCION2CONCEPCION
SAN_PEDRO3SAN PEDRO
CORDILLERA4CORDILLERA
GUAIRA5GUAIRA
CAAGUAZU6CAAGUAZU
CAAZAPA7CAAZAPA
ITAPUA8ITAPUA
MISIONES9MISIONES
PARAGUARI10PARAGUARI
ALTO_PARANA11ALTO PARANA
CENTRAL12CENTRAL
NEEMBUCU13NEEMBUCU
AMAMBAY14AMAMBAY
PTE_HAYES15PTE. HAYES
BOQUERON16BOQUERON
ALTO_PARAGUAY17ALTO PARAGUAY
CANINDEYU18CANINDEYU
CHACO19CHACO
NUEVA_ASUNCION20NUEVA ASUNCION
<?php // app/Domains/Sifen/Enums/Departamento.php
namespace App\Domains\Sifen\Enums;

enum Departamento: int
{
case Capital = 1;
case Concepcion = 2;
case SanPedro = 3;
case Cordillera = 4;
case Guaira = 5;
case Caaguazu = 6;
case Caazapa = 7;
case Itapua = 8;
case Misiones = 9;
case Paraguari = 10;
case AltoParana = 11;
case Central = 12;
case Neembucu = 13;
case Amambay = 14;
case PteHayes = 15;
case Boqueron = 16;
case AltoParaguay = 17;
case Canindeyu = 18;
case Chaco = 19;
case NuevaAsuncion = 20;
}

I.2 — PaisType · Países (ISO 3166 Alpha-3)

Tipo: String-backed. El nombre del enum es el código ISO 3166-1 alpha-3. Lista completa según la SET (~190 países). Solo se muestran países relevantes.

<?php // app/Domains/Sifen/Enums/Pais.php
namespace App\Domains\Sifen\Enums;

// Enumerado completo ISO 3166-1 alpha-3 según catálogo SET
// Solo ejemplos representativos — implementar el catálogo completo según PaisType.java
enum Pais: string
{
case Paraguay = 'PRY';
case Argentina = 'ARG';
case Brasil = 'BRA';
case Uruguay = 'URY';
case Bolivia = 'BOL';
case Chile = 'CHL';
case Peru = 'PER';
case Colombia = 'COL';
case Venezuela = 'VEN';
case Ecuador = 'ECU';
case Usa = 'USA';
case Espana = 'ESP';
case Alemania = 'DEU';
case China = 'CHN';
case Japon = 'JPN';
// ... todos los códigos ISO 3166-1 alpha-3 del enum PaisType.java

public function descripcion(): string
{
return match($this) {
self::Paraguay => 'Paraguay',
self::Argentina => 'Argentina',
self::Brasil => 'Brasil',
// ...
default => $this->value,
};
}
}

I.3 — CMondT · Monedas (ISO 4217)

Tipo: String-backed. El nombre del enum es el código ISO 4217. La moneda local es PYG (Guaraní). El enum contiene ~150 monedas.

<?php // app/Domains/Sifen/Enums/Moneda.php
namespace App\Domains\Sifen\Enums;

enum Moneda: string
{
case PYG = 'PYG'; // Guaraní (moneda local)
case USD = 'USD'; // US Dollar
case EUR = 'EUR'; // Euro
case BRL = 'BRL'; // Brazilian Real
case ARS = 'ARS'; // Argentine Peso
case UYU = 'UYU'; // Peso Uruguayo
case BOB = 'BOB'; // Boliviano
case CLP = 'CLP'; // Chilean Peso
case COP = 'COP'; // Colombian Peso
case PEN = 'PEN'; // Nuevo Sol
case GBP = 'GBP'; // Pound Sterling
case JPY = 'JPY'; // Yen
case CNY = 'CNY'; // Yuan Renminbi
case CAD = 'CAD'; // Canadian Dollar
case AUD = 'AUD'; // Australian Dollar
case CHF = 'CHF'; // Swiss Franc
// ... todas las monedas del enum CMondT.java

public function descripcion(): string
{
return match($this) {
self::PYG => 'Guaraní',
self::USD => 'US Dollar',
self::EUR => 'Euro',
default => $this->value,
};
}
}

2. MAPA DE ESTRUCTURAS POJO → DTO

Jerarquía raíz del Documento Electrónico

DocumentoElectronico (raíz XML: <DE>)
├── Id : String ← CDC (44 chars), lleva @Id en XML
├── dDVId : String ← Dígito Verificador del CDC (Módulo 11)
├── dFecFirma : LocalDateTime ← Formato: yyyy-MM-dd'T'HH:mm:ss
├── dSisFact : short ← 1=Sistema cliente, 2=Sistema SET gratuito

├── gOpeDE : TgOpeDE ← Campos de operación del DE
├── gTimb : TgTimb ← Datos del timbrado
├── gDatGralOpe : TdDatGralOpe ← Datos generales de la operación
├── gDtipDE : TgDtipDE ← Campos específicos por tipo de DE
├── gTotSub : TgTotSub ← Subtotales y totales
├── gCamGen : TgCamGen ← Campos generales opcionales
├── gCamDEAsocList : List<TgCamDEAsoc> ← Documentos asociados (0..N)
└── enlaceQR : String ← URL del QR generado por SET

TgOpeDE — Operación del DE

TgOpeDE
├── iTipEmi : TTipEmi REQUERIDO ← Tipo Emisión (1=Normal, 2=Contingencia)
├── dCodSeg : String REQUERIDO ← Número aleatorio 1-999999999 (9 dígitos, 0-padded)
├── dInfoEmi : String OPCIONAL ← Info del emisor (1-3000 chars)
└── dInfoFisc : String OPCIONAL ← Info del fisco (1-3000 chars)

PHP DTO:

<?php // app/Domains/Sifen/DTOs/OperacionDE.php
namespace App\Domains\Sifen\DTOs;
use App\Domains\Sifen\Enums\TipoEmision;

readonly class OperacionDE
{
public function __construct(
public TipoEmision $tipoEmision,
public string $codigoSeguridad, // 9 dígitos, generado aleatoriamente
public ?string $infoEmisor = null, // max 3000 chars
public ?string $infoFisco = null, // max 3000 chars
) {}
}

TdDatGralOpe — Datos Generales de la Operación

TdDatGralOpe
├── dFeEmiDE : LocalDateTime REQUERIDO ← Fecha y hora de emisión
├── gOpeCom : TgOpeCom REQUERIDO ← Datos de la operación comercial
│ ├── iTiDE : TTiDE ← Tipo DE
│ ├── dDesTiDE : String ← Descripción tipo DE (auto)
│ ├── iTiOpe : TiTiOpe ← B2B/B2C/B2G/B2F
│ ├── dDesTiOpe : String ← Descripción (auto)
│ ├── iTImp : TTImp ← Tipo impuesto
│ ├── dDesTImp : String ← Descripción (auto)
│ ├── dCodEst : String ← Código establecimiento (3 chars, 0-padded)
│ ├── dPunExp : String ← Punto de expedición (3 chars, 0-padded)
│ ├── dNumDoc : String ← Número de documento (7 chars, 0-padded)
│ ├── dNumTim : long ← Número de timbrado (8 dígitos)
│ ├── dEst : String ← Establecimiento
│ ├── dPunEExp : String ← Punto de expedición
│ ├── dNumIniTim : long ← Desde
│ ├── dNumFinTim : long ← Hasta
│ ├── dFecVencTim: LocalDate ← Vencimiento timbrado
│ ├── iTipCont : TiTipCont ← Persona Física/Jurídica
│ ├── dDesTipCont: String ← Descripción (auto)
│ ├── dRucEm : String ← RUC del emisor (sin DV)
│ ├── dDVEmi : String ← Dígito verificador del RUC
│ ├── iTipReg : TTipReg ← Tipo régimen
│ ├── iCondTipCam: TdCondTiCam ← Global/Por ítem (si moneda extranjera)
│ └── dTipCam : BigDecimal ← Tipo de cambio

├── gEmis : TgEmis REQUERIDO ← Datos del emisor
│ ├── dRucEm : String ← RUC emisor ⚠️ DV calculado con Módulo 11
│ ├── dDVEmi : String ← Dígito verificador RUC
│ ├── dNomEmi : String ← Nombre/razón social (max 255 chars)
│ ├── dNomFantasiaEmi: String ← Nombre fantasía (max 255 chars)
│ ├── gActEcoList : List<TgActEco> ← Actividades económicas (1..N)
│ ├── dDirEmi : String ← Dirección (max 255 chars)
│ ├── dNumCasEmi : short ← Número de casa
│ ├── cDepEmi : TDepartamento ← Departamento
│ ├── cDisEmi : short ← Código distrito
│ ├── dDesDisEmi : String ← Descripción distrito
│ ├── cCiuEmi : int ← Código ciudad
│ ├── dDesCiuEmi : String ← Descripción ciudad
│ ├── dTelEmi : String ← Teléfono
│ ├── dEmailEmi : String ← Email
│ └── dInfoEmi : String ← Info adicional emisor

└── gDatRec : TgDatRec CONDICIONAL ← Datos del receptor (obligatorio B2B/B2G)
├── iNatRec : TiNatRec ← Contribuyente/No Contribuyente
├── dNomRec : String ← Nombre receptor (max 255 chars)
├── dRucRec : String ← RUC receptor (si contribuyente)
├── dDVRec : String ← DV del RUC receptor ⚠️ Módulo 11
├── iTipDocRec : TiTipDocRec ← Tipo doc identidad receptor
├── dNumIDRec : String ← Número de documento receptor
├── dEmailRec : String ← Email receptor
└── dDirRec : String ← Dirección receptor

TgCamItem — Ítem del Documento

TgCamItem ← Usado en List<TgCamItem> en TgDtipDE
├── dCodInt : String OPCIONAL ← Código interno del ítem (max 20 chars)
├── dParAranc : short OPCIONAL ← Partida arancelaria (4 dígitos)
├── dNCM : int OPCIONAL ← Código NCM (8 dígitos)
├── dDncpG : String OPCIONAL ← Código DNCP Genérico (8 chars, 0-padded)
├── dDncpE : String OPCIONAL ← Código DNCP Específico
├── dGtin : long OPCIONAL ← Código GTIN del producto
├── dGtinPq : long OPCIONAL ← Código GTIN del empaque
├── dDesProSer : String REQUERIDO ← Descripción del producto/servicio (max 120 chars)
├── cUniMed : TcUniMed REQUERIDO ← Unidad de medida
├── dCantProSer : BigDecimal REQUERIDO ← Cantidad (máx. 10 enteros + 4 decimales)
├── cPaisOrig : PaisType OPCIONAL ← País de origen (ISO 3166)
├── dInfItem : String OPCIONAL ← Info adicional del ítem (max 500 chars)
├── cRelMerc : TcRelMerc OPCIONAL ← Relación mercadería (quiebra/merma)
├── dCanQuiMer : BigDecimal OPCIONAL ← Cantidad quiebra/merma
├── dPorQuiMer : BigDecimal OPCIONAL ← Porcentaje quiebra/merma
├── dCDCAnticipo : String OPCIONAL ← CDC del anticipo asociado (44 chars)
├── gValorItem : TgValorItem REQUERIDO ← Valores monetarios del ítem
│ ├── dPUniProSer : BigDecimal ← Precio unitario
│ ├── dTotBruOpeItem: BigDecimal ← Total bruto
│ ├── gValorRestaItem: TgValorRestaItem ← Descuentos/recargos
│ │ ├── dDescItem : BigDecimal ← Descuento
│ │ ├── dPorcDesIt : BigDecimal ← % descuento
│ │ ├── dDescGloItem : BigDecimal ← Descuento global aplicado
│ │ ├── dAntGloPreUniIt: BigDecimal ← Anticipo global precio unitario
│ │ ├── dAntPreUniIt : BigDecimal ← Anticipo precio unitario
│ │ └── dTotOpeItem : BigDecimal ← Total operación ítem (NETO)
│ └── dTotOpeGs : BigDecimal ← Total en Gs.
├── gCamIVA : TgCamIVA REQUERIDO ← Datos IVA del ítem
│ ├── iAfecIVA : TiAfecIVA ← Afectación IVA
│ ├── dPropIVA : BigDecimal ← Proporción IVA (0-100)
│ ├── dTasaIVA : BigDecimal ← Tasa IVA (0, 5, 10)
│ ├── dBasGravIVA: BigDecimal ← Base gravada
│ ├── dLiqIVAItem: BigDecimal ← Liquidación IVA del ítem
│ └── dBasExe : BigDecimal ← Base exenta
├── gRasMerc : TgRasMerc CONDICIONAL ← Rastreo mercadería (importación)
└── gVehNuevo : TgVehNuevo CONDICIONAL ← Datos vehículo nuevo

PHP DTO:

<?php // app/Domains/Sifen/DTOs/Item.php
namespace App\Domains\Sifen\DTOs;
use App\Domains\Sifen\Enums\{AfectacionIVA, UnidadMedida, Pais, RelacionMercaderia};

readonly class Item
{
public function __construct(
public string $descripcion, // max 120 chars, REQUERIDO
public UnidadMedida $unidadMedida, // REQUERIDO
public float $cantidad, // max 10 enteros + 4 decimales
public float $precioUnitario, // REQUERIDO
public AfectacionIVA $afectacionIva, // REQUERIDO
public float $tasaIva, // 0, 5 o 10
public ?string $codigoInterno = null, // max 20 chars
public ?string $dncp = null, // 8 chars, se 0-padea
public ?Pais $paisOrigen = null,
public ?float $descuento = null,
public ?string $infoAdicional = null, // max 500 chars
) {}
}

TgCamCond — Condición de Pago

TgCamCond
├── iCondOpe : TiCondOpe REQUERIDO ← Contado/Crédito
├── gPaConEIniList : List<TgPaConEIni> CONDICIONAL (si CONTADO)
│ ├── iTiPago : TiTiPago ← Tipo de pago
│ ├── dMonTiPag : BigDecimal ← Monto
│ ├── cMonedasPago : CMondT ← Moneda
│ ├── dCambioMonPag: BigDecimal ← Tipo de cambio
│ ├── dTarjNumAuto : String ← Número autorización tarjeta
│ ├── iForProPa : TiForProPa ← Forma procesamiento (si tarjeta)
│ └── iDenTarj : TiDenTarj ← Denominación tarjeta
└── gPagCred : TgPagCred CONDICIONAL (si CREDITO)
├── iCondCred : TiCondCred ← Plazo/Cuota
├── dPlazoCre : String ← Plazo en días/meses
├── dCuotas : short ← Número de cuotas
├── dMonEntIni : BigDecimal ← Monto entrada inicial
├── dMonCuota : BigDecimal ← Monto por cuota
└── dFecFin : LocalDate ← Fecha fin del crédito

TgCamDEAsoc — Documento Electrónico Asociado

TgCamDEAsoc
├── iTipDocAso : TiTipDocAso REQUERIDO ← Electrónico/Impreso/Constancia
├── dCdCDE : String CONDICIONAL ← CDC (si electrónico, 44 chars)
├── iTIpoDoc : TiTIpoDoc CONDICIONAL ← Tipo doc (si impreso)
├── dNumDoc : String CONDICIONAL ← Número (si impreso)
├── dNumTim : long CONDICIONAL ← Timbrado (si impreso)
├── dFecEmiDoc : LocalDate CONDICIONAL ← Fecha emisión (si impreso)
└── dNomRemi : String OPCIONAL ← Nombre remitente

3. REGLAS DE VALIDACIÓN CRIPTOGRÁFICA

3.1 — Dígito Verificador (Módulo 11)

Fuente: SifenUtil.java:55-68

Algoritmo completo:

// Java original
public static String generateDv(String ruc) {
int baseMax = 11, k = 2, total = 0;
if (ruc.equals("88888801")) return "5"; // caso especial SET
for (int i = ruc.length() - 1; i >= 0; i--) {
k = k > baseMax ? 2 : k;
int n = Integer.parseInt(ruc.substring(i, i + 1));
total += n * k;
k++;
}
return String.valueOf((total % 11) > 1 ? 11 - (total % 11) : 0);
}

Implementación PHP:

<?php // app/Domains/Sifen/Support/DigitoVerificador.php
namespace App\Domains\Sifen\Support;

class DigitoVerificador
{
/**
* Calcula el Dígito Verificador de un RUC paraguayo usando Módulo 11.
* Caso especial: RUC "88888801" → DV = "5" (RUC de prueba de la SET).
*/
public static function calcular(string $ruc): string
{
if ($ruc === '88888801') {
return '5';
}

$baseMax = 11;
$k = 2;
$total = 0;

for ($i = strlen($ruc) - 1; $i >= 0; $i--) {
if ($k > $baseMax) {
$k = 2;
}
$n = (int) $ruc[$i];
$total += $n * $k;
$k++;
}

$resto = $total % 11;

return (string) ($resto > 1 ? 11 - $resto : 0);
}

/**
* Calcula el DV del CDC (Código de Control del DE, 44 dígitos).
* El CDC se construye: 2 (tiDE) + 8 (RUC) + 1 (DV RUC) + 3 (est) + 3 (puntoExp)
* + 7 (numDoc) + 8 (timbrado) + 9 (codSeg) + 2 (tipoEm) + 1 (ambient)
* El DV se calcula sobre los 44 dígitos del CDC.
*/
public static function calcularCDC(string $cdc): string
{
return self::calcular($cdc);
}
}

3.2 — Firma Digital XML (XMLDSig)

Fuente: SignatureHelper.java | Constants.java

Especificaciones Técnicas:

ParámetroValor
Algoritmo de FirmaRSA-SHA256
URI del algoritmohttp://www.w3.org/2001/04/xmldsig-more#rsa-sha256
Algoritmo de DigestSHA-256 (DigestMethod.SHA256)
CanonicalizaciónExclusive XML Canonicalization 1.0 (C14N Exclusive)
Transforms1) ENVELOPED → 2) C14N Exclusive
Tipo de firmaEnveloped (la firma es hija del nodo firmado)
Nodo firmado<DE Id="..."> (referencia por atributo Id)
Posición de la firmaDentro del nodo <DE>, como hijo directo
KeyInfo<X509Data> con el certificado X.509 completo
Formato de certificadoPKCS#12 (.pfx)
Validación del emisorRUC en el DE debe coincidir con SERIALNUMBER del certificado

Flujo de firma:

1. Construir XML del DE
2. Asignar @Id al nodo <DE>
3. Crear Reference("#"+Id) con:
- DigestMethod: SHA-256
- Transform 1: Enveloped Signature
- Transform 2: Exclusive C14N
4. Crear SignedInfo con:
- CanonicalizationMethod: Exclusive C14N
- SignatureMethod: RSA-SHA256
5. Cargar KeyStore PKCS12 con contraseña
6. Obtener PrivateKey + X509Certificate del alias
7. Crear DOMSignContext(privateKey, nodoDE)
8. Firmar → XMLSignature.sign(context)
9. La firma queda embebida en el XML (<Signature> dentro de <DE>)

Implementación PHP con xmlseclibs:

<?php // app/Domains/Sifen/Support/XmlSigner.php
namespace App\Domains\Sifen\Support;

use RobRichards\XMLSecLibs\XMLSecurityDSig;
use RobRichards\XMLSecLibs\XMLSecurityKey;

class XmlSigner
{
public function __construct(
private string $pfxPath, // ruta al archivo .pfx
private string $pfxPassword, // contraseña del certificado
) {}

public function firmar(\DOMDocument $xml): \DOMDocument
{
// 1. Cargar certificado PKCS12
$pfxContent = file_get_contents($this->pfxPath);
$certs = [];
openssl_pkcs12_read($pfxContent, $certs, $this->pfxPassword);

$privateKey = $certs['pkey'];
$certificate = $certs['cert'];

// 2. Crear instancia DSig con Exclusive C14N
$dsig = new XMLSecurityDSig('');
$dsig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);

// 3. Agregar referencia al nodo DE con transforms
$dsig->addReference(
$xml->documentElement,
XMLSecurityDSig::SHA256,
[
'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
XMLSecurityDSig::EXC_C14N,
],
['force_uri' => true]
);

// 4. Crear key RSA-SHA256
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'private']);
$key->loadKey($privateKey);

// 5. Firmar
$dsig->sign($key);

// 6. Agregar X509Certificate en KeyInfo
$dsig->add509Cert($certificate);

// 7. Insertar <Signature> en el XML (enveloped = dentro del nodo DE)
$dsig->appendSignature($xml->documentElement);

return $xml;
}
}

3.3 — mTLS (Mutual TLS)

Fuente: SSLContextHelper.java | SoapHelper.java

Especificaciones mTLS:

ParámetroValor
Protocolo SSL/TLSTLS (SSLContext.getInstance("TLS"))
Tipo de KeyStorePKCS12
CertificadoArchivo .pfx o Base64 codificado, o classpath
KeyManagerFactoryAlgoritmo por defecto del JVM
TrustManagernull → usa el TrustStore del sistema
SOAP VersionSOAP 1.2
Content-Typeapplication/xml; charset=utf-8
Método HTTPPOST sobre HTTPS

Implementación PHP con cURL:

<?php // app/Domains/Sifen/Http/SifenHttpClient.php
namespace App\Domains\Sifen\Http;

class SifenHttpClient
{
public function __construct(
private string $pfxPath,
private string $pfxPassword,
private int $connectTimeout = 10,
private int $readTimeout = 60,
) {}

public function post(string $url, string $soapBody): string
{
$ch = curl_init($url);

curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $soapBody,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => $this->connectTimeout,
CURLOPT_TIMEOUT => $this->readTimeout,
CURLOPT_HTTPHEADER => [
'Content-Type: application/xml; charset=utf-8',
'User-Agent: SIFEN-PHP-Client/1.0',
],
// mTLS: certificado de cliente
CURLOPT_SSLCERTTYPE => 'P12',
CURLOPT_SSLCERT => $this->pfxPath,
CURLOPT_SSLCERTPASSWD => $this->pfxPassword,
// Verificación del servidor SET
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);

$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);

if ($error) {
throw new \RuntimeException("mTLS Error: {$error}");
}

return $response;
}
}

3.4 — Generación del CDC (Código de Control del DE)

El CDC es el campo Id del DocumentoElectronico, 44 dígitos:

CDC = iTiDE(2) + dRucEm(8) + dDVEmi(1) + dCodEst(3) + dPunExp(3)
+ dNumDoc(7) + dNumTim(8) + dCodSeg(9) + iTipEmi(2) + dAmbiente(1)
<?php // app/Domains/Sifen/Support/CdcGenerator.php
namespace App\Domains\Sifen\Support;

class CdcGenerator
{
public static function generar(
int $tipoDE, // TTiDE val (1-8)
string $rucEmisor, // sin DV, puede tener hasta 8 dígitos
string $dvRuc, // 1 dígito
string $establecimiento, // 3 dígitos, 0-padded
string $puntoExpedicion, // 3 dígitos, 0-padded
string $numeroDocumento, // 7 dígitos, 0-padded
string $numeroTimbrado, // 8 dígitos
string $codigoSeguridad, // 9 dígitos aleatorios, 0-padded
int $tipoEmision, // TTipEmi val (1 o 2)
int $ambiente, // 1=Test, 2=Producción
): string {
$cdc = str_pad($tipoDE, 2, '0', STR_PAD_LEFT)
. str_pad($rucEmisor, 8, '0', STR_PAD_LEFT)
. $dvRuc
. str_pad($establecimiento, 3, '0', STR_PAD_LEFT)
. str_pad($puntoExpedicion, 3, '0', STR_PAD_LEFT)
. str_pad($numeroDocumento, 7, '0', STR_PAD_LEFT)
. str_pad($numeroTimbrado, 8, '0', STR_PAD_LEFT)
. str_pad($codigoSeguridad, 9, '0', STR_PAD_LEFT)
. str_pad($tipoEmision, 2, '0', STR_PAD_LEFT)
. $ambiente;

// El DV del CDC se agrega al campo dDVId del DocumentoElectronico
return $cdc; // 43 chars → dDVId = DigitoVerificador::calcular($cdc)
}

public static function codigoSeguridadAleatorio(): string
{
return str_pad((string) random_int(1, 999999999), 9, '0', STR_PAD_LEFT);
}
}

4. GUÍA DE IMPLEMENTACIÓN LARAVEL 12

4.1 — Estructura de Directorios propuesta

app/
└── Domains/
└── Sifen/
├── Enums/ ← 40+ PHP Backed Enums (esta biblia)
│ ├── TipoDocumentoElectronico.php
│ ├── TipoEmision.php
│ ├── TipoTransaccion.php
│ ├── AfectacionIVA.php
│ ├── TipoPago.php
│ ├── UnidadMedida.php
│ ├── Moneda.php
│ ├── Pais.php
│ ├── Departamento.php
│ └── ... (todos los enums de esta biblia)

├── DTOs/ ← Objetos de Transferencia (readonly classes)
│ ├── DocumentoElectronico.php
│ ├── OperacionDE.php
│ ├── DatosGeneralesOperacion.php
│ ├── DatosEmisor.php
│ ├── DatosReceptor.php
│ ├── Item.php
│ ├── CondicionPago.php
│ ├── DocumentoAsociado.php
│ └── Totales.php

├── Support/ ← Lógica de negocio pura
│ ├── DigitoVerificador.php ← Módulo 11
│ ├── CdcGenerator.php ← Construcción del CDC
│ ├── XmlBuilder.php ← Construcción del XML según esquema SET
│ └── XmlSigner.php ← Firma digital XMLDSig RSA-SHA256

├── Http/ ← Capa de transporte
│ ├── SifenHttpClient.php ← mTLS con cURL
│ └── SoapEnvelope.php ← Construcción del sobre SOAP 1.2

├── Services/ ← Casos de uso
│ ├── TransmitirDeService.php
│ ├── ConsultarDeService.php
│ ├── TransmitirEventoService.php
│ └── ConsultarRucService.php

├── Responses/ ← Parseo de respuestas XML de la SET
│ ├── RespuestaTransmision.php
│ └── RespuestaConsulta.php

└── Exceptions/
└── SifenException.php

4.2 — Mapeo Java Collections → PHP / Laravel

JavaPHP / LaravelNotas
List<TgCamItem>Collection<Item> o Item[]Laravel Collection o array tipado
List<TgActEco>array de ActivityEco DTOs1..N actividades económicas
List<TgCamDEAsoc>Collection de DocumentoAsociado0..N documentos asociados
List<TgPaConEIni>array de PagoContadoSolo si condición = CONTADO
BigDecimal (Java)string o bcmath en PHPUsar bcscale(4) para cálculos
LocalDateTimeCarbon\Carbon->format('Y-m-d\TH:i:s')
LocalDateCarbon\Carbon->format('Y-m-d')
short / intintSin diferencia en PHP
Enum .getVal()$enum->valueBacked enum PHP
SifenUtil.leftPad()str_pad($s, $len, '0', STR_PAD_LEFT)
SifenUtil.generateDv()DigitoVerificador::calcular($ruc)Módulo 11
SifenUtil.sha256Hex()hash('sha256', $input)Equivalente exacto

4.3 — Ejemplo de DTO raíz DocumentoElectronico

<?php // app/Domains/Sifen/DTOs/DocumentoElectronico.php
namespace App\Domains\Sifen\DTOs;

use Carbon\Carbon;
use Illuminate\Support\Collection;

readonly class DocumentoElectronico
{
public string $id; // CDC de 44 caracteres
public string $dvId; // Dígito verificador del CDC

public function __construct(
public Carbon $fechaFirma, // yyyy-MM-dd'T'HH:mm:ss
public int $sistemaFactura, // 1=cliente, 2=SET gratuita
public OperacionDE $operacion, // TgOpeDE
public Timbrado $timbrado, // TgTimb
public DatosGeneralesOpe $datosGenerales, // TdDatGralOpe
public TipoDeTipoDE $tipoDE, // TgDtipDE (FE, NC, ND, NR...)
public Totales $totales, // TgTotSub
public ?CamposGenerales $camposGenerales = null,
/** @var Collection<DocumentoAsociado> */
public Collection $documentosAsociados = new Collection(),
) {
// El CDC y su DV se calculan en el constructor
$this->id = CdcGenerator::generar(/* ... parámetros */);
$this->dvId = DigitoVerificador::calcular($this->id);
}
}

4.4 — Endpoints SOAP de la SET

OperaciónEndpoint TESTMétodo SOAP
Recepción DEhttps://sifen-test.set.gov.py/de/ws/sync/recibe.wsdlrEnviaDe
Recepción Lotehttps://sifen-test.set.gov.py/de/ws/async/recibe-lote.wsdlrEnviaLoteDe
Consulta Estado DEhttps://sifen-test.set.gov.py/de/ws/consultas/estado.wsdlrConsultaEstadoDe
Consulta Lotehttps://sifen-test.set.gov.py/de/ws/consultas/lote.wsdlrConsultaLoteDe
Recepción Eventohttps://sifen-test.set.gov.py/de/ws/evento/recibe-evento.wsdlrEnviaEvento
Consulta RUChttps://sifen-test.set.gov.py/de/ws/consultas/ruc.wsdlrGetActEco

Nota: Reemplazar sifen-test por sifen para producción. Namespace: http://ekuatia.set.gov.py/sifen/xsd XSD Version: v150


4.5 — Constantes de Sistema

Fuente: Constants.java

<?php // app/Domains/Sifen/Support/SifenConstants.php
namespace App\Domains\Sifen\Support;

final class SifenConstants
{
// Versión del SDK y protocolo SIFEN
public const SDK_VERSION = '0.2.4';
public const SIFEN_VERSION = '150';

// Namespace XML oficial de la SET
public const NS_URI = 'http://ekuatia.set.gov.py/sifen/xsd';
public const NS_RECEP_DE = self::NS_URI . ' siRecepDE_v150.xsd';
public const NS_RECEP_EVT = self::NS_URI . ' siRecepEvento_v150.xsd';

// Algoritmos criptográficos
public const RSA_SHA256_URI = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
public const C14N_EXCL_URI = 'http://www.w3.org/2001/10/xml-exc-c14n#';

// Caso especial Módulo 11
public const RUC_ESPECIAL_SET = '88888801';
public const DV_ESPECIAL_SET = '5';

// Ambientes
public const AMBIENTE_TEST = 1;
public const AMBIENTE_PRODUCCION = 2;

// Sistema de facturación
public const SISTEMA_CLIENTE = 1;
public const SISTEMA_SET = 2;
}

4.6 — Service Provider recomendado

<?php // app/Providers/SifenServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Domains\Sifen\Http\SifenHttpClient;
use App\Domains\Sifen\Support\XmlSigner;

class SifenServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(SifenHttpClient::class, fn() => new SifenHttpClient(
pfxPath: config('sifen.certificado_path'),
pfxPassword: config('sifen.certificado_password'),
));

$this->app->singleton(XmlSigner::class, fn() => new XmlSigner(
pfxPath: config('sifen.certificado_path'),
pfxPassword: config('sifen.certificado_password'),
));
}
}
<?php // config/sifen.php
return [
'ambiente' => env('SIFEN_AMBIENTE', 1), // 1=test, 2=prod
'certificado_path' => env('SIFEN_CERT_PATH'),
'certificado_password' => env('SIFEN_CERT_PASSWORD'),
'ruc_emisor' => env('SIFEN_RUC'),
'establecimiento' => env('SIFEN_ESTABLECIMIENTO', '001'),
'punto_expedicion' => env('SIFEN_PUNTO_EXP', '001'),
];

Fin del SIFEN_TYPES_BIBLE.md — Generado desde análisis exhaustivo del código Java fuente Versión del documento: 1.0.0 | Fecha: 2026-03-03