Método Sync — Solo Backend

El método más simple de integración. Tu backend envía el comprobante usando sendEcf y espera la respuesta completa de la DGII en una sola llamada. Ideal para sistemas donde el usuario puede esperar unos segundos por la confirmación (POS, ERP, sistemas de escritorio).

¿Cuándo usar este método? — Cuando tu sistema puede esperar la respuesta (en promedio 300ms a 2 segundos). El backend maneja todo: envío, polling y resultado. El usuario recibe el código de seguridad y QR al finalizar.

Cómo funciona

El método sendEcf encapsula toda la complejidad en una sola llamada:

1Tu Sistema llama sendEcf(ecf)
SDK determina el endpoint correcto (/ecf/31, /ecf/32, etc.)
2ECF SSD firma el XML con tu certificado digital
3ECF SSD se autentica con la DGII (semilla → token)
4ECF SSD envía el e-CF a la DGII
5Polling automático con backoff exponencial hasta obtener respuesta
Retorna EcfResponse con código de seguridad, URL QR, estado, etc.

Estructura del Comprobante (ECF)

Todos los comprobantes siguen la misma estructura base. Solo cambia el TipoeCF y los campos específicos de cada tipo:

SecciónCampos principales
Encabezado.IdDocTipoeCF, eNCF
Encabezado.EmisorRNCEmisor, RazonSocialEmisor, DireccionEmisor, FechaEmision
Encabezado.CompradorRNCComprador, RazonSocialComprador (requerido en E31)
Encabezado.TotalesMontoGravadoTotal, TotalITBIS, MontoTotal, etc.
DetallesItems[]NombreItem, CantidadItem, PrecioUnitarioItem, MontoItem, IndicadorFacturacion

Ejemplo completo — Factura de Crédito Fiscal (E31)

La E31 es la más común. Requiere datos del comprador (RNC) y soporta ITBIS:

TypeScript

typescript
import { EcfClient } from "@ssddo/ecf-sdk";
const client = new EcfClient({
apiKey: "tu-jwt-token",
environment: "prod",
});
const resultado = await client.sendEcf("rnc-empresa", {
encabezado: {
idDoc: {
tipoeCF: "FacturaDeCreditoFiscalElectronica",
encf: "E310000000001",
},
emisor: {
rncEmisor: "123456789",
razonSocialEmisor: "Mi Empresa SRL",
direccionEmisor: "Calle Principal #1, Santo Domingo",
fechaEmision: new Date().toISOString(),
},
comprador: {
rncComprador: "987654321",
razonSocialComprador: "Cliente Corp SRL",
},
totales: {
montoGravadoTotal: 10000.00,
totalITBIS: 1800.00,
montoTotal: 11800.00,
},
},
detallesItems: [
{
nombreItem: "Servicio de consultoría",
indicadorFacturacion: 3, // Gravado 18%
cantidadItem: 1,
precioUnitarioItem: 10000.00,
montoItem: 10000.00,
},
],
});
// Datos para impresión del comprobante
console.log(resultado.codSec); // Código de seguridad
console.log(resultado.impresionUrl); // URL para código QR
console.log(resultado.fechaFirma); // Fecha de firma digital
console.log(resultado.estatus); // "Aceptado" | "AceptadoCondicional" | "Rechazado"

Python

python
from ecf_dgii import EcfClient
async with EcfClient(
api_key="tu-jwt-token",
environment="prod",
) as client:
resultado = await client.send_ecf("rnc-empresa", {
"encabezado": {
"idDoc": {
"tipoeCF": "FacturaDeCreditoFiscalElectronica",
"encf": "E310000000001",
},
"emisor": {
"rncEmisor": "123456789",
"razonSocialEmisor": "Mi Empresa SRL",
"direccionEmisor": "Calle Principal #1, Santo Domingo",
},
"comprador": {
"rncComprador": "987654321",
"razonSocialComprador": "Cliente Corp SRL",
},
"totales": {
"montoGravadoTotal": 10000.00,
"totalITBIS": 1800.00,
"montoTotal": 11800.00,
},
},
"detallesItems": [
{
"nombreItem": "Servicio de consultoría",
"indicadorFacturacion": 3,
"cantidadItem": 1,
"precioUnitarioItem": 10000.00,
"montoItem": 10000.00,
},
],
})
print(resultado.cod_sec)
print(resultado.impresion_url)
print(resultado.fecha_firma)

C# (.NET)

csharp
var client = new EcfClient(new EcfClientOptions
{
ApiKey = "tu-jwt-token",
Environment = EcfEnvironment.Prod
});
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 = DateTimeOffset.Now
},
Comprador = new Comprador
{
RncComprador = "987654321",
RazonSocialComprador = "Cliente Corp SRL"
},
Totales = new Totales
{
MontoGravadoTotal = 10000.00m,
TotalITBIS = 1800.00m,
MontoTotal = 11800.00m
}
},
DetallesItems = new List<Item>
{
new Item
{
NombreItem = "Servicio de consultoría",
IndicadorFacturacion = IndicadorFacturacionType.NoFacturable_18Percent,
CantidadItem = 1,
PrecioUnitarioItem = 10000.00m,
MontoItem = 10000.00m
}
}
};
EcfResponse resultado = await client.SendEcfAsync(ecf);
Console.WriteLine($"Código: {resultado.CodSec}");
Console.WriteLine($"QR: {resultado.ImpresionUrl}");
Console.WriteLine($"Estado: {resultado.Progress}");

Ejemplo — Factura de Consumo (E32)

La E32 no requiere datos del comprador (ventas a consumidor final):

typescript
const resultado = await client.sendEcf("rnc-empresa", {
encabezado: {
idDoc: {
tipoeCF: "FacturaDeConsumoElectronica",
encf: "E320000000001",
},
emisor: {
rncEmisor: "123456789",
razonSocialEmisor: "Mi Tienda SRL",
fechaEmision: new Date().toISOString(),
},
// Sin comprador — es consumo final
totales: {
montoGravadoTotal: 500.00,
totalITBIS: 90.00,
montoTotal: 590.00,
},
},
detallesItems: [
{
nombreItem: "Producto A",
indicadorFacturacion: 3,
cantidadItem: 2,
precioUnitarioItem: 250.00,
montoItem: 500.00,
},
],
});

Ejemplo — Nota de Crédito (E34)

Las notas de crédito referencian el comprobante original que se desea anular o modificar:

typescript
const resultado = await client.sendEcf("rnc-empresa", {
encabezado: {
idDoc: {
tipoeCF: "NotaDeCreditoElectronica",
encf: "E340000000001",
},
emisor: {
rncEmisor: "123456789",
razonSocialEmisor: "Mi Empresa SRL",
fechaEmision: new Date().toISOString(),
},
comprador: {
rncComprador: "987654321",
razonSocialComprador: "Cliente Corp SRL",
},
totales: {
montoGravadoTotal: 10000.00,
totalITBIS: 1800.00,
montoTotal: 11800.00,
},
},
detallesItems: [
{
nombreItem: "Servicio de consultoría (anulación)",
indicadorFacturacion: 3,
cantidadItem: 1,
precioUnitarioItem: 10000.00,
montoItem: 10000.00,
},
],
// Referencia al comprobante original
informacionReferencia: {
ncfModificado: "E310000000001",
fechaNCFModificado: "2026-03-20",
codigoModificacion: 1, // Anulación total
},
});

Respuesta (EcfResponse)

Al completarse el envío, recibes un EcfResponse con los datos para cumplir los requisitos de impresión de la DGII:

CampoDescripción
ImpresionUrlURL para generar el código QR (requerido por la DGII en el comprobante impreso)
CodSecCódigo de seguridad — debe aparecer en el comprobante impreso
FechaFirmaFecha y hora de la firma digital
EstatusAceptado, AceptadoCondicional, Rechazado
ProgressQueuedSendingPollingFinished / Error
EncfNúmero de comprobante fiscal electrónico asignado
MensajeMensaje de respuesta de la DGII
ErrorsDetalle de errores (si los hay)
MontoTotalMonto total del comprobante
SecuenciaUtilizadaIndica si la secuencia fue utilizada

QR e Impresión

La DGII requiere que todo comprobante impreso incluya un código QR, el código de seguridad y la fecha de firma:

typescript
const resultado = await client.sendEcf("rnc", ecf);
// Estos tres datos son obligatorios en el comprobante impreso
const urlQr = resultado.impresionUrl; // Codificar como QR
const codigoSeg = resultado.codSec; // Imprimir como texto
const fechaFirma = resultado.fechaFirma; // Imprimir como texto

Ventajas del método sync: Simplicidad — una sola llamada, una sola respuesta. No necesitas manejar tokens frontend ni polling manual.

Desventaja: El backend queda bloqueado durante el polling (en promedio 300ms a 2 segundos, dependiendo del tamaño del request y carga del servidor). Para aplicaciones web de alta concurrencia, considere el método async (Frontend/Backend).