🇩🇴Rep. DominicanaGuía Técnica

Autenticación en la API DGII para e-CF: OAuth2, tokens y certificados en República Dominicana

Cómo implementar correctamente la autenticación en la API DGII para e-CF en República Dominicana: OAuth2, gestión de tokens, certificados digitales y errores de autenticación frecuentes.

Ing. Carlos Méndez
Arquitecto de Software · Integraciones Fiscales LATAM
7 min lectura7 de septiembre de 2026

Por Ing. Carlos Méndez | 7 de septiembre de 2026

Ing. Carlos Méndez es arquitecto de software con más de 10 años integrando sistemas fiscales en América Latina. Ha liderado implementaciones de facturación electrónica en Colombia, México y Centroamérica para ISVs de mediana y gran escala.

El primer request a la API DGII devuelve 401. El token parece correcto. El certificado está instalado. Las credenciales son las del ambiente correcto. Sin embargo, la autenticación falla y el mensaje de error es genérico: 'unauthorized'. La autenticación en la API DGII para e-CF combina dos mecanismos distintos — OAuth2 para la sesión y certificado digital para la firma — y confundir sus roles es el origen más común de este tipo de error.

Esta guía documenta los dos niveles de autenticación que requiere la integración e-CF DGII, cómo obtener y renovar tokens, cómo vincular el certificado al flujo de transmisión, y cómo diagnosticar los errores de autenticación más frecuentes en cada ambiente.

Los dos niveles de autenticación en la API DGII

La API DGII para e-CF opera con dos mecanismos de seguridad independientes que deben implementarse correctamente y en el orden adecuado. El primer nivel es la autenticación de sesión mediante OAuth2 con el flujo Client Credentials: el sistema obtiene un access token que autoriza las llamadas a la API. El segundo nivel es la autenticación del documento: el XML del e-CF debe estar firmado con el certificado digital del emisor antes de ser transmitido. Estos dos mecanismos son complementarios, no alternativos.

Un error frecuente es creer que el certificado digital sustituye el OAuth2 o viceversa. No es así: el OAuth2 autentica al sistema que hace la llamada API, el certificado digital garantiza la integridad y autoría del documento XML transmitido. Ambos son requeridos para que la DGII acepte el e-CF.

OAuth2 con flujo Client Credentials: obtención del access token

El flujo OAuth2 Client Credentials es el mecanismo machine-to-machine de la DGII. No requiere interacción del usuario. El sistema presenta su client_id y client_secret al endpoint de token de la DGII y recibe un access_token con tiempo de expiración. Las credenciales (client_id y client_secret) son asignadas por la DGII durante el proceso de habilitación como contribuyente electrónico.

curl
obtener-token-dgii.sh
# Ambiente QA
curl -X POST https://ecfqa.dgii.gov.do/ecf/auth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=TU_CLIENT_ID' \
  -d 'client_secret=TU_CLIENT_SECRET' \
  -d 'scope=ecf:emision'

# Respuesta esperada:
# {
#   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
#   "token_type": "Bearer",
#   "expires_in": 3600
# }

El access_token expira en 3600 segundos (1 hora) en la mayoría de los casos. El sistema debe gestionar la renovación del token antes de que expire para evitar interrupciones en la emisión. El patrón recomendado es renovar el token cuando quede menos del 20% del tiempo de vida (menos de 720 segundos) o cuando la API retorne 401, lo que sea primero.

Gestión del ciclo de vida del token

Una estrategia correcta de gestión de tokens para integraciones de alto volumen implementa: almacenamiento del token en memoria (no en base de datos, para evitar latencia de lectura en cada request), timestamp de expiación calculado al momento de obtener el token (now + expires_in - buffer de seguridad de 120s), renovación proactiva en background antes del vencimiento, y retry automático con renovación de token cuando la API retorna 401 en un request válido.

python
token-manager-dgii.py
import time
import requests

class DGIITokenManager:
    def __init__(self, client_id: str, client_secret: str, base_url: str):
        self.client_id = client_id
        self.client_secret = client_secret
        self.token_url = f"{base_url}/ecf/auth/token"
        self._token = None
        self._expires_at = 0
        self._buffer_seconds = 120  # renovar 2 min antes de expirar

    def get_token(self) -> str:
        if self._is_token_valid():
            return self._token
        return self._refresh_token()

    def _is_token_valid(self) -> bool:
        return self._token and time.time() < (self._expires_at - self._buffer_seconds)

    def _refresh_token(self) -> str:
        response = requests.post(
            self.token_url,
            data={
                'grant_type': 'client_credentials',
                'client_id': self.client_id,
                'client_secret': self.client_secret,
                'scope': 'ecf:emision'
            },
            headers={'Content-Type': 'application/x-www-form-urlencoded'}
        )
        response.raise_for_status()
        data = response.json()
        self._token = data['access_token']
        self._expires_at = time.time() + data['expires_in']
        return self._token

El certificado digital: uso en la transmisión e-CF

El certificado digital no se usa en la llamada HTTP a la API DGII como certificado TLS de cliente (mutualTLS). Su uso es dentro del XML: firma el contenido del documento e-CF según el estándar XAdES-BES antes de la transmisión. El XML firmado se envía como body del request POST, con el access_token en el header Authorization: Bearer.

El certificado tiene dos componentes críticos: la clave privada (usada para firmar, nunca sale del servidor del emisor) y el certificado público (incluido en la firma XML para que la DGII verifique la autoría). El certificado debe estar vigente al momento de la firma; una firma realizada con un certificado vencido un segundo antes es inválida aunque la fecha del documento sea anterior al vencimiento.

Nunca almacenar la clave privada del certificado en variables de entorno de texto plano en entornos de producción. Usar un gestor de secretos (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) o un Hardware Security Module (HSM) si el volumen de firma lo justifica.

Diferencias de autenticación entre ambiente QA y producción

El ambiente QA (ecfqa.dgii.gov.do) usa credenciales OAuth2 de prueba asignadas por la DGII para el proceso de homologación. Estas credenciales no funcionan en producción. El certificado digital en QA puede ser el certificado de producción del emisor o un certificado de prueba proporcionado por la DGII, dependiendo de la fase del proceso. El ambiente de producción (ecf.dgii.gov.do) requiere credenciales OAuth2 de producción y el certificado digital real del emisor.

Una práctica recomendada es usar variables de entorno o archivos de configuración separados para QA y producción, con validación al inicio del proceso de que las credenciales del ambiente configurado corresponden al dominio de endpoint activo. Mezclar credenciales de QA con el endpoint de producción genera errores 401 que parecen intermitentes porque la DGII puede retornar mensajes de error distintos según el tipo de credencial inválida.

Errores de autenticación frecuentes y cómo diagnosticarlos

Los errores de autenticación más frecuentes son: HTTP 401 con 'invalid_client' — el client_id o client_secret es incorrecto o pertenece al ambiente equivocado. HTTP 401 con 'invalid_scope' — el scope solicitado no está habilitado para las credenciales. HTTP 403 en la transmisión del e-CF — el token es válido pero el RNC del emisor en el token no coincide con el RNC en el XML. Error de firma DGII código 2 — el certificado usado para firmar no corresponde al RNC del emisor registrado. Error de firma DGII código 7 — el certificado está vencido al momento de la validación DGII.

Para diagnóstico rápido: registrar en el log el timestamp exacto de obtención del token, el expires_in recibido, y el timestamp de cada request de transmisión. Permite identificar si los 401 ocurren por token expirado o por credenciales incorrectas sin necesidad de reproducir el error.

Renovación del certificado digital: planificación y continuidad

Los certificados digitales para e-CF en República Dominicana tienen vigencia de 2 años. La renovación requiere iniciar el proceso con la entidad certificadora con al menos 30 días de anticipación. Durante la transición, el sistema debe ser capaz de operar con el certificado nuevo mientras el certificado anterior todavía es válido para documentos firmados con él. Las firmas realizadas con el certificado anterior, mientras estaba vigente, siguen siendo válidas después del vencimiento.

Un sistema robusto implementa monitoreo del vencimiento del certificado con alerta a 60 y 30 días. Los certificados vencidos son el segundo origen más común de interrupciones en producción después de los errores de esquema XML, y son completamente prevenibles con planificación.

Preguntas frecuentes

¿Cuál es la diferencia entre el OAuth2 de la DGII y el certificado digital en la integración e-CF?

El OAuth2 autentica al sistema (ISV o emisor) que consume la API DGII: es el mecanismo que permite al servidor hacer requests HTTP autorizados. El certificado digital autentica el documento: firma el XML del e-CF para garantizar que fue generado por el emisor habilitado y que no fue alterado en tránsito. Ambos deben estar correctamente configurados para que la DGII acepte el e-CF; uno no sustituye al otro.

¿Cómo puedo implementar la renovación automática del access token en mi integración?

El patrón más robusto es un singleton TokenManager que almacena el token y su timestamp de expiración en memoria. Antes de cada request a la API, el sistema consulta al TokenManager: si el token tiene más de 120 segundos de vida restante, se usa directamente; si no, se renueva antes del request. Para sistemas de alta concurrencia, implementar un mutex o semafóro para evitar que múltiples threads soliciten renovación simultánea del token.

¿Qué diferencia hay entre las credenciales OAuth2 de QA y producción DGII?

Son credenciales completamente distintas asignadas por la DGII para cada ambiente. Las credenciales de QA permiten acceder al ambiente ecfqa.dgii.gov.do y están vinculadas a RNC y secuencias de prueba. Las de producción acceden a ecf.dgii.gov.do con RNC y secuencias reales. No existe mecanismo de promoción automática de credenciales entre ambientes; deben gestionarse de forma independiente en el sistema del ISV.

¿Es posible usar un mismo certificado digital para múltiples RNC emisores en la misma integración?

No. Cada RNC emisor debe contar con su propio certificado digital que lo identifica como contribuyente electrónico habilitado. Un ISV que gestiona la facturación de múltiples empresas (modelo multi-tenant) debe mantener certificados separados por cada RNC emisor y aplicar el certificado correcto al momento de firmar el XML del e-CF de cada empresa. El RNC en el certificado debe coincidir con el RNCEmisor del XML.

Sobre el autor

Ing. Carlos Méndez es arquitecto de software con más de 10 años integrando sistemas fiscales en América Latina. Ha liderado implementaciones de facturación electrónica en Colombia, México y Centroamérica para ISVs de mediana y gran escala.