ecfx/ecf-dgii-php

PHP SDK for the ECF DGII electronic fiscal receipt API (Dominican Republic)

Maintainers

Package info

github.com/SSD-Smart-Software-Development-SRL/ecf-dgii-php

pkg:composer/ecfx/ecf-dgii-php

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-03-14 12:33 UTC

This package is auto-updated.

Last update: 2026-03-14 12:54:54 UTC


README

PHP SDK para integrar la facturacion electronica (e-CF) en Republica Dominicana a traves de ECF SSD.

Packagist Version Packagist Downloads CI License

Que es ECF SSD

ECF SSD es una plataforma que simplifica la emision de comprobantes fiscales electronicos (e-CF) en Republica Dominicana. En vez de que cada empresa implemente todo el proceso de comunicacion con la DGII (firmado XML, autenticacion por semilla, manejo de certificados, reintentos, almacenamiento, etc.), ECF SSD lo hace por ti.

Tu solo envias el comprobante en JSON a traves de este SDK, y el servicio se encarga de:

  • Firmar el comprobante electronicamente (XML signing con tu certificado digital)
  • Autenticar con la DGII (semilla -> token)
  • Enviar el e-CF a la DGII
  • Validar emisor-receptor
  • Almacenar los comprobantes de forma segura
  • Reintentar automaticamente en caso de fallos
  • Gestionar tus certificados digitales

Usas WooCommerce? Tenemos un plugin listo para facturacion electronica sin escribir codigo.

Buscas otro lenguaje? Tambien disponible en .NET, TypeScript, React, Python, Java, Kotlin, Swift y C++. Ver todos los SDKs y plugins.

Instalacion

composer require ecfx/ecf-dgii-php

Requisitos

  • PHP 8.1+
  • ext-curl
  • ext-json
  • ext-mbstring

Como Empezar

Paso 1: Registrate en ECF SSD

Visita https://ecf.ssd.com.do y crea tu cuenta.

Paso 2: Obten tu API Key

  1. Una vez logueado, selecciona el ambiente Test en el selector de ambientes (esquina superior derecha)
  2. Ve a Settings > API Key > Generate API Key
  3. Copia tu API Key -- la usaras como bearer token para autenticarte con el SDK

Paso 3: Contacta a ECF SSD para la Integracion

Contacta al equipo de ECF SSD (contacto@ssd.com.do) para iniciar el proceso de integracion y certificacion de tu sistema (no de las empresas de tus clientes -- la certificacion es para tu plataforma). El equipo te guiara a traves del proceso usando el ambiente de certificacion (Cert).

Paso 4: Usa Produccion

Una vez que tu sistema este integrado y certificado, podras usar el ambiente de produccion (Prod) para emitir comprobantes fiscales electronicos reales.

Vienes de otro proveedor? ECF SSD soporta migracion desde otros proveedores de facturacion electronica. Contacta al equipo para coordinar la transicion.

Configuracion

use Ecfx\EcfDgii\Configuration;

$config = Configuration::getDefaultConfiguration()
    ->setHost('https://api.test.ecfx.ssd.com.do')
    ->setAccessToken('your-api-key-here');

Ambientes

Ambiente URL Uso
Test https://api.test.ecfx.ssd.com.do Desarrollo y pruebas internas
Cert https://api.cert.ecfx.ssd.com.do Proceso de certificacion con la DGII
Prod https://api.prod.ecfx.ssd.com.do Produccion

Autenticacion

El SDK utiliza JWT Bearer Token. Puedes configurar el token de dos formas:

  1. Directamente en el codigo: pasando el API Key con setAccessToken()
  2. Variable de entorno: ECF_DGII_TOKEN

Ejemplo: Factura de Consumo (ECF 32)

Cada tipo de ECF tiene su propio conjunto de clases con el prefijo del tipo (ej. Ecf32ECF, Ecf32Encabezado, Ecf32Item para Factura de Consumo).

<?php

require_once 'vendor/autoload.php';

use GuzzleHttp\Client;
use Ecfx\EcfDgii\Configuration;
use Ecfx\EcfDgii\Api\EcfApi;
use Ecfx\EcfDgii\ApiException;
use Ecfx\EcfDgii\Model\Ecf32ECF;
use Ecfx\EcfDgii\Model\Ecf32Encabezado;
use Ecfx\EcfDgii\Model\Ecf32IdDoc;
use Ecfx\EcfDgii\Model\Ecf32Emisor;
use Ecfx\EcfDgii\Model\Ecf32Comprador;
use Ecfx\EcfDgii\Model\Ecf32Totales;
use Ecfx\EcfDgii\Model\Ecf32Item;
use Ecfx\EcfDgii\Model\Ecf32FormaDePago;
use Ecfx\EcfDgii\Model\Ecf32VersionType;
use Ecfx\EcfDgii\Model\Ecf32TipoPagoType;
use Ecfx\EcfDgii\Model\Ecf32FormaPagoType;
use Ecfx\EcfDgii\Model\Ecf32IndicadorFacturacionType;
use Ecfx\EcfDgii\Model\Ecf32IndicadorBienoServicioType;
use Ecfx\EcfDgii\Model\Ecf32TipoIngresosValidationType;
use Ecfx\EcfDgii\Model\TipoeCFType;
use Ecfx\EcfDgii\Model\IndicadorMontoGravadoType;
use Ecfx\EcfDgii\Model\UnidadMedidaType;

// 1. Configurar
$config = Configuration::getDefaultConfiguration()
    ->setHost('https://api.test.ecfx.ssd.com.do')
    ->setAccessToken(getenv('ECF_DGII_TOKEN'));

// 2. Crear el cliente API
$ecfApi = new EcfApi(new Client(), $config);

// 3. Construir el ECF 32 (Factura de Consumo)
$ecf = new Ecf32ECF([
    'encabezado' => new Ecf32Encabezado([
        'version' => Ecf32VersionType::VERSION1_0,
        'id_doc' => new Ecf32IdDoc([
            'tipoe_cf' => TipoeCFType::FACTURA_DE_CONSUMO_ELECTRONICA,
            'encf' => 'E320000000019',
            'indicador_monto_gravado' => IndicadorMontoGravadoType::CON_ITBIS_INCLUIDO,
            'tipo_ingresos' => Ecf32TipoIngresosValidationType::_01,
            'tipo_pago' => Ecf32TipoPagoType::CONTADO,
            'tabla_formas_pago' => [
                new Ecf32FormaDePago([
                    'forma_pago' => Ecf32FormaPagoType::EFECTIVO,
                    'monto_pago' => 590,
                ]),
            ],
        ]),
        'emisor' => new Ecf32Emisor([
            'rnc_emisor' => 'TODO_YOUR_RNC',           // TODO: Reemplaza con tu RNC
            'razon_social_emisor' => 'TODO_YOUR_RAZON_SOCIAL', // TODO: Reemplaza con tu razon social
            'direccion_emisor' => 'TODO_YOUR_ADDRESS',  // TODO: Reemplaza con tu direccion
            'numero_factura_interna' => '21',
            'fecha_emision' => new \DateTime('2026-03-13'),
        ]),
        'comprador' => new Ecf32Comprador(),
        'totales' => new Ecf32Totales([
            'monto_gravado_total' => 500,
            'monto_gravado_i1' => 500,
            'itbi_s1' => 18,
            'total_itbis' => 90,
            'total_itbis1' => 90,
            'monto_total' => 590,
            'monto_periodo' => 590,
        ]),
    ]),
    'detalles_items' => [
        new Ecf32Item([
            'numero_linea' => 1,
            'indicador_facturacion' => Ecf32IndicadorFacturacionType::ITBIS1_18_PERCENT,
            'nombre_item' => 'Servicio Digital',
            'indicador_bieno_servicio' => Ecf32IndicadorBienoServicioType::SERVICIO,
            'cantidad_item' => 1,
            'unidad_medida' => UnidadMedidaType::UNIDAD,
            'precio_unitario_item' => 500,
            'monto_item' => 500,
        ]),
    ],
]);

// 4. Enviar el ECF
try {
    $result = $ecfApi->recepcionEcf32($ecf);

    echo "ECF enviado!\n";
    echo "Message ID: " . $result->getMessageId() . "\n";
} catch (ApiException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    echo "Response: " . $e->getResponseBody() . "\n";
}

Usando EcfService (auto-routing + polling)

El EcfService enruta automaticamente al endpoint correcto segun el tipo de ECF y hace polling hasta que la DGII termine de procesar:

use Ecfx\EcfDgii\EcfService;
use Ecfx\EcfDgii\EcfProcessingException;
use Ecfx\EcfDgii\EcfPollingTimeoutException;

$service = new EcfService($ecfApi, pollingMaxAttempts: 30, pollingIntervalSeconds: 2);

try {
    $result = $service->sendEcf($ecf);

    echo "ECF aceptado!\n";
    echo "Status: " . $result->getEstatus() . "\n";
    echo "ENCF: " . $result->getEncf() . "\n";
} catch (EcfProcessingException $e) {
    echo "ECF rechazado: " . $e->getMessage() . "\n";
} catch (EcfPollingTimeoutException $e) {
    echo "Polling timeout: " . $e->getMessage() . "\n";
}

Como Funciona sendEcf

Tu sistema                          ECF SSD                         DGII
   |                                   |                              |
   |-- sendEcf(ecf) ----------------->|                              |
   |                                   |-- firma XML ----------------|
   |                                   |-- autenticacion (semilla) ->|
   |                                   |-- envio e-CF -------------->|
   |                                   |<-- trackId ----------------|
   |                                   |-- polling estado ---------->|
   |                                   |<-- resultado final --------|
   |<-- EcfResponse ------------------|                              |
   |                                   |                              |
  1. Enrutamiento automatico: Determina el endpoint correcto (/ecf/31, /ecf/32, etc.) basandose en el tipoeCF
  2. Envio: POST al endpoint correspondiente
  3. Polling: Consulta periodicamente el estado hasta que la DGII responda (Finished o Error)
  4. Resultado: Retorna el EcfResponse con el estado final, codigo de seguridad, URL de impresion, etc.

Respuesta (EcfResponse)

Al completarse el envio, recibes un EcfResponse con los datos necesarios para cumplir con los requisitos de impresion de la DGII:

Campo Descripcion
ImpresionUrl URL para generar el codigo QR requerido por la DGII en el comprobante impreso
CodSec Codigo de seguridad -- debe aparecer en el comprobante impreso
FechaFirma Fecha y hora de la firma digital del comprobante
Estatus Estado DGII: Aceptado, AceptadoCondicional, Rechazado
Progress Estado del procesamiento: Queued, Sending, Polling, Finished, Error
Encf Numero de comprobante fiscal electronico (eNCF)
Mensaje Mensaje de respuesta de la DGII
Errors Detalle de errores (si los hay)
MontoTotal Monto total del comprobante

QR e Impresion

La DGII requiere que todo comprobante impreso incluya un codigo QR. El campo ImpresionUrl contiene la URL que debe codificarse como QR. Adicionalmente, el CodSec (codigo de seguridad) y la FechaFirma deben aparecer impresos en el comprobante.

$result = $service->sendEcf($ecf);

$urlQr = $result->getImpresionUrl();         // codificar como QR
$codigoSeguridad = $result->getCodSec();     // imprimir en el comprobante
$fechaFirma = $result->getFechaFirma();      // fecha de firma digital

Tipos de Comprobantes (ECF)

Cada tipo de ECF tiene su propio conjunto de clases. Usa las clases que correspondan a tu tipo de documento:

Tipo Prefijo eNCF Descripcion Endpoint
31 Ecf31* E31 Factura de Credito Fiscal recepcionEcf31()
32 Ecf32* E32 Factura de Consumo recepcionEcf32()
33 Ecf33* E33 Nota de Debito recepcionEcf33()
34 Ecf34* E34 Nota de Credito recepcionEcf34()
41 Ecf41* E41 Compras recepcionEcf41()
43 Ecf43* E43 Gastos Menores recepcionEcf43()
44 Ecf44* E44 Regimenes Especiales recepcionEcf44()
45 Ecf45* E45 Gubernamental recepcionEcf45()
46 Ecf46* E46 Exportaciones recepcionEcf46()
47 Ecf47* E47 Pagos al Exterior recepcionEcf47()

Por ejemplo, para enviar una Factura de Credito Fiscal usa Ecf31ECF, Ecf31Encabezado, Ecf31Item, etc. y llama $ecfApi->recepcionEcf31($ecf).

Funcionalidades del API

Ademas de enviar comprobantes, el SDK expone todos los endpoints del API:

Clase Descripcion
EcfService Envio de ECF con auto-routing y polling
EcfApi Envio de ECF (tipos 31-47), consultas, busquedas, anulaciones
CompanyApi CRUD de empresas y gestion de certificados
DgiiApi Consultas DGII (directorio, estado, timbre, track IDs, etc.)
RecepcionApi Seguimiento de solicitudes de recepcion
ApiKeyApi Gestion de API keys

Funcionalidades adicionales

Funcionalidad Descripcion
Empresas Crear, consultar y eliminar empresas registradas
Certificados Subir y consultar certificados digitales
Consulta de e-CF Buscar comprobantes por RNC, eNCF, fecha, monto, etc.
Aprobacion Comercial Enviar aprobacion/rechazo comercial (ACECF)
Anulacion de Rangos Solicitar anulacion de secuencias de eNCF
Consultas DGII Directorio, estado, resultado, timbre, RFCE, track IDs
Estatus de Servicios Verificar disponibilidad de servicios DGII
API Keys Crear API keys para acceso programatico

Uso Directo de los Clientes API

Para control total, usa las clases API generadas directamente:

use GuzzleHttp\Client;
use Ecfx\EcfDgii\Configuration;
use Ecfx\EcfDgii\Api\CompanyApi;
use Ecfx\EcfDgii\Api\EcfApi;
use Ecfx\EcfDgii\Api\DgiiApi;
use Ecfx\EcfDgii\Api\RecepcionApi;
use Ecfx\EcfDgii\Api\ApiKeyApi;

$config = Configuration::getDefaultConfiguration()
    ->setHost('https://api.prod.ecfx.ssd.com.do')
    ->setAccessToken('your-api-key');

$client = new Client();

// Operaciones de empresas
$companyApi = new CompanyApi($client, $config);
$companies = $companyApi->getCompanies();
$company = $companyApi->getCompanyByRnc('123456789');

// Operaciones de ECF
$ecfApi = new EcfApi($client, $config);
$response = $ecfApi->recepcionEcf31($ecf);           // Factura de credito fiscal
$response = $ecfApi->recepcionEcf32($ecf);           // Factura de consumo
$results = $ecfApi->searchEcfs('123456789');           // Buscar ECFs por RNC
$ecfById = $ecfApi->getEcfById('123456789', $msgId);  // Obtener ECF por message ID
$ecfApi->aprobacionComercial('123456789', $encf, $acecfRequest); // Aprobacion comercial

// Consultas DGII
$dgiiApi = new DgiiApi($client, $config);
$directorio = $dgiiApi->consultaDirectorioListado('123456789');
$estado = $dgiiApi->consultaEstado('123456789', $rncEmisor, $ncf, $rncComprador, $codSeg);
$timbre = $dgiiApi->consultaTimbre('123456789', $rncEmisor, $encf, $monto, $codSeg);
$servicios = $dgiiApi->estatusServiciosObtenerEstatus('123456789');

// Seguimiento de recepcion
$recepcionApi = new RecepcionApi($client, $config);
$requests = $recepcionApi->searchEcfReceptionRequests();

Manejo de Errores

Excepcion Cuando
EcfProcessingException La DGII rechaza el ECF durante el procesamiento
EcfPollingTimeoutException El polling excede el maximo de intentos sin resultado final
ApiException Errores HTTP/red al comunicarse con el API
use Ecfx\EcfDgii\ApiException;
use Ecfx\EcfDgii\EcfProcessingException;
use Ecfx\EcfDgii\EcfPollingTimeoutException;

try {
    $result = $service->sendEcf($ecf);
} catch (EcfProcessingException $e) {
    // ECF rechazado por la DGII
    $response = $e->getEcfResponse();
    if ($response) {
        echo "Errores: " . $response->getErrors() . "\n";
    }
} catch (EcfPollingTimeoutException $e) {
    // El polling no obtuvo resultado a tiempo
    echo "Timeout: " . $e->getMessage() . "\n";
} catch (ApiException $e) {
    // Error HTTP (4xx, 5xx, red)
    echo "HTTP Error: " . $e->getCode() . "\n";
    echo "Body: " . $e->getResponseBody() . "\n";
}

Variables de Entorno

Variable Descripcion
ECF_DGII_TOKEN API key para autenticacion (desde ecf.ssd.com.do Settings > API Key)

Ejemplos

Regenerar desde OpenAPI Spec

openapi-generator generate \
  -i path/to/openapi/v1.json \
  -g php \
  -c openapi-generator-config.json \
  -o . \
  --skip-validate-spec

Contribuir

  1. Fork el repositorio
  2. Crea tu feature branch (git checkout -b feature/mi-feature)
  3. Haz commit de tus cambios (git commit -m 'Agregar mi feature')
  4. Push al branch (git push origin feature/mi-feature)
  5. Abre un Pull Request

Los tests corren automaticamente via GitHub Actions en cada push y PR.

Documentacion del API

La documentacion completa del API de ECF SSD esta disponible en:

https://ecf.ssd.com.do/documentacion/api-ecf-ssd

Incluye referencia de todos los endpoints, schemas, codigos de error y ejemplos de request/response.

Integracion con Frontend (TypeScript / React)

Si tu aplicacion PHP tiene un frontend en React o TypeScript, puedes usar los SDKs de frontend para consultar el estado de los comprobantes directamente desde el cliente, sin pasar por tu backend:

# TypeScript / Node.js
npm install ecf-dgii-client

# React (incluye hooks y componentes)
npm install ecf-dgii-react

Tu backend PHP envia el ECF y genera un token de lectura. El frontend usa ese token para hacer polling del estado, obtener el QR (impresionUrl) y el codigo de seguridad (codSec) directamente contra ECF SSD. Ver la seccion Arquitectura Backend / Frontend en la documentacion principal.

Plugin WooCommerce

Si usas WooCommerce, tenemos un plugin listo para facturacion electronica sin escribir codigo:

ECF SSD para WooCommerce

Soporte

Otros SDKs y Plugins

Este SDK es parte de una coleccion de SDKs oficiales para multiples plataformas:

Plataforma Paquete Instalacion
.NET NuGet dotnet add package SSDDO.ECF_DGII.SDK
TypeScript npm npm install ecf-dgii-client
React npm npm install ecf-dgii-react
Python PyPI pip install ecf-dgii-client
PHP Packagist composer require ecfx/ecf-dgii-php
Java Maven Central Ver java/README.md
Kotlin Maven Central Ver kotlin/README.md
iOS/Swift Swift Package Manager Ver ios/README.md
C++ vcpkg / Conan Ver C++/README.md
WooCommerce GitHub Plugin WordPress

Licencia

MIT

Hecho con platano power por SSD Smart Software Development SRL