Skip to content

Uso Rápido

En esta guía vas a emitir y enviar tu primer e-Ticket a la DGI (en homologación).

Configurar → Registrar CAE → Emitir (valida, numera, firma) → Enviar → Consultar resultado → PDF
… y al cierre del día: Reporte diario

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);

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),
});

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 },
],
});

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).


// 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}");

Con el paquete UruFactura.Pdf:

await File.WriteAllBytesAsync($"eticket_{emitido.Numero:D8}.pdf", CfePdf.GenerarA4(emitido)); // A4
await File.WriteAllBytesAsync($"eticket_{emitido.Numero:D8}_80mm.pdf", CfePdf.GenerarTermico(emitido)); // ticket

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)");