SSDDO.ECF_DGII.SDK 4.0.0

dotnet add package SSDDO.ECF_DGII.SDK --version 4.0.0
                    
NuGet\Install-Package SSDDO.ECF_DGII.SDK -Version 4.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SSDDO.ECF_DGII.SDK" Version="4.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SSDDO.ECF_DGII.SDK" Version="4.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SSDDO.ECF_DGII.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SSDDO.ECF_DGII.SDK --version 4.0.0
                    
#r "nuget: SSDDO.ECF_DGII.SDK, 4.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SSDDO.ECF_DGII.SDK@4.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SSDDO.ECF_DGII.SDK&version=4.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SSDDO.ECF_DGII.SDK&version=4.0.0
                    
Install as a Cake Tool

DGII ECF

Paquetes
SDK NuGet Downloads

SDK oficial para integrar la facturación electrónica (e-CF) en República Dominicana a través del servicio ECF SSD.

Qué cambió en v3

Las versiones anteriores (v1, v2) requerían que cada empresa implementara la comunicación directa con la DGII: manejo de certificados, firmado de XML, semilla/token, envío de comprobantes, manejo de errores, reintentos, almacenamiento, etc. Todo eso era responsabilidad del desarrollador.

La v3 cambia el enfoque completamente. Ahora el SDK se conecta a la plataforma ECF SSD, que se encarga de:

  • ✅ Firmado de comprobantes (XML signing)
  • ✅ Autenticación con la DGII (semilla/token)
  • ✅ Envío y recepción de e-CF
  • ✅ Validación emisor-receptor
  • ✅ Almacenamiento seguro
  • ✅ Reintentos automáticos
  • ✅ Manejo de certificados digitales

Tu único trabajo es: registrarte en ecf.ssd.com.do, completar la certificación DGII, obtener tu API key, y enviar tus comprobantes con este SDK.

Comenzar

1. Regístrate en ecf.ssd.com.do

Crea tu cuenta y obtén tu API Key. Luego contacta al equipo de ECF SSD para integrar y certificar tu sistema (la certificación es para tu plataforma, no para las empresas de tus clientes). Una vez certificado, podrás usar el ambiente de producción. Si vienes de otro proveedor, ECF SSD soporta migración.

2. Instala el paquete

dotnet add package SSDDO.ECF_DGII.SDK

3. Envía tu primer comprobante

using EcfDgii.Client;
using EcfDgii.Client.Generated.Models;

// Configura el cliente con tu API key (JWT obtenido en ecf.ssd.com.do)
var client = new EcfClient(new EcfClientOptions
{
    ApiKey = "tu-jwt-token",        // o usa la variable de entorno ECF_API_KEY
    Environment = EcfEnvironment.Prod
});

// Construye el comprobante
var ecf = new ECF
{
    Encabezado = new Encabezado
    {
        IdDoc = new IdDoc
        {
            TipoeCF = TipoeCFType.FacturaDeCreditoFiscalElectronica,
            Encf = "E310000000001"
        },
        Emisor = new Emisor
        {
            RncEmisor = "123456789",
            RazonSocialEmisor = "Mi Empresa SRL",
            DireccionEmisor = "Calle Principal #1, Santo Domingo",
            FechaEmision = new Date(2026, 1, 10)
        },
        Totales = new Totales
        {
            // montos, ITBIS, etc.
        }
    },
    DetallesItems = new List<Item>
    {
        new Item
        {
            NombreItem = "Servicio de consultoría",
            IndicadorFacturacion = IndicadorFacturacionType.NoFacturable_18Percent,
            CantidadItem = new UntypedDouble(1),
            PrecioUnitarioItem = new UntypedDouble(10000.00),
            MontoItem = new UntypedDouble(10000.00)
        }
    }
};

// Envía y espera el resultado
// SendEcfAsync hace todo: enruta al endpoint correcto, envía, y espera hasta que la DGII responda
try
{
    EcfResponse resultado = await client.SendEcfAsync(ecf);
    Console.WriteLine($"Comprobante procesado exitosamente!");
    Console.WriteLine($"Estado: {resultado.Progress}");
    Console.WriteLine($"Mensaje DGII: {resultado.Mensaje}");
    Console.WriteLine($"Código seguridad: {resultado.CodSec}");
    Console.WriteLine($"URL impresión: {resultado.ImpresionUrl}");
}
catch (EcfException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
    Console.WriteLine($"Detalle: {ex.Response.Errors}");
}

Eso es todo. No necesitas manejar XML, firmar documentos, obtener semillas, ni reintentar requests. El servicio ECF SSD se encarga de todo.

Respuesta (EcfResponse)

Cuando SendEcfAsync termina exitosamente, retorna un EcfResponse con toda la información que necesitas para cumplir con los requisitos de la DGII:

Campo Tipo Descripción
ImpresionUrl string URL para generar el código QR requerido por la DGII en el comprobante impreso
CodSec string Código de seguridad — debe aparecer en el comprobante impreso
FechaFirma DateTimeOffset Fecha y hora en que el comprobante fue firmado digitalmente
Estatus EcfEstado Estado asignado por la DGII (Aceptado, AceptadoCondicional, Rechazado)
Progress EcfProgress Estado del procesamiento (Queued, Sending, Polling, Finished, Error)
Encf string Número de comprobante fiscal electrónico (eNCF)
RncEmisor string RNC del emisor
Mensaje string Mensaje de respuesta de la DGII
Errors string Detalle de errores (si los hay)
MontoTotal double Monto total del comprobante
SecuenciaUtilizada bool Indica si la secuencia fue utilizada
DgiiEnvironment DGIIEnvironment Ambiente DGII donde fue procesado
MessageId string Identificador único del mensaje

QR e Impresión del Comprobante

La DGII requiere que los comprobantes impresos incluyan un código QR. El ImpresionUrl contiene la URL que debe codificarse como QR:

EcfResponse resultado = await client.SendEcfAsync(ecf);

// Datos necesarios para el comprobante impreso
string urlQr = resultado.ImpresionUrl;          // codificar como QR
string codigoSeguridad = resultado.CodSec;      // imprimir en el comprobante
DateTimeOffset fechaFirma = resultado.FechaFirma; // fecha de firma digital

// Verificar aceptación
if (resultado.Estatus == EcfEstado.Aceptado)
{
    Console.WriteLine("Comprobante aceptado por la DGII");
    Console.WriteLine($"QR URL: {urlQr}");
    Console.WriteLine($"Código seguridad: {codigoSeguridad}");
    Console.WriteLine($"Firmado: {fechaFirma}");
}

Configuración

Variables de Entorno

Variable Descripción
ECF_API_KEY JWT Bearer token (obtenido en ecf.ssd.com.do)
ECF_API_URL URL base (solo si necesitas override)

Ambientes

Ambiente URL Uso
Test https://api.test.ecfx.ssd.com.do Desarrollo y pruebas
Cert https://api.cert.ecfx.ssd.com.do Proceso de certificación DGII
Prod https://api.prod.ecfx.ssd.com.do Producción

Opciones de Polling

SendEcfAsync espera automáticamente a que la DGII procese el comprobante. Puedes personalizar el comportamiento:

var resultado = await client.SendEcfAsync(ecf, new PollingOptions
{
    InitialDelayMs = 1000,      // espera inicial entre consultas
    MaxDelayMs = 30000,         // espera máxima entre consultas
    MaxRetries = 60,            // máximo de reintentos
    BackoffMultiplier = 2,      // multiplicador exponencial
    TimeoutMs = 120000          // timeout total (2 minutos)
});

Tipos de Comprobantes

TipoeCF Ruta Descripción
FacturaDeCreditoFiscalElectronica /ecf/31 Factura de Crédito Fiscal
FacturaDeConsumoElectronica /ecf/32 Factura de Consumo
NotaDeDebitoElectronica /ecf/33 Nota de Débito
NotaDeCreditoElectronica /ecf/34 Nota de Crédito
ComprasElectronico /ecf/41 Compras
GastosMenoresElectronico /ecf/43 Gastos Menores
RegimenesEspecialesElectronico /ecf/44 Regímenes Especiales
GubernamentalElectronico /ecf/45 Gubernamental
ComprobanteDeExportacionesElectronico /ecf/46 Exportaciones
ComprobanteParaPagosAlExteriorElectronico /ecf/47 Pagos al Exterior

Ejemplo completo — Factura de Crédito Fiscal (e-CF 31)

El SDK genera modelos específicos por tipo de comprobante (Ecf31ECF, Ecf31Encabezado, etc.) con todas las propiedades tipadas. Este es un ejemplo completo de una Factura de Crédito Fiscal con ITBIS, impuestos adicionales, descuentos y montos no facturables:

{
  "encabezado": {
    "idDoc": {
      "encf": "E310000051630",
      "TipoeCF": "FacturaDeCreditoFiscalElectronica",
      "TipoPago": "Contado",
      "TipoIngresos": "01",
      "TablaFormasPago": [
        {
          "FormaPago": "Efectivo",
          "MontoPago": 1015.25
        }
      ],
      "IndicadorMontoGravado": "ConITBISIncluido",
      "FechaVencimientoSecuencia": "2028-12-31T00:00:00"
    },
    "Emisor": {
      "RNCEmisor": "131460941",
      "FechaEmision": "2026-01-10",
      "DireccionEmisor": "AVE. ISABEL AGUIAR NO. 269, ZONA INDUSTRIAL DE HERRERA",
      "RazonSocialEmisor": "DOCUMENTOS ELECTRONICOS DE 02"
    },
    "Totales": {
      "ITBIS1": 18,
      "MontoGravadoI1": 762.71,
      "MontoGravadoTotal": 762.71,
      "TotalITBIS1": 137.29,
      "TotalITBIS": 137.29,
      "MontoNoFacturable": 100.0,
      "ImpuestosAdicionales": [
        {
          "TipoImpuesto": "002",
          "TasaImpuestoAdicional": 2,
          "OtrosImpuestosAdicionales": 15.25
        }
      ],
      "MontoImpuestoAdicional": 15.25,
      "MontoTotal": 1015.25,
      "MontoPeriodo": 1015.25
    },
    "Version": "Version1_0",
    "Comprador": {
      "RNCComprador": "131880681",
      "RazonSocialComprador": "DOCUMENTOS ELECTRONICOS DE 03"
    }
  },
  "DetallesItems": [
    {
      "MontoItem": 1016.95,
      "NombreItem": "Iphone 18 Pro max",
      "NumeroLinea": 1,
      "CantidadItem": 1,
      "UnidadMedida": "Unidad",
      "PrecioUnitarioItem": 1016.95,
      "IndicadorFacturacion": "ITBIS1_18Percent",
      "IndicadorBienoServicio": "Bien",
      "TablaImpuestoAdicional": [
        {
          "TipoImpuesto": "002"
        }
      ]
    },
    {
      "MontoItem": 100.0,
      "NombreItem": "Costo de Envío",
      "NumeroLinea": 2,
      "CantidadItem": 1,
      "UnidadMedida": "Unidad",
      "PrecioUnitarioItem": 100.0,
      "IndicadorFacturacion": "NoFacturable_18Percent",
      "IndicadorBienoServicio": "Servicio"
    }
  ],
  "DescuentosORecargos": [
    {
      "TipoValor": "$",
      "TipoAjuste": "D",
      "NumeroLinea": 1,
      "MontoDescuentooRecargo": 84.75,
      "DescripcionDescuentooRecargo": "Descuento",
      "IndicadorFacturacionDescuentooRecargo": "ITBIS1_18Percent"
    }
  ]
}

Arquitectura Backend / Frontend

En la mayoría de implementaciones, el backend maneja la lógica de negocio (validación, almacenamiento, conversión) y envía el comprobante. El frontend obtiene un token de solo lectura para consultar el estado directamente:

var ecfClient = new EcfClient(new EcfClientOptions
{
    ApiKey = backendJwtToken,
    Environment = EcfEnvironment.Prod
});

// Endpoint de facturación — tu lógica de negocio + envío a ECF SSD
[HttpPost("/api/v1/invoices")]
public async Task<IActionResult> CreateInvoice(CreateInvoiceRequest request)
{
    // 1. Validar y guardar la factura en tu base de datos
    var invoice = await _invoiceService.ValidateAndSave(request);

    // 2. Convertir tu factura interna al formato ECF
    var ecf = _mapper.ToEcf(invoice);

    // 3. Enviar a ECF SSD (sin polling)
    var response = await ecfClient.Api.Ecf.E31[rnc].PostAsync(ecf);
    await _invoiceService.UpdateMessageId(invoice.Id, response.MessageId);

    return Ok(new { invoice.Id, response.MessageId });
}

// Endpoint separado: generar token de lectura para el frontend
[HttpGet("/api/v1/ecf-token")]
public async Task<IActionResult> GetEcfToken()
{
    var apiKey = await ecfClient.Api.ApiKey.PostAsync(new NewCompanyApiKeyRequest
    {
        // token restringido al tenant y RNC, solo lectura
    });
    return Ok(new { apiKey.Token });
}

El frontend almacena el token de forma segura, lo renueva al recibir 401 o al expirar, y consulta ECF SSD directamente sin pasar por el backend. Ver README principal para el diagrama completo y ejemplo de frontend.

SendEcfAsync es una conveniencia que encapsula envío + polling en una sola llamada. Ideal para scripts o backends simples sin frontend.

Acceso Directo al API

Para operaciones que no cubre SendEcfAsync, usa client.Api directamente:

// Consultar comprobantes
var comprobantes = await client.Api.Ecf["123456789"].GetAsync();

// Buscar un comprobante específico
var resultado = await client.Api.Ecf["123456789"]["E310000000001"].GetAsync();

// Consultar estado en la DGII
var estado = await client.Api.Dgii["123456789"].Consultaestado.Estado.GetAsync(config =>
{
    config.QueryParameters.RncEmisor = "123456789";
    config.QueryParameters.NcfElectronico = "E310000000001";
    config.QueryParameters.RncComprador = "987654321";
    config.QueryParameters.CodigoSeguridad = "ABC123";
});

// Gestión de empresas
var empresas = await client.Api.Company.GetAsync();
await client.Api.Company.PutAsync(new UpsertCompanyRequest { /* ... */ });

// Aprobación comercial
await client.Api.Ecf.Aprobacioncomercial["123456789"]["E310000000001"]
    .PostAsync(new SendAcecfRequest { /* ... */ });

// Anulación de rangos
await client.Api.Ecf.Anularrango["123456789"]
    .PostAsync(new AnulacionRequest { /* ... */ });

// Estatus de servicios DGII
var estatus = await client.Api.Dgii["123456789"].Estatusservicios.ObtenerEstatus.GetAsync();

Manejo de Errores

Excepción Cuándo
EcfException El comprobante fue procesado pero la DGII lo rechazó
PollingMaxRetriesException Se agotaron los reintentos esperando respuesta
PollingTimeoutException Se agotó el timeout esperando respuesta
try
{
    var resultado = await client.SendEcfAsync(ecf);
}
catch (EcfException ex)
{
    // La DGII rechazó el comprobante
    Console.WriteLine($"Rechazado: {ex.Response.Errors}");
    Console.WriteLine($"Estado DGII: {ex.Response.Estatus}");
}
catch (PollingTimeoutException)
{
    // El comprobante fue enviado pero no se recibió respuesta a tiempo
    // Puedes consultar el estado después con client.Api.Ecf[rnc][encf].GetAsync()
}

Cancelación

Todas las operaciones async soportan CancellationToken:

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
var resultado = await client.SendEcfAsync(ecf, cancellationToken: cts.Token);

Migración desde v2

v2 (implementación propia) v3 (ECF SSD)
Manejar certificado digital (.p12/.pfx) Subir certificado una vez en ecf.ssd.com.do
Obtener semilla y firmarla No necesario — el servicio lo maneja
Serializar a XML y firmar No necesario — envías JSON, el servicio firma
Enviar XML a la DGII await client.SendEcfAsync(ecf)
Parsear respuesta XML Respuesta tipada EcfResponse
Implementar reintentos Polling automático con backoff exponencial
SSDDO.ECF_DGII.Models + SSDDO.ECF_DGII.SDK Solo SSDDO.ECF_DGII.SDK v3

Por qué ECF SSD

Con la v2 tenías la librería, pero aún debías implementar seguridad, almacenamiento, firmado, manejo de certificados, módulo de recepción, reintentos, y más.

Con la v3 y ECF SSD:

  • Instalas el paquete NuGet
  • Te registras y certificas en ecf.ssd.com.do
  • Envías comprobantes con una línea de código
  • El servicio se encarga del firmado, validación, envío a DGII, almacenamiento, y más

Para más información visita https://ecf.ssd.com.do


🇩🇴 Hecho con plátano power

© Smart Software Development SSD SRL 2026

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.0.0 351 5/7/2026
3.1.1 104 5/6/2026
3.1.0 1,155 3/24/2026
3.0.0 114 3/23/2026
2.0.1 792 6/30/2024
2.0.0 218 6/30/2024
1.2.2 229 3/28/2024
1.2.1 228 3/24/2024
1.2.0 235 3/23/2024
1.1.0 249 3/13/2024