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-ecfDonde {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/jsonCuerpo 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: 4que 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: 32para 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:
| Campo | Descripción |
|---|---|
| message | Mensaje legible con el resumen de todos los errores encontrados |
| code | Código de error general (ECF_VALIDATION_FAILED) |
| requestId | ID único de la solicitud para seguimiento y debugging |
| details.validationErrors | Array con los errores de validación detallados |
| validationErrors[].code | Código específico del error (ej: TIPO_ECF_MISMATCH) |
| validationErrors[].field | Ruta completa al campo con error (ej: ECF.Encabezado.IdDoc.TipoeCF) |
| validationErrors[].details | Objeto con información adicional del error (valores esperados, recibidos, etc.) |
| validationErrors[].name | Nombre del tipo de error (EcfValidationError) |
💡 Recomendación: Usa
validate=truedurante 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: 4indica que están exentos de ITBIS - Productos gravados (Items 3 y 4):
IndicadorFacturacion: 1indica ITBIS al 18% - Comprador genérico:
RNCComprador: "00000000000"yRazonSocialComprador: "Consumidor Final"se utilizan cuando el comprador no proporciona identificación - Sin fecha de vencimiento: Las facturas de consumo no incluyen
FechaVencimientoSecuencianiFechaLimitePago
Campos específicos del e-CF 32
| Campo | Valor / Descripción |
|---|---|
TipoeCF | Debe ser 32 |
eNCF | Formato E32XXXXXXXXXX (13 caracteres) |
RNCComprador | Puede ser "00000000000" para consumidores anónimos |
RazonSocialComprador | Puede ser "-" o "Consumidor Final" cuando no se identifica al comprador |
IndicadorFacturacion | 1 = gravado ITBIS 18%, 2 = gravado ITBIS 16%, 4 = exento |
FechaVencimientoSecuencia | No aplica para e-CF 32 |
FechaLimitePago | No aplica para e-CF 32 |
Paginacion | No 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 Extendido | Encabezado completo + todos los renglones de detalle de ítems | Cuando MontoTotal ≥ RD$ 250,000 |
| Resumen de Factura | Solo 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
MontoTotaly 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:
| Estado | Descripción |
|---|---|
| RECIBIDO | El documento ha sido recibido pero aún no ha sido procesado |
| PROCESANDO | El documento está siendo procesado y validado |
| ACEPTADO | El documento ha sido validado y aceptado correctamente |
| RECHAZADO | El documento ha sido rechazado por errores en su formato o contenido |
| ERROR | Ha 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:
- Recepción del documento JSON - MSeller recibe el documento
- Transformación a XML - Conversión automática al formato requerido por la DGII
- Aplicación de firma electrónica - Utilizando tu certificado digital
- Almacenamiento del documento XML - Guardado seguro de la versión firmada
- Respuesta inmediata - Devolución de códigos de seguridad y enlace QR
- Procesamiento en cola - El documento se coloca en cola para envío a la DGII
- 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 HTTP | Descripción | Solución |
|---|---|---|
| 400 | JSON mal formateado | Verifica que el JSON cumpla con la estructura definida |
| 401 | Error de autenticación | Verifica tu token de acceso |
| 403 | API Key inválida | Verifica tu API Key |
| 429 | Límite de solicitudes excedido | Reduce la frecuencia de solicitudes según tu plan |
| 500 | Error del servidor | Contacta al soporte técnico |
Buenas prácticas
- Validación previa con parámetro validate: Usa el parámetro
validate=truedurante el desarrollo para validar tus documentos antes de enviarlos oficialmente. Esto te permite detectar errores sin consumir secuencias de e-NCF. - Manejo de errores: Implementa un sistema robusto para manejar los diferentes tipos de errores retornados tanto por la validación como por la DGII.
- Reintentos: Implementa una estrategia de reintentos para casos de fallos temporales, pero evita reintentar documentos con errores de validación.
- Almacenamiento local: Mantén una copia local de los documentos enviados para referencia futura.
- Consulta periódica: Implementa consultas periódicas para actualizar el estado de los documentos enviados.
- Tiempo de espera: Programa consultas con un tiempo de espera adecuado entre el envío del documento y la consulta de su estado.
- 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.
- Proceso de dos pasos: En desarrollo, primero valida con
validate=truey 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
| Archivo | Descripción | Última modificación | Tamaño |
|---|---|---|---|
| Formato Comprobante Fiscal Electrónico (e-CF) V 1.0 | Especificaciones para la elaboración de un e-CF | 18/09/2024 | 2,1MB |
| Formato Acuse de Recibo v1.0 | Especificaciones para recibir y dar constancia de recibo de un e-CF | 23/07/2020 | 193,2KB |
| Formato Aprobación Comercial V1.0 | Especificaciones para recibir y dar respuesta de la conformidad de un e-CF | 10/01/2020 | 212,2KB |
| Formato Anulación de e-CF V1.0 | Especificaciones para la Anulación de un e-CF | 20/06/2022 | 494,4KB |
| Formato Resumen Factura Consumo Electrónico v1.0 | Especificaciones para la remisión del resumen de factura de consumo electrónica menor a DOP250 mil | 19/08/2020 | 275KB |
Documentación Técnica (XSD)
| Archivo | Descripción | Última modificación | Tamaño |
|---|---|---|---|
| e-CF 31 v.1.0 | Factura de Crédito Fiscal Electrónica | 13/02/2025 | 120,1KB |
| e-CF 32 v.1.0 | Factura de Consumo Electrónica | 13/02/2025 | 120,1KB |
| e-CF 33 v.1.0 | Nota de Débito Electrónica | 13/02/2025 | 121,5KB |
| e-CF 34 v.1.0 | Nota de Crédito Electrónica | 13/02/2025 | 119,1KB |
| e-CF 41 v.1.0 | Comprobante de Compras Electrónico | 13/02/2025 | 108,5KB |
| e-CF 43 v.1.0 | Comprobante de Gastos Menores Electrónico | 13/02/2025 | 93,8KB |
| e-CF 44 v.1.0 | Comprobante de Regímenes Especiales Electrónico | 13/02/2025 | 111,6KB |
| e-CF 45 v.1.0 | Comprobante Gubernamental Electrónico | 13/02/2025 | 118,9KB |
| e-CF 46 v.1.0 | Comprobante para Pagos al Exterior Electrónico | 13/02/2025 | 113,2KB |
| e-CF 47 v.1.0 | Comprobante de Ingresos Electrónico | 13/02/2025 | 98,9KB |
| RFCE 32 v1.0 | Representación Fiscal de Comprobante Electrónico | 20/06/2023 | 15KB |
| ARECF v1.0 | Acuse de Recibo de e-CF | 20/06/2023 | 2,8KB |
| ANECF v.1.0 | Acuse Negativo de Recibo de e-CF | 20/06/2023 | 5KB |
| ACECF v.1.0 | Acuse Comercial de e-CF | 21/12/2022 | 3,5KB |
| Semilla v.1.0 | Definición de semilla para firma | 12/11/2020 | 487B |
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
-
JSON a XML: Para comprobar la conversión correcta entre el formato JSON que utilizas en las solicitudes y el formato XML que se utiliza internamente.
-
Validadores XSD: Para verificar que tus documentos XML cumplen con los esquemas definidos por la DGII.
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:
- Envía tus documentos al endpoint
TesteCFcomo se describe en la sección de Envío de documentos - Utiliza secuencias de prueba para los eNCF (como se indica en la nota sobre secuencias aleatorias)
- 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
Formato de Documentos e-CF
Ejemplos completos de JSON para cada tipo de Comprobante Fiscal Electrónico (e-CF) usado en las pruebas de certificación DGII con MSeller ECF. Tipos 31, 32, 33, 34, 41, 43, 44, 45, 46 y 47.
Consulta de Documentos
Cómo consultar el estado de documentos electrónicos enviados a través de MSeller ECF