01Qué hace Lume y qué haces tú
| Lume | Tú |
|---|---|
| Controla la numeración eNCF | Armas el XML del comprobante |
| Valida antes de transmitir | Lo firmas con el certificado del emisor |
| Transmite a la DGII y reintenta | Obtienes el token de autenticación |
| Consulta el veredicto y reconcilia | Imprimes la representación impresa |
| Conserva el registro fiscal | Guardas la venta |
Lume nunca recibe la llave privada. Ni el .p12, ni su contraseña, ni un PIN.
No es una cortesía: custodiar certificados de terceros abre requisitos regulatorios ante INDOTEL que preferimos que ninguna de las dos partes asuma.
02Antes de escribir código
El emisor tiene que estar certificado ante la DGII con software = Lume. Sin eso no hay emisión válida, por perfecta que sea la integración. Ese proceso lo acompañamos nosotros y toma entre 7 y 18 días hábiles.
- Un contribuyente no puede estar postulado con dos proveedores a la vez. Si venía en proceso con otro sistema, hay que reiniciar.
- Iniciar la certificación con Lume no lo desconecta de su proveedor actual. Puede seguir facturando hasta que termine.
Puedes crear credenciales y desarrollar contra certecf desde el primer día. Lo que no funciona hasta que la certificación cierre es emitir en producción.
03Tu credencial
Authorization: Bearer lum_cert_...La credencial identifica a tu sistema, y está autorizada sobre una lista explícita de RNC emisores. El RNC viaja siempre explícito en cada petición; si no estás autorizado sobre él, la respuesta es 403 nombrando ambos.
Si tu sistema atiende a varios emisores, puedes indicar quién disparó la operación:
X-Lume-Actor: cliente_42/usuario_7Se guarda para auditoría. No otorga permisos.
04El token de DGII
Este es el paso que sorprende, así que va primero.
Transmitir a la DGII exige firmar una semilla con el certificado del emisor y cambiarla por un token de una hora. No basta con que el comprobante venga firmado: la autenticación misma necesita la llave.
Como no custodiamos certificados, ese paso lo haces tú:
# 1. Pedir la semilla
curl https://ecf.dgii.gov.do/certecf/autenticacion/api/autenticacion/semilla
# 2. Firmarla con el certificado del emisor (XML-DSig)
# 3. Cambiarla por un token
curl -X POST https://ecf.dgii.gov.do/certecf/autenticacion/api/autenticacion/validarsemilla \
-F 'xml=@semilla-firmada.xml;type=text/xml'
# → { "token": "...", "expira": "...", "expedido": "..." }{
"token": "...",
"expira": "2026-09-01T18:09:38Z",
"environment": "certecf"
}Lo cacheamos por emisor y ambiente. Renuévalo antes de que venza: sin token vigente no transmitimos — aunque el comprobante sí queda registrado y sale solo cuando entregues uno nuevo.
05Numeración
El eNCF va dentro del XML firmado, y la firma cubre el contenido: no se puede renumerar después. Si tienes varias cajas sobre un mismo RNC, dos no pueden reclamar el mismo número — una colisión es un rechazo que ya no se deshace.
{ "rnc": "131123456", "ecfType": "31", "environment": "certecf" }
→ { "encf": "E310000001501", "vencimiento": null }La reserva es atómica: dos llamadas concurrentes nunca obtienen el mismo número.
06Emitir
Idempotency-Key: {tu-id-de-venta}
{
"xml": "<ECF>…</ECF>",
"kind": "ecf",
"environment": "certecf",
"referencia": "POS-2026-09-01-00412"
}{
"id": "febb8ff5-…",
"encf": "E320000000103",
"estado": "transmitido",
"track_id": "e8c09c43-…",
"codigo_seguridad": "abc123",
"qr": "https://ecf.dgii.gov.do/…"
}Es 202, no 200. Aceptamos el comprobante y la DGII decide después. Tu cajero no espera.
El Idempotency-Key es obligatorio. Reintentar con la misma clave devuelve el mismo comprobante con "idempotente": true y nunca crea un segundo. Es lo que hace seguro reintentar tras un timeout, cuando no sabes si llegamos a recibirlo.
Imprime de inmediato, no nos esperes. El codigo_seguridad son los primeros 6 caracteres del SignatureValue de tu propio XML, así que ya tienes todo para el Timbre y el QR.
07Saber qué pasó
| Estado | Significa |
|---|---|
recibido | Lo tenemos y lo validamos. Todavía no salió |
transmitido | Enviado a la DGII, esperando veredicto |
aceptado | La DGII lo aceptó |
rechazado | La DGII lo rechazó. Incluye su respuesta sin traducir |
Nosotros consultamos el veredicto por ti y reconciliamos. No tienes que hacer polling contra la DGII.
08Errores
Todos verificados contra el servicio, no inventados.
| Código | Cuándo | Qué hacer |
|---|---|---|
401 | Falta la credencial o no es válida | Revisa el header Authorization |
403 | No estás autorizado sobre ese RNC | Pídenos la autorización para ese emisor |
400 | Falta Idempotency-Key | Manda tu identificador de venta |
400 | Falta el RNC o environment | Van siempre explícitos. No hay default |
422 | El XML no está firmado | Fírmalo antes. Lume no firma documentos |
409 | No hay token de DGII vigente | Entrega uno. El comprobante ya quedó registrado |
502 | Error hablando con la DGII | Reintenta con la misma Idempotency-Key |
El cuerpo de los errores trae como_resolver cuando hay algo concreto que hacer.
09Ambientes
environment es obligatorio en cada petición. No hay valor por defecto, y testecf está rechazado explícitamente.
| Valor | Qué es |
|---|---|
certecf | Certificación. Aquí desarrollas y aquí se certifica cada emisor |
ecf | Producción. Comprobantes fiscales reales |
Un emisor solo puede emitir en certecf mientras su postulación está activa. Una vez que llega a Finalizado, la DGII cierra esa ventana y responde "no tiene una postulación activa".
Las pruebas de integración ocurren durante la certificación de un emisor real. Es una restricción del régimen, no una decisión nuestra.
10Lo que no está en v0
- Recepción de e-CF de terceros, ARECF y aprobación comercial
- Anulación de secuencias no utilizadas
- Webhooks — hoy se consulta con
GET /documentos/{id} - Sub-rangos por punto de emisión, para POS offline con varias cajas
- Que Lume arme el XML a partir de un payload de venta
11Referencia rápida
| Método | Ruta | Para qué |
|---|---|---|
POST | /emisores/{rnc}/token | Entregar el token de DGII |
POST | /reservar-encf | Reservar el siguiente eNCF |
POST | /submit | Emitir un comprobante firmado |
GET | /documentos/{id} | Estado y transiciones |
POST | /consulta | Consultar un trackId |
GET | /health | Estado del servicio |