Skip to content

Migrar desde otro proveedor

Esta guía te ayuda a migrar a UruFactura SDK desde diferentes puntos de partida, ya sea que estés usando una solución propietaria, integrando SOAP directamente, o usando otra librería.


Sin dependencias de vendors

100% open-source y MIT. No hay licencias, suscripciones ni lock-in con ningún proveedor.

API idiomática en C#

Objetos tipados, métodos async/await, DI-friendly. No más SOAP ni XML manual.

Mantenido con .NET 10

Soporte para las últimas versiones de .NET. Sin librerías legacy ni WCF.

Todo incluido

XML, firma digital, SOAP, CAE, PDFs. Una sola dependencia.


Si actualmente construís los XML y llamadas SOAP a mano:

// ❌ Antes: construir XML manualmente y llamar SOAP
var xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
<CFE xmlns=""http://www.dgi.gub.uy/wdgi/CFEv1"">
<eTck>
<TmstFirma>{DateTime.UtcNow:o}</TmstFirma>
<Encabezado>
<IdDoc>
<TipoCFE>101</TipoCFE>
<Serie>A</Serie>
<Nro>1</Nro>
...
</IdDoc>
</Encabezado>
...
</eTck>
</CFE>";
// Firmar XML con XmlDsig... (código extenso)
var soapEnvelope = WrapInSoapEnvelope(signedXml);
var response = await httpClient.PostAsync(dgiEndpoint, soapContent);
// Parsear respuesta SOAP manualmente...
// ✅ Después: API de alto nivel
var eticket = client.CrearETicket();
eticket.Numero = 1;
eticket.Detalle.Add(new LineaDetalle
{
NroLinea = 1,
NombreItem = "Servicio",
Cantidad = 1,
PrecioUnitario = 1000m,
IndFactIva = TipoIva.Basico,
});
var respuesta = await client.EnviarCfeAsync(eticket);

Migración desde una solución ERP propietaria

Section titled “Migración desde una solución ERP propietaria”

Si estás migrando desde un módulo de facturación electrónica de un ERP (Biscuit, Pragma, ContaPyme, etc.):

Tu sistema actualUruFactura SDK
Comprobante / DocumentoCfe (base) + ETicket, EFactura, etc.
Línea de artículo / ítemLineaDetalle
Proveedor / ReceptorReceptor
Rango CAE / TalonarioCae con RangoDesde / RangoHasta
Estado del comprobanteRespuestaDgi.Exitoso + RespuestaDgi.Codigo
Representación impresaclient.GenerarPdfA4() / GenerarPdfTermico()
  1. Mantener ambos sistemas en paralelo

    No apagues el sistema anterior hasta validar el nuevo en homologación.

  2. Mapear los tipos de CFE

    // Mapeo desde tu sistema a TipoCfe
    TipoCfe MapearTipo(string tipoSistemaAnterior) => tipoSistemaAnterior switch
    {
    "TICKET" => TipoCfe.ETicket,
    "FACTURA" => TipoCfe.EFactura,
    "NC_TICKET" => TipoCfe.NotaCreditoETicket,
    "NC_FACTURA" => TipoCfe.NotaCreditoEFactura,
    _ => throw new ArgumentException($"Tipo desconocido: {tipoSistemaAnterior}")
    };
  3. Adaptar la estructura de datos

    // Convertir entidad de tu sistema a LineaDetalle del SDK
    static LineaDetalle ConvertirLinea(MiLineaFactura linea, int nroLinea) =>
    new LineaDetalle
    {
    NroLinea = nroLinea,
    NombreItem = linea.DescripcionProducto,
    Cantidad = linea.Cantidad,
    PrecioUnitario = linea.PrecioUnitario,
    IndFactIva = linea.EsExento ? TipoIva.Exento
    : linea.IvaMinimo ? TipoIva.Minimo
    : TipoIva.Basico,
    };
  4. Implementar una capa de servicio

    public class FacturacionService
    {
    private readonly UruFacturaClient _client;
    public async Task<ResultadoEmision> EmitirAsync(ComprobanteDTO dto)
    {
    var cfe = dto.Tipo switch
    {
    "TICKET" => (Cfe)_client.CrearETicket(),
    "FACTURA" => _client.CrearEFactura(),
    _ => throw new ArgumentException($"Tipo no soportado: {dto.Tipo}")
    };
    cfe.Numero = dto.Numero;
    if (dto.Receptor != null)
    {
    cfe.Receptor = new Receptor
    {
    Documento = dto.Receptor.Rut,
    RazonSocial = dto.Receptor.Nombre,
    Direccion = dto.Receptor.Direccion,
    Ciudad = dto.Receptor.Ciudad,
    };
    }
    int nroLinea = 1;
    foreach (var linea in dto.Lineas)
    cfe.Detalle.Add(ConvertirLinea(linea, nroLinea++));
    var respuesta = await _client.EnviarCfeAsync(cfe);
    return new ResultadoEmision
    {
    Exitoso = respuesta.Exitoso,
    Codigo = respuesta.Codigo,
    Mensaje = respuesta.Mensaje,
    PdfA4 = respuesta.Exitoso ? _client.GenerarPdfA4(cfe) : null,
    };
    }
    }
  5. Probar en homologación

    Reproducí los escenarios más comunes de tu operación: ventas simples, notas de crédito, exportación.

  6. Migrar los CAEs

    Solicitá nuevos CAEs en DGI o trasladá los existentes. Registralos con:

    client.Cae.RegistrarCae(new Cae { ... });
  7. Cambiar a producción

    Ambiente = Ambiente.Produccion

Si estás usando otra librería .NET de facturación electrónica uruguaya:

OperaciónLibrería genéricaUruFactura SDK
Crear comprobantenew Comprobante(tipo)client.CrearETicket()
Agregar ítemcomprobante.AddItem(...)cfe.Detalle.Add(new LineaDetalle {...})
Firmar XMLfirma.Sign(xml, cert)Automático en EnviarCfeAsync
Enviar a DGIsoap.Send(xml)await client.EnviarCfeAsync(cfe)
Generar PDFpdf.Render(comprobante)client.GenerarPdfA4(cfe)
Estado CFEsoap.ConsultarEstado(id)await client.ConsultarEstadoCfeAsync(cfe)

Antes de ir a producción, verificá:

  • Certificado digital cargado y funcionando en el nuevo sistema
  • CAEs registrados para todos los tipos de CFE a emitir
  • Ambiente de homologación testeado con los tipos de CFE que usás
  • Reporte Diario enviado exitosamente en las pruebas
  • PDFs generados y verificados visualmente
  • Manejo de errores implementado (rechazos DGI, errores de red)
  • Archivo de XMLs configurado (almacenamiento durable, 5+ años)
  • Monitoreo de CAEs implementado (alertas de vencimiento/agotamiento)
  • Secretos del certificado en gestión segura (variables de entorno / Key Vault)
  • Ambiente cambiado a Producción antes del go-live