Uso Rápido
En esta guía vas a emitir y enviar tu primer e-Ticket a la DGI (en homologación).
El flujo
Section titled “El flujo”Configurar → Registrar CAE → Emitir (valida, numera, firma) → Enviar → Consultar resultado → PDF … y al cierre del día: Reporte diarioPaso 1: Cliente
Section titled “Paso 1: Cliente”using UruFactura;
var config = new UruFacturaConfig{ Emisor = new Emisor { Rut = "219999820013", RazonSocial = "Mi Empresa S.A.", DomicilioFiscal = "Av. 18 de Julio 1234", Ciudad = "Montevideo", Departamento = "Montevideo", }, Ambiente = Ambiente.Homologacion, RutaCertificado = "/ruta/al/certificado.p12", PasswordCertificado = Environment.GetEnvironmentVariable("CERT_PASSWORD"),};
using var client = new UruFacturaClient(config);Paso 2: Registrar el CAE
Section titled “Paso 2: Registrar el CAE”El CAE es el rango de números que la DGI autoriza para un tipo de CFE y una serie.
await client.RegistrarCaeAsync(new Cae{ NumeroAutorizacion = "90110001945", // CAE_ID entregado por la DGI TipoCfe = TipoCfe.ETicket, Serie = "A", RangoDesde = 1, RangoHasta = 1000, FechaVencimiento = new DateOnly(2027, 12, 31),});Paso 3: Emitir
Section titled “Paso 3: Emitir”Cfe describe el comprobante (es inmutable). EmitirAsync lo valida, le asigna el próximo número del CAE, arma el XML, lo firma y lo registra.
var emitido = await client.EmitirAsync(new Cfe(TipoCfe.ETicket){ Detalle = [ new LineaDetalle { NombreItem = "Servicio de consultoría", Cantidad = 1, PrecioUnitario = 5000m, IndFactIva = TipoIva.Basico }, ],});var emitido = await client.EmitirAsync(new Cfe(TipoCfe.EFactura){ Receptor = new Receptor { Documento = "214844360018", RazonSocial = "Empresa Compradora S.A.", Direccion = "Bulevar España 2345", Ciudad = "Montevideo", }, Detalle = [ new LineaDetalle { NombreItem = "Producto A", Cantidad = 10, PrecioUnitario = 500m, IndFactIva = TipoIva.Basico }, new LineaDetalle { NombreItem = "Producto B", Cantidad = 5, PrecioUnitario = 200m, IndFactIva = TipoIva.Minimo }, ],});var emitido = await client.EmitirAsync(new Cfe(TipoCfe.NotaCreditoETicket){ Referencias = [ new RefCfe { TipoCfe = TipoCfe.ETicket, Serie = "A", NroCfe = 42, FechaCfe = new DateOnly(2025, 6, 15), MontoCfeRef = 1220m, // total del CFE original (obligatorio desde CFE v25.01) MonedaCfeRef = Moneda.PesoUruguayo, // moneda del CFE original (obligatoria) Razon = "Devolución de mercadería", }, ], Detalle = [new LineaDetalle { NombreItem = "Devolución - Producto X", Cantidad = 2, PrecioUnitario = 300m }],});Si el CFE no es válido, EmitirAsync lanza CfeValidationException (con la lista en Errores: campo y motivo de cada uno) sin consumir números. Para revisar sin emitir: client.Validar(cfe).
Paso 4: Enviar y consultar el resultado
Section titled “Paso 4: Enviar y consultar el resultado”// 1) La DGI acusa recibo del sobre (AS = recibido, BS/BA = rechazado)var acuse = await client.EnviarAsync(emitido);if (!acuse.Recibido){ Console.WriteLine($"❌ {acuse.Mensaje}"); // "Sobre rechazado (BS): motivos" return;}
// 2) Resultado del comprobante: EstadoCfe.Aceptado (AE), Rechazado (BE), Observado (CE)var estado = await client.ConsultarEnvioAsync(acuse);Console.WriteLine(emitido.AceptadoPorDgi ? "✅ Aceptado" : $"❌ [{emitido.EstadoDgi}]: {emitido.MensajeDgi}");Paso 5: Representación impresa (PDF)
Section titled “Paso 5: Representación impresa (PDF)”Con el paquete UruFactura.Pdf:
await File.WriteAllBytesAsync($"eticket_{emitido.Numero:D8}.pdf", CfePdf.GenerarA4(emitido)); // A4await File.WriteAllBytesAsync($"eticket_{emitido.Numero:D8}_80mm.pdf", CfePdf.GenerarTermico(emitido)); // ticketReporte diario
Section titled “Reporte diario”La DGI exige enviar cada día un resumen de los CFE emitidos. Sale del almacenamiento del cliente (todo lo que se emitió con EmitirAsync):
// Usá la fecha de Uruguay (HoraUruguay), no DateTime.Today: el servidor puede estar en UTC.var reporte = await client.EnviarReporteDiarioAsync(HoraUruguay.Hoy().AddDays(-1));Console.WriteLine($"Reporte diario: {reporte.Estado} ({reporte.CantidadCfe} CFE)");Próximos pasos
Section titled “Próximos pasos”Gestión de CAEMonitorear CAEs, persistir la numeración y usar varias instancias.
Certificación DGIProceso de homologación y habilitación en producción.
Migración desde otro proveedor¿Venís de otra solución? Esta guía es para vos.