Guía · Referencia del API

Lume · RiserUp SRL

Integración e-CF

Emite comprobantes fiscales electrónicos válidos ante la DGII desde tu propio sistema, sin construir el ciclo completo ni entregarnos la llave privada de tus clientes.

Versión v0 Ambiente staging Base URL lume-ecf-staging.up.railway.app
v0

El contrato está probado punta a punta contra la DGII. Producción todavía no está abierta.

Los nombres de campo pueden cambiar antes de la v1. La forma del flujo — token, numeración, emisión, reconciliación — no.

01TokenFirmas la semilla y nos lo entregas
02ReservarPides el siguiente eNCF
03FirmarArmas y firmas el comprobante
04EmitirNos lo mandas, transmitimos
05ReconciliarConsultamos el veredicto por ti

01Qué hace Lume y qué haces tú

Lume
Controla la numeración eNCFArmas el XML del comprobante
Valida antes de transmitirLo firmas con el certificado del emisor
Transmite a la DGII y reintentaObtienes el token de autenticación
Consulta el veredicto y reconciliaImprimes la representación impresa
Conserva el registro fiscalGuardas 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

Header
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:

Opcional
X-Lume-Actor: cliente_42/usuario_7

Se 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ú:

Contra la DGII
# 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": "..." }
POST/emisores/{rnc}/token
Request
{
  "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.

POST/reservar-encf
Request · Response
{ "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

POST/submit
Request
Idempotency-Key: {tu-id-de-venta}

{
  "xml": "<ECF>…</ECF>",
  "kind": "ecf",
  "environment": "certecf",
  "referencia": "POS-2026-09-01-00412"
}
202 Accepted
{
  "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ó

GET/documentos/{id}
EstadoSignifica
recibidoLo tenemos y lo validamos. Todavía no salió
transmitidoEnviado a la DGII, esperando veredicto
aceptadoLa DGII lo aceptó
rechazadoLa 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ódigoCuándoQué hacer
401Falta la credencial o no es válidaRevisa el header Authorization
403No estás autorizado sobre ese RNCPídenos la autorización para ese emisor
400Falta Idempotency-KeyManda tu identificador de venta
400Falta el RNC o environmentVan siempre explícitos. No hay default
422El XML no está firmadoFírmalo antes. Lume no firma documentos
409No hay token de DGII vigenteEntrega uno. El comprobante ya quedó registrado
502Error hablando con la DGIIReintenta 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.

ValorQué es
certecfCertificación. Aquí desarrollas y aquí se certifica cada emisor
ecfProducción. Comprobantes fiscales reales
No existe un sandbox permanente

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étodoRutaPara qué
POST/emisores/{rnc}/tokenEntregar el token de DGII
POST/reservar-encfReservar el siguiente eNCF
POST/submitEmitir un comprobante firmado
GET/documentos/{id}Estado y transiciones
POST/consultaConsultar un trackId
GET/healthEstado del servicio