Librería PHP para facturación electrónica con la Dirección General de Impuestos Internos (DGII) de República Dominicana, especialmente diseñada para CodeIgniter 4.
Esta librería es una copia exacta de la funcionalidad de la librería original dgii-ecf de Node.js/TypeScript, pero portada completamente a PHP para CodeIgniter 4.
- ✅ Autenticación con DGII usando certificados digitales (.p12)
- ✅ Firma digital de documentos XML usando XMLDSig
- ✅ Envío de comprobantes fiscales electrónicos (e-CF)
- ✅ Facturas de crédito fiscal (ECF31)
- ✅ Facturas de consumo (ECF32) y resúmenes (RFCE)
- ✅ Consulta de estado de comprobantes
- ✅ Generación de códigos QR para comprobantes
- ✅ Comunicación emisor-receptor
- ✅ Aprobaciones comerciales
- ✅ Anulación de rangos de secuencias
- ✅ Autenticación personalizada con JWT
- ✅ Ambientes múltiples (DEV, CERT, PROD)
- ✅ Cache y logging integrados
- ✅ Configuración flexible
- PHP 8.1 o superior
- CodeIgniter 4.3 o superior
- Extensiones PHP:
openssl,dom,curl,gd(para QR) - Certificado digital válido (.p12) emitido por DigiFirma
composer require dgii-ecf/codeigniter4- Copiar el archivo de configuración:
cp vendor/dgii-ecf/codeigniter4/examples/config_example.php app/Config/DgiiEcf.php- Configurar tu certificado y datos en
app/Config/DgiiEcf.php:
<?php
namespace Config;
use DgiiEcf\Config\DgiiEcf as BaseDgiiEcf;
use DgiiEcf\Core\Environment;
class DgiiEcf extends BaseDgiiEcf
{
public Environment $defaultEnvironment = Environment::DEV;
public array $certificate = [
'path' => APPPATH . '../certificates/mi_certificado.p12',
'password' => 'mi_password_secreto',
];
public string $rncEmisor = '123456789'; // Tu RNC
}- Registrar el proveedor de servicios (opcional):
En app/Config/Services.php:
<?php
namespace Config;
use CodeIgniter\Config\BaseService;
use DgiiEcf\Providers\DgiiEcfServiceProvider;
class Services extends BaseService
{
// Extender servicios de DGII ECF
public static function dgiiEcf(bool $getShared = true)
{
return DgiiEcfServiceProvider::ecf($getShared);
}
}<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use DgiiEcf\DgiiEcf;
class InvoiceController extends Controller
{
public function sendInvoice()
{
try {
// 1. Preparar datos de la factura
$invoiceData = [
'Encabezado' => [
'Version' => '1.0',
'IdDoc' => [
'TipoeCF' => '31',
'eNCF' => 'E310000000001',
// ... más campos
],
'Emisor' => [
'RNCEmisor' => config('DgiiEcf')->rncEmisor,
'RazonSocialEmisor' => 'MI EMPRESA SRL',
// ... más campos
],
// ... más secciones
]
];
// 2. Obtener servicios
$ecf = DgiiEcf::ecf();
$transformer = DgiiEcf::transformer();
$signature = DgiiEcf::signature();
// 3. Autenticar con DGII
$tokenData = $ecf->authenticate();
// 4. Convertir JSON a XML
$xmlInvoice = $transformer->json2xml($invoiceData);
// 5. Firmar documento
$signedXml = $signature->signXml($xmlInvoice, 'ECF');
// 6. Enviar a DGII
$fileName = config('DgiiEcf')->rncEmisor . 'E310000000001.xml';
$response = $ecf->sendElectronicDocument($signedXml, $fileName);
return $this->response->setJSON([
'success' => true,
'trackId' => $response?->trackId
]);
} catch (\Exception $e) {
return $this->response->setJSON([
'success' => false,
'message' => $e->getMessage()
])->setStatusCode(500);
}
}
}public function checkStatus()
{
$trackId = $this->request->getGet('trackId');
$ecf = DgiiEcf::ecf();
$ecf->authenticate();
$status = $ecf->statusTrackId($trackId);
return $this->response->setJSON($status);
}public function generateQR()
{
$qrGenerator = DgiiEcf::qrGenerator();
$qrUrl = $qrGenerator::generateEcfQRCodeURL(
'123456789', // RNC emisor
'987654321', // RNC comprador
'E310000000001', // e-NCF
118000.00, // Monto total
'2024-01-15', // Fecha emisión
'2024-01-15', // Fecha firma
'ABC123', // Código seguridad
Environment::DEV
);
$qrImage = $qrGenerator::generateQRCodeImage($qrUrl);
return $this->response->setJSON([
'qr_url' => $qrUrl,
'qr_image' => $qrImage
]);
}// Servicio principal ECF
$ecf = DgiiEcf::ecf();
// Lector de certificados
$p12Reader = DgiiEcf::p12Reader();
// Firmador de documentos
$signature = DgiiEcf::signature();
// Transformador JSON/XML
$transformer = DgiiEcf::transformer();
// Comunicación emisor-receptor
$senderReceiver = DgiiEcf::senderReceiver();
// Autenticación personalizada
$customAuth = DgiiEcf::customAuthentication();// Utilidades de fecha
$dateUtils = DgiiEcf::dateUtils();
$currentDateTime = $dateUtils::getCurrentFormattedDateTime();
// Utilidades de firma
$signatureUtils = DgiiEcf::signatureUtils();
$securityCode = $signatureUtils::getCodeSixDigitFromSignature($signedXml);
// Generador de QR
$qrGenerator = DgiiEcf::qrGenerator();
// Utilidades XML
$xmlUtils = DgiiEcf::xmlUtils();
// Generador aleatorio
$randomGen = DgiiEcf::randomGenerator();Para implementar endpoints de receptor:
<?php
namespace App\Controllers;
use DgiiEcf\DgiiEcf;
use DgiiEcf\SenderReceiver\ReceivedStatus;
class ReceiverController extends Controller
{
// GET /fe/autenticacion/api/semilla
public function getSeed()
{
$customAuth = DgiiEcf::customAuthentication();
$seed = $customAuth->generateSeed();
return $this->response
->setContentType('application/xml')
->setBody($seed);
}
// POST /fe/autenticacion/api/validacioncertificado
public function validateCertificate()
{
$customAuth = DgiiEcf::customAuthentication();
// Procesar multipart y validar...
$token = $customAuth->verifySignedSeed($signedSeed);
return $this->response->setJSON([
'token' => $token,
'expira' => date('Y-m-d H:i:s', time() + 3600)
]);
}
// POST /fe/recepcion/api/ecf
public function receiveEcf()
{
$senderReceiver = DgiiEcf::senderReceiver();
// Procesar e-CF recibido...
$arecfXml = $senderReceiver->getECFDataFromXML(
$xmlContent,
$receptorRNC,
ReceivedStatus::E_CF_RECIBIDO
);
// Firmar y retornar ARECF
$signature = DgiiEcf::signature();
$signedArecf = $signature->signXml($arecfXml, 'ARECF');
return $this->response
->setContentType('application/xml')
->setBody($signedArecf);
}
}# .env
DGII_CERTIFICATE_PATH="/path/to/certificate.p12"
DGII_CERTIFICATE_PASSWORD="mi_password"
DGII_RNC_EMISOR="123456789"
DGII_ENVIRONMENT="DEV"// app/Config/DgiiEcf.php
public array $certificate = [
'path' => getenv('DGII_CERTIFICATE_PATH'),
'password' => getenv('DGII_CERTIFICATE_PASSWORD'),
];
public string $rncEmisor = getenv('DGII_RNC_EMISOR');- DEV (
Environment::DEV): Ambiente de desarrollo/pruebas - CERT (
Environment::CERT): Ambiente de certificación - PROD (
Environment::PROD): Ambiente de producción
- Guía de Instalación Completa
- Ejemplos Avanzados
- API Reference
- Comunicación Emisor-Receptor
- Troubleshooting
⚠️ Nunca hardcodees contraseñas de certificados en el código⚠️ Usa variables de entorno para datos sensibles⚠️ Mantén los certificados en ubicaciones seguras⚠️ Valida siempre las firmas digitales recibidas
Las contribuciones son bienvenidas. Por favor:
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/nueva-caracteristica) - Commit tus cambios (
git commit -am 'Agregar nueva característica') - Push a la rama (
git push origin feature/nueva-caracteristica) - Abre un Pull Request
Este proyecto está bajo la Licencia MIT. Ver LICENSE para más detalles.
- Librería original: dgii-ecf por Victor Santos
- Portado a CodeIgniter 4: Esta implementación
- Documentación DGII: Facturación Electrónica
- Issues: GitHub Issues
⭐ ¿Te gusta este proyecto? ¡Dale una estrella en GitHub!