MSeller LogoECF MSeller
🔍
Integración

Envío de Documentos

Cómo enviar documentos electrónicos en MSeller ECF

Envío de Documentos

Esta sección explica cómo enviar documentos electrónicos utilizando la API de MSeller ECF.

Envío de documentos

Para enviar un documento electrónico a la plataforma, debes realizar una solicitud POST al endpoint correspondiente:

POST /{entorno}/documentos-ecf

Donde {entorno} puede ser:

  • TesteCF (para pruebas)
  • CerteCF (para certificación)
  • eCF (para producción)

Encabezados requeridos

Authorization: Bearer {tu_token}
X-API-KEY: {tu_api_key}
Content-Type: application/json

Cuerpo de la solicitud

El cuerpo de la solicitud debe contener el documento en formato JSON estructurado según las especificaciones detalladas en Formato de Documentos.

Ejemplos de documentos JSON

Ejemplo 1: Factura de Crédito Fiscal con descuento simple

{
  "ECF": {
    "Encabezado": {
      "Version": "1.0",
      "IdDoc": {
        "TipoeCF": "31",
        "eNCF": "E310571508136",
        "FechaVencimientoSecuencia": "31-12-2026",
        "IndicadorEnvioDiferido": "0",
        "IndicadorMontoGravado": "0",
        "TipoIngresos": "05",
        "TipoPago": "2",
        "FechaLimitePago": "07-08-2026",
        "TotalPaginas": 1
      },
      "Emisor": {
        "RNCEmisor": "102320705",
        "RazonSocialEmisor": "Comercial Ejemplo SRL",
        "DireccionEmisor": "Calle Principal No. 123",
        "FechaEmision": "29-06-2025"
      },
      "Comprador": {
        "RNCComprador": "101023122",
        "RazonSocialComprador": "Cliente Prueba SRL"
      },
      "Totales": {
        "MontoGravadoTotal": 540.0,
        "MontoGravadoI1": 540.0,
        "MontoExento": 0,
        "ITBIS1": 18,
        "TotalITBIS": 97.2,
        "TotalITBIS1": 97.2,
        "MontoTotal": 637.2,
        "MontoNoFacturable": 0
      }
    },
    "DetallesItems": {
      "Item": [
        {
          "NumeroLinea": "1",
          "IndicadorFacturacion": "1",
          "NombreItem": "Producto Ejemplo",
          "IndicadorBienoServicio": "1",
          "CantidadItem": 24,
          "UnidadMedida": "43",
          "PrecioUnitarioItem": 25.0,
          "DescuentoMonto": 60.0,
          "TablaSubDescuento": {
            "SubDescuento": [
              {
                "TipoSubDescuento": "%",
                "SubDescuentoPorcentaje": 10.0,
                "MontoSubDescuento": 60.0
              }
            ]
          },
          "MontoItem": 540.0
        }
      ]
    },
    "Paginacion": {
      "Pagina": [
        {
          "PaginaNo": 1,
          "NoLineaDesde": 1,
          "NoLineaHasta": 1,
          "SubtotalMontoGravadoPagina": 540.0,
          "SubtotalMontoGravado1Pagina": 540.0,
          "SubtotalExentoPagina": 0,
          "SubtotalItbisPagina": 97.2,
          "SubtotalItbis1Pagina": 97.2,
          "MontoSubtotalPagina": 637.2,
          "SubtotalMontoNoFacturablePagina": 0
        }
      ]
    },
    "FechaHoraFirma": ""
  }
}

Ejemplo 2: Factura de Consumo con múltiples ITBIS y producto exento

Este ejemplo muestra una factura de consumo (tipo 32) con múltiples productos que incluyen diferentes tasas de ITBIS (18% y 16%) y un producto exento de impuestos.

{
  "ECF": {
    "Encabezado": {
      "Version": "1.0",
      "IdDoc": {
        "TipoeCF": 32,
        "eNCF": "E320004380890",
        "IndicadorEnvioDiferido": 0,
        "IndicadorMontoGravado": 0,
        "TipoIngresos": "01",
        "TipoPago": 1
      },
      "Emisor": {
        "RNCEmisor": "000000000",
        "RazonSocialEmisor": "Empresa Ejemplo SRL",
        "NombreComercial": "Tienda Ejemplo",
        "Sucursal": "SUCURSAL PRINCIPAL",
        "DireccionEmisor": "Calle Principal #100",
        "Municipio": "010100",
        "Provincia": "010000",
        "WebSite": "www.ejemplo.com.do",
        "CodigoVendedor": "VEND001",
        "FechaEmision": "04-11-2025"
      },
      "Comprador": {
        "RNCComprador": "40211111111",
        "RazonSocialComprador": "Juan Pérez",
        "DireccionComprador": "C/ Ejemplo #123",
        "FechaEntrega": "04-11-2025"
      },
      "Totales": {
        "MontoGravadoTotal": 1139.5,
        "MontoGravadoI1": 807.02,
        "MontoGravadoI2": 332.48,
        "MontoExento": 96,
        "ITBIS1": 18,
        "ITBIS2": 16,
        "TotalITBIS": 194.11,
        "TotalITBIS1": 140.91,
        "TotalITBIS2": 53.2,
        "MontoTotal": 1405.39,
        "MontoNoFacturable": 0
      }
    },
    "DetallesItems": {
      "Item": [
        {
          "NumeroLinea": 1,
          "IndicadorFacturacion": 4,
          "NombreItem": "AGUA FONTINA",
          "IndicadorBienoServicio": 1,
          "DescripcionItem": "AGUA FONTINA",
          "CantidadItem": 1,
          "UnidadMedida": 43,
          "PrecioUnitarioItem": 96,
          "MontoItem": 96
        },
        {
          "NumeroLinea": 2,
          "IndicadorFacturacion": 1,
          "NombreItem": "MALTA INDIA 12/1",
          "IndicadorBienoServicio": 1,
          "DescripcionItem": "MALTA INDIA 12/1",
          "CantidadItem": 1,
          "UnidadMedida": 43,
          "PrecioUnitarioItem": 807.02,
          "DescuentoMonto": 24.21,
          "TablaSubDescuento": {
            "SubDescuento": [
              {
                "TipoSubDescuento": "%",
                "SubDescuentoPorcentaje": 3,
                "MontoSubDescuento": 24.21
              }
            ]
          },
          "MontoItem": 807.02
        },
        {
          "NumeroLinea": 3,
          "IndicadorFacturacion": 2,
          "NombreItem": "CAFE BUSTELO CAPSULA 1.7 OZ.",
          "IndicadorBienoServicio": 1,
          "DescripcionItem": "CAFE BUSTELO CAPSULA 1.7 OZ.",
          "CantidadItem": 1,
          "UnidadMedida": 43,
          "PrecioUnitarioItem": 332.48,
          "MontoItem": 332.48
        }
      ]
    },
    "FechaHoraFirma": "03-11-2025 19:26:35"
  }
}

Características destacadas de este ejemplo:

  • Producto exento (Item 1): El agua tiene IndicadorFacturacion: 4 que indica que está exenta de ITBIS
  • Múltiples tasas de ITBIS: Item 2 con ITBIS1 (18%) e Item 3 con ITBIS2 (16%)
  • Descuento aplicado: El Item 2 incluye un descuento del 3%
  • Factura de consumo: TipoeCF: 32 para ventas al consumidor final
  • Información completa del emisor: Incluye sucursal, municipio, provincia y código de vendedor

Nota importante: Para facturas de consumo (tipo 32), puedes omitir el RNC del comprador si es una venta a persona física sin RNC, pero es recomendable incluirlo cuando esté disponible.

Parámetro de validación

Puedes agregar el parámetro validate=true al endpoint para validar el documento antes de enviarlo a la DGII:

POST /{entorno}/documentos-ecf?validate=true

⚠️ IMPORTANTE - Esta opción está en fase de pruebas: Esta opción no está activada por defecto hasta completar la fase de depuración y pruebas. Durante este período, ningún documento será validado automáticamente. Una vez estabilizado el feature, esta validación no será opcional pero será controlada explícitamente mediante el parámetro validate=false.

Cuando este parámetro está presente, MSeller ECF realiza una validación completa del documento verificando que cumpla con todos los requisitos y parámetros necesarios antes de procesarlo y enviarlo a la DGII:

  • Detecta errores de formato antes de registrar el documento
  • Verifica cálculos y totales según las especificaciones de la DGII
  • Valida campos requeridos y sus valores permitidos
  • Comprueba la estructura del documento contra los esquemas XSD oficiales
  • Ahorra secuencias de e-NCF al evitar envíos con errores
  • Debugging eficiente con mensajes de error detallados antes del envío oficial

Respuesta de validación exitosa:

Si el documento pasa todas las validaciones, recibirás una respuesta indicando que el documento es válido:

{
  "valid": true,
  "message": "El documento ha sido validado correctamente y cumple con todos los requisitos de la DGII"
}

Respuesta de validación con errores:

Si se encuentran errores, recibirás un detalle de los problemas encontrados:

{
  "message": " 2 error(s):\n1. [TIPO_ECF_MISMATCH] ECF.Encabezado.IdDoc.TipoeCF: TipoeCF (322) no coincide con el código de tipo del eNCF (32) | Details: {\"expected\":32,\"received\":322,\"encf\":\"E320000000002\"}\n2. [TIPO_ECF_INVALID_LENGTH] ECF.Encabezado.IdDoc.TipoeCF: TipoeCF debe tener 2 dígitos | Details: {\"expected\":2,\"received\":3,\"value\":\"322\"}",
  "code": "ECF_VALIDATION_FAILED",
  "requestId": "fdc9a42b-fbf6-41c4-9985-1c27e312197a",
  "details": {
    "validationErrors": [
      {
        "code": "TIPO_ECF_MISMATCH",
        "field": "ECF.Encabezado.IdDoc.TipoeCF",
        "details": {
          "expected": 32,
          "received": 322,
          "encf": "E320000000002"
        },
        "name": "EcfValidationError"
      },
      {
        "code": "TIPO_ECF_INVALID_LENGTH",
        "field": "ECF.Encabezado.IdDoc.TipoeCF",
        "details": {
          "expected": 2,
          "received": 3,
          "value": "322"
        },
        "name": "EcfValidationError"
      }
    ]
  }
}

Campos de la respuesta de error:

CampoDescripción
messageMensaje legible con el resumen de todos los errores encontrados
codeCódigo de error general (ECF_VALIDATION_FAILED)
requestIdID único de la solicitud para seguimiento y debugging
details.validationErrorsArray con los errores de validación detallados
validationErrors[].codeCódigo específico del error (ej: TIPO_ECF_MISMATCH)
validationErrors[].fieldRuta completa al campo con error (ej: ECF.Encabezado.IdDoc.TipoeCF)
validationErrors[].detailsObjeto con información adicional del error (valores esperados, recibidos, etc.)
validationErrors[].nameNombre del tipo de error (EcfValidationError)

💡 Recomendación: Usa validate=true durante el desarrollo y pruebas para asegurar que tus documentos cumplan con todos los requisitos antes de enviarlos oficialmente a la DGII.

⚠️ Nota importante: Cuando usas validate=true, el documento NO se envía a la DGII y NO se consume una secuencia de e-NCF. Solo se realiza la validación del formato y contenido.

Ejemplo de validación de documento

Antes de enviar un documento oficialmente, puedes validarlo usando el parámetro validate=true:

curl -X POST \
  'https://ecf.api.mseller.app/TesteCF/documentos-ecf?validate=true' \
  -H 'Authorization: Bearer eyJraWQiOiJ1dE...' \
  -H 'X-API-KEY: tu_api_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "ECF": {
      "Encabezado": {
        "Version": "1.0",
        "IdDoc": {
          "TipoeCF": "31",
          "eNCF": "E310571508136"
        },
        "Emisor": {
          "RNCEmisor": "102320705",
          "RazonSocialEmisor": "Comercial Ejemplo SRL"
        }
      }
    }
  }'
async function validarDocumento(documento) {
  const idToken = localStorage.getItem("idToken");

  try {
    const response = await fetch(
      "https://ecf.api.mseller.app/TesteCF/documentos-ecf?validate=true",
      {
        method: "POST",
        headers: {
          Authorization: `Bearer ${idToken}`,
          "X-API-KEY": "tu_api_key",
          "Content-Type": "application/json",
        },
        body: JSON.stringify(documento),
      },
    );

    const resultado = await response.json();

    // Verificar si la validación fue exitosa
    if (response.ok && resultado.valid) {
      console.log("✓ Documento válido, listo para enviar");
      // Ahora puedes enviarlo sin el parámetro validate
      return enviarDocumento(documento);
    } else if (resultado.code === "ECF_VALIDATION_FAILED") {
      console.error("✗ Errores de validación encontrados:");
      console.error(`Request ID: ${resultado.requestId}`);
      console.error(resultado.message);

      // Mostrar detalles de cada error
      resultado.details.validationErrors.forEach((error, index) => {
        console.error(`\nError ${index + 1}:`);
        console.error(`  Campo: ${error.field}`);
        console.error(`  Código: ${error.code}`);
        console.error(`  Detalles:`, error.details);
      });

      return resultado;
    } else {
      console.error("✗ Error inesperado:", resultado);
      return resultado;
    }
  } catch (error) {
    console.error("Error al validar documento:", error);
    throw error;
  }
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

public class MSellercfClient
{
    private readonly HttpClient _client = new HttpClient();
    private readonly string _idToken;
    private readonly string _apiKey;

    public MSellercfClient(string idToken, string apiKey)
    {
        _idToken = idToken;
        _apiKey = apiKey;
    }

    public async Task<JObject> ValidarDocumento(JObject documento)
    {
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_idToken}");
        _client.DefaultRequestHeaders.Add("X-API-KEY", _apiKey);

        var content = new StringContent(
            documento.ToString(),
            Encoding.UTF8,
            "application/json");

        var response = await _client.PostAsync(
            "https://ecf.api.mseller.app/TesteCF/documentos-ecf?validate=true",
            content);

        var responseJson = await response.Content.ReadAsStringAsync();
        var resultado = JObject.Parse(responseJson);

        // Verificar si la validación fue exitosa
        if (response.IsSuccessStatusCode && resultado["valid"]?.ToObject<bool>() == true)
        {
            Console.WriteLine("✓ Documento válido, listo para enviar");
            // Ahora puedes enviarlo sin el parámetro validate
            return await EnviarDocumento(documento);
        }
        else if (resultado["code"]?.ToString() == "ECF_VALIDATION_FAILED")
        {
            Console.WriteLine("✗ Errores de validación encontrados:");
            Console.WriteLine($"Request ID: {resultado["requestId"]}");
            Console.WriteLine(resultado["message"]);

            // Mostrar detalles de cada error
            var errors = resultado["details"]?["validationErrors"];
            if (errors != null)
            {
                for (int i = 0; i < errors.Count(); i++)
                {
                    var error = errors[i];
                    Console.WriteLine($"\nError {i + 1}:");
                    Console.WriteLine($"  Campo: {error["field"]}");
                    Console.WriteLine($"  Código: {error["code"]}");
                    Console.WriteLine($"  Detalles: {error["details"]}");
                }
            }

            return resultado;
        }
        else
        {
            Console.WriteLine("✗ Error inesperado:");
            Console.WriteLine(resultado);
            return resultado;
        }
    }
}
<?php
function validarDocumento($documento, $idToken, $apiKey) {
    $url = 'https://ecf.api.mseller.app/TesteCF/documentos-ecf?validate=true';

    $options = [
        'http' => [
            'method' => 'POST',
            'header' =>
                "Authorization: Bearer " . $idToken . "\r\n" .
                "X-API-KEY: " . $apiKey . "\r\n" .
                "Content-Type: application/json\r\n",
            'content' => json_encode($documento)
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === false) {
        throw new Exception('Error al validar documento');
    }

    $resultado = json_decode($result, true);

    // Verificar si la validación fue exitosa
    if (isset($resultado['valid']) && $resultado['valid'] === true) {
        echo "✓ Documento válido, listo para enviar\n";
        // Ahora puedes enviarlo sin el parámetro validate
        return enviarDocumento($documento, $idToken, $apiKey);
    } else if (isset($resultado['code']) && $resultado['code'] === 'ECF_VALIDATION_FAILED') {
        echo "✗ Errores de validación encontrados:\n";
        echo "Request ID: " . $resultado['requestId'] . "\n";
        echo $resultado['message'] . "\n";

        // Mostrar detalles de cada error
        if (isset($resultado['details']['validationErrors'])) {
            foreach ($resultado['details']['validationErrors'] as $index => $error) {
                echo "\nError " . ($index + 1) . ":\n";
                echo "  Campo: " . $error['field'] . "\n";
                echo "  Código: " . $error['code'] . "\n";
                echo "  Detalles: " . json_encode($error['details']) . "\n";
            }
        }

        return $resultado;
    } else {
        echo "✗ Error inesperado:\n";
        print_r($resultado);
        return $resultado;
    }
}

// Uso
$idToken = $_SESSION['idToken'];
$apiKey = 'tu_api_key';
$resultado = validarDocumento($documento, $idToken, $apiKey);
?>

Ejemplo de envío

curl -X POST \
  https://ecf.api.mseller.app/TesteCF/documentos-ecf \
  -H 'Authorization: Bearer eyJraWQiOiJ1dE...' \
  -H 'X-API-KEY: tu_api_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "ECF": {
      "Encabezado": {
        "Version": "1.0",
        "IdDoc": {
          "TipoeCF": "31",
          "eNCF": "E310571508136",
          "FechaVencimientoSecuencia": "31-12-2026",
          "IndicadorEnvioDiferido": "0",
          "IndicadorMontoGravado": "0",
          "TipoIngresos": "05",
          "TipoPago": "2",
          "FechaLimitePago": "07-08-2026",
          "TotalPaginas": 1
        },
        "Emisor": {
          "RNCEmisor": "Tu RNC",
          "RazonSocialEmisor": "Tu Negocio",
          "DireccionEmisor": "DireccionEmisor1",
          "FechaEmision": "29-06-2025"
        },
        "Comprador": {
          "RNCComprador": "101023122",
          "RazonSocialComprador": "Cliente Prueba SRL"
        },
        "Totales": {
          "MontoGravadoTotal": 540.0,
          "MontoGravadoI1": 540.0,
          "MontoExento": 0,
          "ITBIS1": 18,
          "TotalITBIS": 97.2,
          "TotalITBIS1": 97.2,
          "MontoTotal": 637.2,
          "MontoNoFacturable": 0
        }
      }
    }
  }'
async function enviarDocumento() {
  const documento = {
    ECF: {
      Encabezado: {
        Version: "1.0",
        IdDoc: {
          TipoeCF: "31",
          eNCF: "E310571508136",
          FechaVencimientoSecuencia: "31-12-2026",
          IndicadorEnvioDiferido: "0",
          IndicadorMontoGravado: "0",
          TipoIngresos: "05",
          TipoPago: "2",
          FechaLimitePago: "07-08-2026",
          TotalPaginas: 1,
        },
        Emisor: {
          RNCEmisor: "Tu RNC",
          RazonSocialEmisor: "Tu Negocio",
          DireccionEmisor: "DireccionEmisor1",
          FechaEmision: "29-06-2025",
        },
        Comprador: {
          RNCComprador: "101023122",
          RazonSocialComprador: "Cliente Prueba SRL",
        },
        Totales: {
          MontoGravadoTotal: 540.0,
          MontoGravadoI1: 540.0,
          MontoExento: 0,
          ITBIS1: 18,
          TotalITBIS: 97.2,
          TotalITBIS1: 97.2,
          MontoTotal: 637.2,
          MontoNoFacturable: 0,
        },
      },
      DetallesItems: {
        Item: [
          {
            NumeroLinea: "1",
            IndicadorFacturacion: "1",
            NombreItem: "Producto 1",
            IndicadorBienoServicio: "1",
            CantidadItem: 24,
            UnidadMedida: "43",
            PrecioUnitarioItem: 25.0,
            DescuentoMonto: 60.0,
            TablaSubDescuento: {
              SubDescuento: [
                {
                  TipoSubDescuento: "%",
                  SubDescuentoPorcentaje: 10.0,
                  MontoSubDescuento: 60.0,
                },
              ],
            },
            MontoItem: 540.0,
          },
        ],
      },
      Paginacion: {
        Pagina: [
          {
            PaginaNo: 1,
            NoLineaDesde: 1,
            NoLineaHasta: 1,
            SubtotalMontoGravadoPagina: 540.0,
            SubtotalMontoGravado1Pagina: 540.0,
            SubtotalExentoPagina: 0,
            SubtotalItbisPagina: 97.2,
            SubtotalItbis1Pagina: 97.2,
            MontoSubtotalPagina: 637.2,
            SubtotalMontoNoFacturablePagina: 0,
          },
        ],
      },
      FechaHoraFirma: "",
    },
  };

const idToken = localStorage.getItem("idToken");

try {
const response = await fetch(
"https://ecf.api.mseller.app/TesteCF/documentos-ecf",
{
method: "POST",
headers: {
Authorization: `Bearer ${idToken}`,
"X-API-KEY": "tu_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify(documento),
}
);

    const resultado = await response.json();
    console.log("Documento enviado:", resultado);
    return resultado;

} catch (error) {
console.error("Error al enviar documento:", error);
throw error;
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class MSellercfClient
{
    private readonly HttpClient _client = new HttpClient();
    private readonly string _idToken;
    private readonly string _apiKey;

    public MSellercfClient(string idToken, string apiKey)
    {
        _idToken = idToken;
        _apiKey = apiKey;
    }

    public async Task<JObject> EnviarDocumento()
    {
        // Crear el objeto documento
        var documento = new JObject();
        var ecf = new JObject();

        var encabezado = new JObject();
        encabezado["Version"] = "1.0";

        var idDoc = new JObject();
        idDoc["TipoeCF"] = "31";
        idDoc["eNCF"] = "E310571508136";
        idDoc["FechaVencimientoSecuencia"] = "31-12-2026";
        idDoc["IndicadorEnvioDiferido"] = "0";
        idDoc["IndicadorMontoGravado"] = "0";
        idDoc["TipoIngresos"] = "05";
        idDoc["TipoPago"] = "2";
        idDoc["FechaLimitePago"] = "07-08-2026";
        idDoc["TotalPaginas"] = 1;

        var emisor = new JObject();
        emisor["RNCEmisor"] = "Tu RNC";
        emisor["RazonSocialEmisor"] = "Tu Negocio";
        emisor["DireccionEmisor"] = "DireccionEmisor1";
        emisor["FechaEmision"] = "29-06-2025";

        var comprador = new JObject();
        comprador["RNCComprador"] = "101023122";
        comprador["RazonSocialComprador"] = "Cliente Prueba SRL";

        var totales = new JObject();
        totales["MontoGravadoTotal"] = 540.0;
        totales["MontoGravadoI1"] = 540.0;
        totales["MontoExento"] = 0;
        totales["ITBIS1"] = 18;
        totales["TotalITBIS"] = 97.2;
        totales["TotalITBIS1"] = 97.2;
        totales["MontoTotal"] = 637.2;
        totales["MontoNoFacturable"] = 0;

        // Estructura completa del documento (ejemplo simplificado)
        encabezado["IdDoc"] = idDoc;
        encabezado["Emisor"] = emisor;
        encabezado["Comprador"] = comprador;
        encabezado["Totales"] = totales;

        // Agregar más detalles conforme a la estructura completa
        // ...

        ecf["Encabezado"] = encabezado;
        documento["ECF"] = ecf;

        // Configurar la solicitud HTTP
        _client.DefaultRequestHeaders.Clear();
        _client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_idToken}");
        _client.DefaultRequestHeaders.Add("X-API-KEY", _apiKey);

        var content = new StringContent(
            documento.ToString(),
            Encoding.UTF8,
            "application/json");

        var response = await _client.PostAsync(
            "https://ecf.api.mseller.app/TesteCF/documentos-ecf",
            content);

        var responseJson = await response.Content.ReadAsStringAsync();
        return JObject.Parse(responseJson);
    }
}
<?php
function enviarDocumento($idToken, $apiKey) {
    $url = 'https://ecf.api.mseller.app/TesteCF/documentos-ecf';

    // Documento en formato JSON
    $documento = [
        'ECF' => [
            'Encabezado' => [
                'Version' => '1.0',
                'IdDoc' => [
                    'TipoeCF' => '31',
                    'eNCF' => 'E310571508136',
                    'FechaVencimientoSecuencia' => '31-12-2026',
                    'IndicadorEnvioDiferido' => '0',
                    'IndicadorMontoGravado' => '0',
                    'TipoIngresos' => '05',
                    'TipoPago' => '2',
                    'FechaLimitePago' => '07-08-2026',
                    'TotalPaginas' => 1
                ],
                'Emisor' => [
                    'RNCEmisor' => 'Tu RNC',
                    'RazonSocialEmisor' => 'Tu Negocio',
                    'DireccionEmisor' => 'DireccionEmisor1',
                    'FechaEmision' => '29-06-2025'
                ],
                'Comprador' => [
                    'RNCComprador' => '101023122',
                    'RazonSocialComprador' => 'Cliente Prueba SRL'
                ],
                'Totales' => [
                    'MontoGravadoTotal' => 540.0,
                    'MontoGravadoI1' => 540.0,
                    'MontoExento' => 0,
                    'ITBIS1' => 18,
                    'TotalITBIS' => 97.2,
                    'TotalITBIS1' => 97.2,
                    'MontoTotal' => 637.2,
                    'MontoNoFacturable' => 0
                ]
            ],
            'DetallesItems' => [
                'Item' => [
                    [
                        'NumeroLinea' => '1',
                        'IndicadorFacturacion' => '1',
                        'NombreItem' => 'Producto 1',
                        'IndicadorBienoServicio' => '1',
                        'CantidadItem' => 24,
                        'UnidadMedida' => '43',
                        'PrecioUnitarioItem' => 25.0,
                        'DescuentoMonto' => 60.0,
                        'TablaSubDescuento' => [
                            'SubDescuento' => [
                                [
                                    'TipoSubDescuento' => '%',
                                    'SubDescuentoPorcentaje' => 10.0,
                                    'MontoSubDescuento' => 60.0
                                ]
                            ]
                        ],
                        'MontoItem' => 540.0
                    ]
                ]
            ]
            // Agregar Paginación y otros elementos según necesidad
        ]
    ];

    $options = [
        'http' => [
            'method' => 'POST',
            'header' =>
                "Authorization: Bearer " . $idToken . "\r\n" .
                "X-API-KEY: " . $apiKey . "\r\n" .
                "Content-Type: application/json\r\n",
            'content' => json_encode($documento)
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === false) {
        // Manejar error
        return null;
    }

    return json_decode($result, true);

}

// Uso
$idToken = $_SESSION['idToken']; // Obtenido del proceso de autenticación
$apiKey = 'tu_api_key';
$resultado = enviarDocumento($idToken, $apiKey);
print_r($resultado);
?>

Nota: En el ambiente de prueba debes buscar una secuencia aleatoria que no haya sido utilizada, debes tratar con diferentes secuencias

Respuesta exitosa

{
  "rnc": "102320705",
  "ecf": "E310000009175",
  "internalTrackId": "58f1bdd7-f4be-4a2e-a1e6-570c95b8d477",
  "securityCode": "fWCZCV",
  "qr_url": "https://ecf.dgii.gov.do/testecf/consultatimbre?rncemisor=102320705&RncComprador=101023122&encf=E310000009175&FechaEmision=14-05-2025&montototal=637.2&FechaFirma=14-05-2025%2002:57:33&codigoseguridad=fWCZCV",
  "signedDate": "14-05-2025 02:57:33"
}

Factura de Consumo Electrónica (e-CF 32)

La Factura de Consumo Electrónica (e-CF 32) es el comprobante fiscal electrónico que acredita la transferencia de bienes, la entrega en uso o la prestación de servicios a consumidores finales. A diferencia de la Factura de Crédito Fiscal (e-CF 31), la Factura de Consumo no otorga al comprador el derecho a crédito fiscal para el ITBIS, ni puede ser utilizada para sustentar costos y gastos deducibles del Impuesto Sobre la Renta (ISR).

Su e-NCF sigue el formato E32XXXXXXXXXX (13 caracteres), donde:

  • E: indica que es un documento electrónico
  • 32: código exclusivo para facturas de consumo
  • XXXXXXXXXX: secuencia numérica única autorizada por la DGII

Nota importante: La Factura de Consumo Electrónica es de uso obligatorio para todas las transacciones con consumidores finales (B2C). Al emitirse un e-CF 32, se cierra la cadena de créditos fiscales para esa transacción.

Ejemplo de Factura de Consumo (e-CF 32)

{
  "ECF": {
    "Encabezado": {
      "Version": "1.0",
      "IdDoc": {
        "TipoeCF": 32,
        "eNCF": "E320000000001",
        "IndicadorEnvioDiferido": 10,
        "IndicadorMontoGravado": 0,
        "TipoIngresos": "01",
        "TipoPago": 1
      },
      "Emisor": {
        "RNCEmisor": "130000001",
        "RazonSocialEmisor": "Supermercado Ejemplo SRL",
        "DireccionEmisor": "Av. Principal #50, Santo Domingo",
        "FechaEmision": "03-03-2026"
      },
      "Comprador": {
        "RNCComprador": "00000000000",
        "RazonSocialComprador": "Consumidor Final"
      },
      "Totales": {
        "MontoGravadoTotal": 355.93,
        "MontoGravadoI1": 355.93,
        "MontoExento": 109.98,
        "TotalITBIS": 64.07,
        "TotalITBIS1": 64.07,
        "MontoTotal": 529.98
      }
    },
    "DetallesItems": {
      "Item": [
        {
          "NumeroLinea": 1,
          "IndicadorFacturacion": 4,
          "NombreItem": "Agua Mineral 500ml",
          "IndicadorBienoServicio": 1,
          "CantidadItem": 1.0,
          "PrecioUnitarioItem": 64.99,
          "MontoItem": 64.99
        },
        {
          "NumeroLinea": 2,
          "IndicadorFacturacion": 4,
          "NombreItem": "Bolsa Plástica Reciclable 30 GL",
          "IndicadorBienoServicio": 1,
          "CantidadItem": 1.0,
          "PrecioUnitarioItem": 44.99,
          "MontoItem": 44.99
        },
        {
          "NumeroLinea": 3,
          "IndicadorFacturacion": 1,
          "NombreItem": "Detergente Líquido 400ml",
          "IndicadorBienoServicio": 1,
          "CantidadItem": 1.0,
          "PrecioUnitarioItem": 105.92,
          "MontoItem": 105.92
        },
        {
          "NumeroLinea": 4,
          "IndicadorFacturacion": 1,
          "NombreItem": "Limpiador Multiuso 900ml",
          "IndicadorBienoServicio": 1,
          "CantidadItem": 1.0,
          "PrecioUnitarioItem": 250.01,
          "MontoItem": 250.01
        }
      ]
    },
    "FechaHoraFirma": "03-03-2026 13:59:45"
  }
}

Características destacadas de este ejemplo:

  • Productos exentos (Items 1 y 2): IndicadorFacturacion: 4 indica que están exentos de ITBIS
  • Productos gravados (Items 3 y 4): IndicadorFacturacion: 1 indica ITBIS al 18%
  • Comprador genérico: RNCComprador: "00000000000" y RazonSocialComprador: "Consumidor Final" se utilizan cuando el comprador no proporciona identificación
  • Sin fecha de vencimiento: Las facturas de consumo no incluyen FechaVencimientoSecuencia ni FechaLimitePago

Campos específicos del e-CF 32

CampoValor / Descripción
TipoeCFDebe ser 32
eNCFFormato E32XXXXXXXXXX (13 caracteres)
RNCCompradorPuede ser "00000000000" para consumidores anónimos
RazonSocialCompradorPuede ser "-" o "Consumidor Final" cuando no se identifica al comprador
IndicadorFacturacion1 = gravado ITBIS 18%, 2 = gravado ITBIS 16%, 4 = exento
FechaVencimientoSecuenciaNo aplica para e-CF 32
FechaLimitePagoNo aplica para e-CF 32
PaginacionNo requerida para e-CF 32

Resumen de Factura de Consumo

La DGII establece dos modalidades de envío para las Facturas de Consumo Electrónicas según su monto:

  • Documento Extendido: contiene todos los detalles de la factura, incluyendo cada renglón (línea de producto) con sus montos individuales. Se envía completo a la DGII.
  • Resumen de Factura: contiene únicamente los datos totales de la factura y el número de comprobante (e-NCF). No incluye el detalle de los ítems.

MSeller maneja este proceso de forma completamente automática. Como desarrollador, solo debes enviar el documento completo con todos los detalles de los ítems. MSeller se encarga de determinar si corresponde enviar el documento extendido o el resumen a la DGII.

Flujo automático de MSeller

Modalidad¿Qué se envía a la DGII?¿Cuándo aplica?
Documento ExtendidoEncabezado completo + todos los renglones de detalle de ítemsCuando MontoTotal ≥ RD$ 250,000
Resumen de FacturaSolo totales y número de comprobante (e-NCF)Cuando MontoTotal < RD$ 250,000

💡 Simplificación para el desarrollador: No necesitas implementar lógica para decidir cuándo enviar el documento extendido o el resumen. Siempre envía el documento completo con todos los detalles — MSeller evalúa el MontoTotal y decide automáticamente la modalidad correcta de envío a la DGII.

Código de seguridad en el Resumen

Cuando MSeller genera un Resumen de Factura (para montos menores a RD$ 250,000), extrae automáticamente los 6 caracteres del código de seguridad de la firma digital del documento extendido. Este código se utiliza como clave identificadora en el resumen enviado a la DGII, garantizando la trazabilidad entre el documento completo almacenado y el resumen reportado.

Retención y almacenamiento

MSeller almacena todos los documentos extendidos de facturas de consumo por un período de 10 años, conforme a los requisitos de retención establecidos por la DGII. Esto aplica independientemente de si el documento enviado a la DGII fue el extendido o el resumen:

  • Montos ≥ RD$ 250,000: el documento extendido se envía a la DGII y se almacena por 10 años.
  • Montos < RD$ 250,000: solo el resumen se envía a la DGII, pero el documento extendido completo se genera, firma y almacena por 10 años para consulta y auditoría.

⚠️ Importante: No necesitas implementar almacenamiento de documentos en tu sistema para cumplir con la normativa de retención de la DGII. MSeller gestiona esto de forma transparente.

Estados de los documentos

Los documentos enviados a la plataforma pueden tener los siguientes estados:

EstadoDescripción
RECIBIDOEl documento ha sido recibido pero aún no ha sido procesado
PROCESANDOEl documento está siendo procesado y validado
ACEPTADOEl documento ha sido validado y aceptado correctamente
RECHAZADOEl documento ha sido rechazado por errores en su formato o contenido
ERRORHa ocurrido un error durante el procesamiento del documento

Flujo de procesamiento asíncrono

Es importante entender que MSeller ECF utiliza un procesamiento asíncrono para optimizar el rendimiento y manejar grandes volúmenes de documentos. El proceso completo incluye:

  1. Recepción del documento JSON - MSeller recibe el documento
  2. Transformación a XML - Conversión automática al formato requerido por la DGII
  3. Aplicación de firma electrónica - Utilizando tu certificado digital
  4. Almacenamiento del documento XML - Guardado seguro de la versión firmada
  5. Respuesta inmediata - Devolución de códigos de seguridad y enlace QR
  6. Procesamiento en cola - El documento se coloca en cola para envío a la DGII
  7. Actualización de estado - El estado del documento se actualiza tras la respuesta de la DGII

IMPORTANTE: Debido a este proceso asíncrono, debes esperar unos segundos antes de consultar el estado final del documento para verificar si fue aceptado o rechazado por la DGII.

Manejo de errores

Errores comunes en el envío

Código HTTPDescripciónSolución
400JSON mal formateadoVerifica que el JSON cumpla con la estructura definida
401Error de autenticaciónVerifica tu token de acceso
403API Key inválidaVerifica tu API Key
429Límite de solicitudes excedidoReduce la frecuencia de solicitudes según tu plan
500Error del servidorContacta al soporte técnico

Buenas prácticas

  1. Validación previa con parámetro validate: Usa el parámetro validate=true durante el desarrollo para validar tus documentos antes de enviarlos oficialmente. Esto te permite detectar errores sin consumir secuencias de e-NCF.
  2. Manejo de errores: Implementa un sistema robusto para manejar los diferentes tipos de errores retornados tanto por la validación como por la DGII.
  3. Reintentos: Implementa una estrategia de reintentos para casos de fallos temporales, pero evita reintentar documentos con errores de validación.
  4. Almacenamiento local: Mantén una copia local de los documentos enviados para referencia futura.
  5. Consulta periódica: Implementa consultas periódicas para actualizar el estado de los documentos enviados.
  6. Tiempo de espera: Programa consultas con un tiempo de espera adecuado entre el envío del documento y la consulta de su estado.
  7. Gestión de códigos de seguridad: Almacena y gestiona correctamente los códigos de seguridad y URLs de QR para la representación impresa de las facturas.
  8. Proceso de dos pasos: En desarrollo, primero valida con validate=true y si es exitoso, envía sin el parámetro para el registro oficial.

Recursos y herramientas para la adaptación de documentos

Para asegurar que tu integración con MSeller ECF funcione correctamente, es fundamental comprender la estructura y los requisitos específicos de los documentos electrónicos. La Dirección General de Impuestos Internos (DGII) ofrece recursos oficiales que te ayudarán en este proceso.

Documentación y archivos XSD oficiales

La DGII proporciona documentación detallada y archivos XSD (XML Schema Definition) que contienen la definición completa de la estructura de los documentos electrónicos. Estos recursos son esenciales para comprender los campos requeridos y las validaciones que se aplican a cada tipo de documento.

Formatos XML

ArchivoDescripciónÚltima modificaciónTamaño
Formato Comprobante Fiscal Electrónico (e-CF) V 1.0Especificaciones para la elaboración de un e-CF18/09/20242,1MB
Formato Acuse de Recibo v1.0Especificaciones para recibir y dar constancia de recibo de un e-CF23/07/2020193,2KB
Formato Aprobación Comercial V1.0Especificaciones para recibir y dar respuesta de la conformidad de un e-CF10/01/2020212,2KB
Formato Anulación de e-CF V1.0Especificaciones para la Anulación de un e-CF20/06/2022494,4KB
Formato Resumen Factura Consumo Electrónico v1.0Especificaciones para la remisión del resumen de factura de consumo electrónica menor a DOP250 mil19/08/2020275KB

Documentación Técnica (XSD)

ArchivoDescripciónÚltima modificaciónTamaño
e-CF 31 v.1.0Factura de Crédito Fiscal Electrónica13/02/2025120,1KB
e-CF 32 v.1.0Factura de Consumo Electrónica13/02/2025120,1KB
e-CF 33 v.1.0Nota de Débito Electrónica13/02/2025121,5KB
e-CF 34 v.1.0Nota de Crédito Electrónica13/02/2025119,1KB
e-CF 41 v.1.0Comprobante de Compras Electrónico13/02/2025108,5KB
e-CF 43 v.1.0Comprobante de Gastos Menores Electrónico13/02/202593,8KB
e-CF 44 v.1.0Comprobante de Regímenes Especiales Electrónico13/02/2025111,6KB
e-CF 45 v.1.0Comprobante Gubernamental Electrónico13/02/2025118,9KB
e-CF 46 v.1.0Comprobante para Pagos al Exterior Electrónico13/02/2025113,2KB
e-CF 47 v.1.0Comprobante de Ingresos Electrónico13/02/202598,9KB
RFCE 32 v1.0Representación Fiscal de Comprobante Electrónico20/06/202315KB
ARECF v1.0Acuse de Recibo de e-CF20/06/20232,8KB
ANECF v.1.0Acuse Negativo de Recibo de e-CF20/06/20235KB
ACECF v.1.0Acuse Comercial de e-CF21/12/20223,5KB
Semilla v.1.0Definición de semilla para firma12/11/2020487B

Nota: Los archivos XSD se pueden abrir con Visual Studio en Windows para visualizar la estructura completa de los esquemas XML.

Herramientas para validación y depuración

Para facilitar la adaptación de tus sistemas a los requisitos de documentos electrónicos, puedes utilizar las siguientes herramientas:

Convertidores y validadores online

Simuladores de entorno

MSeller ECF ofrece un ambiente de prueba (TesteCF) que te permite validar tus documentos antes de usarlos en producción. Este entorno simula completamente el proceso de envío y recepción de documentos electrónicos.

Para usar el simulador:

  1. Envía tus documentos al endpoint TesteCF como se describe en la sección de Envío de documentos
  2. Utiliza secuencias de prueba para los eNCF (como se indica en la nota sobre secuencias aleatorias)
  3. Verifica las respuestas y corrija cualquier error antes de pasar a producción

Soporte y asesoría

Si encuentras dificultades durante la implementación o adaptación de tus documentos, puedes recurrir a:

  • Soporte técnico de MSeller: A través del portal de soporte
  • Documentación extendida: Disponible en el Centro de Ayuda de MSeller
  • Asesoría especializada: MSeller ofrece servicios de consultoría para casos complejos de integración