La numeración la lleva su sistema¶
Cada ERP o Facturador numera sus propios documentos, tipo por tipo. Esta API no reserva números, no reparte consecutivos ni lleva ningún contador: usted envía el e-NCF completo con cada comprobante, la API comprueba lo básico y, si pasa, lo manda a la DGII.
¿Venía de enviar sin
e_ncf? Antes la API podía asignarlo cuando faltaba. Ya no:id_doc.e_ncfes obligatorio, y si falta la respuesta es un422que se lo explica.
Qué se envía¶
| Campo | Tipo | Oblig. | Reglas |
|---|---|---|---|
id_doc.e_ncf |
string(13) | ● | E + tipo (2 dígitos) + consecutivo (10 dígitos). El tipo es el de la ruta: un E32… no se admite en /documents/31. |
id_doc.fecha_vencimiento_secuencia |
fecha | ◐ | dd-MM-aaaa. Vencimiento de la autorización de la DGII a la que pertenece ese número. Obligatoria en el 31, 33, 41, 43, 44, 45, 46 y 47; no aplica en el 32 ni en el 34. |
{
"emisor": { "rnc": "133802074" },
"id_doc": {
"e_ncf": "E310000000042",
"fecha_vencimiento_secuencia": "31-12-2028",
"tipo_ingresos": "01",
"tipo_pago": "1"
}
}
Como en toda llamada que actúa por una empresa, la petición declara su RNC en emisor.rnc (obligatorio), que
es también lo que identifica la empresa en cuyo nombre se emite: su token tiene que estar habilitado para ella
(tokens-y-permisos.md).
Si envía su propio XML (passthrough-xml.md), son los nodos <eNCF> y
<FechaVencimientoSecuencia> de siempre, con las mismas reglas.
No hace falta que los números sean correlativos de una petición a otra: dos sistemas de la misma empresa pueden llevar sub-rangos distintos, o puede emitir el 50 y luego el 20. La API no espera ningún orden. Lo que garantiza es que un folio no se usa dos veces.
Qué se comprueba antes de enviar a la DGII¶
Poco, a propósito: la DGII es quien manda sobre sus rangos. Pero cada una de estas comprobaciones
evita un rechazo que, además, puede dejar el número gastado. Si falla alguna, la respuesta es un 422
con el motivo en document.errors (la forma exacta) y no se crea nada: su número sigue libre para el comprobante corregido.
| Comprobación | Mensaje (resumen) |
|---|---|
Estructura E + tipo + 10 dígitos, y que el tipo sea el de la ruta |
«El e-NCF indicado (…) no tiene la estructura E+tipo+10 dígitos del tipo 31.» |
| Que el consecutivo no sea 0 | «El consecutivo empieza en 1.» |
| Que no caiga en un rango anulado (la DGII no admite reutilizar una secuencia anulada) | «…pertenece a un rango anulado y no puede volver a usarse.» |
| Que no caiga en un rango cuya anulación quedó sin confirmar | «…cae en un rango cuya anulación ante la DGII se transmitió sin que llegara a confirmarse…» |
Que la fecha de vencimiento esté declarada (en los tipos que la llevan) y tenga formato dd-MM-aaaa |
«Falta la fecha de vencimiento de la secuencia (id_doc.fecha_vencimiento_secuencia)…» |
| Que la secuencia no haya vencido (el último día de vigencia todavía vale) | «La secuencia del e-NCF … venció el dd-mm-aaaa.» |
Su autorización registrada (opcional)¶
Si nos entrega la autorización que le dio la DGII —el rango y su fecha de vencimiento— y la registramos para su empresa, se hacen dos comprobaciones más, que cazan un error antes de gastar el número:
- que el e-NCF caiga dentro de un rango activo de ese tipo (el mensaje le dice qué rangos hay registrados);
- que la fecha de vencimiento que declara sea la de esa autorización (y si no la declara, se toma de ella).
Es opcional: sin autorización registrada se valida sólo lo que llega en la petición, y la DGII valida el rango por su lado. Si su sistema ya lleva el control de sus rangos, no la necesita.
¿Qué pasa si reenvía un folio que ya existe?¶
Un folio tiene un solo documento. Reenviarlo no es un error de validación ni crea otro comprobante:
no se vuelve a construir, firmar ni transmitir nada, y se le responde según el estado del documento
que ya existe. La respuesta lleva "duplicate": true y el mismo detalle que
GET /api/v1/documents/{identificador} (cómo se arma), sin los
archivos: para el XML y el PDF consulte después el documento por su identificador.
| Estado del documento | HTTP | Qué se le dice | Qué hacer |
|---|---|---|---|
received (1) |
200 |
Ya fue recibido y está en cola para enviarse a la DGII. | Nada: consulte el estado más tarde. |
in_process_dgii (3) |
200 |
Ya se envió y está en espera de la respuesta de la DGII. | Esperar. |
not_found_dgii (7) |
200 |
Ya se envió; la DGII todavía no lo registra y se sigue consultando. | Esperar. |
unresolved (8) |
200 |
Ya se envió, pero la DGII no confirmó su resultado tras varias consultas. | Consulte GET /api/v1/documents/{identificador}; si persiste, contáctenos. |
accepted_dgii (4) |
200 |
«Documento enviado y aprobado anteriormente.» Ya fue procesado: la DGII lo aceptó y tiene validez fiscal. | Nada: ya está. |
conditionally_accepted_dgii (5) |
200 |
«Documento enviado y aprobado anteriormente.» Ya fue procesado: aceptado de forma condicional (con observaciones en errors). |
Nada; corrija las observaciones en lo que emita después. |
rejected_dgii (6) |
409 |
Ya fue procesado y la DGII lo rechazó (motivos en errors). |
Emita el corregido con otro folio. |
rejected_validation (2) |
409 |
Se recibió pero no superó las validaciones previas al envío: nunca llegó a la DGII. | Emita el corregido con otro folio y anule el que no usó. |
system_error (9) |
202 |
Se había detenido por un error interno nuestro: se reintenta su envío. | Esperar y consultar el estado. |
Es la respuesta de siempre de un e-CF suyo (status, message y document), más "duplicate": true. Con un 200 o un
202 el status de la raíz es success; con un 409 es error (el reenvío no sirvió), pero la carga sigue siendo
el document con el estado del que ya existe (cómo leerlas):
{
"status": "success",
"message": "Documento enviado y aprobado anteriormente. El e-NCF E310000000001 ya fue procesado: la DGII lo aceptó y tiene validez fiscal. No se envió de nuevo.",
"duplicate": true,
"document": {
"document_id": 1234,
"ecf_type_code": "31",
"e_ncf": "E310000000001",
"identificador": "133802074E310000000001",
"track_id": "a1b2c3d4-...",
"status_code": 4,
"status": "accepted_dgii",
"status_description": "La DGII aceptó el e-CF: tiene validez fiscal.",
"is_valid_fiscally": true
}
}
El track_id que trae el reenvío es el del documento que ya existe: null si todavía no se transmitió
(o en la factura de consumo (32) por debajo de RD$250.000, que nunca lo tiene), el asignado al
transmitir (in_process_dgii) y conservado en los estados finales
(estados.md).
Cuando el documento existente está aprobado (aceptado o aceptado condicional), el message empieza
siempre por «Documento enviado y aprobado anteriormente.»: su sistema puede reconocer esa frase para dar
el reenvío por resuelto sin interpretar el resto del texto.
Lo que importa de este diseño:
- Reenviar es seguro. Si su petición se cortó y no sabe si llegó, repítala con el mismo folio: si ya había llegado se le responde con ese documento; si no, se recibe como nueva. Nunca se transmite dos veces el mismo e-NCF, que es justo lo que la DGII desaconseja («múltiples TrackIds»).
- Lo que mande en el reenvío no cambia nada. El documento ya se firmó y se transmitió con los datos del primer envío; el cuerpo del reenvío se ignora (queda registrado, a efectos de auditoría, pero no se usa). Si necesita corregir un comprobante rechazado, es otro folio.
- Se contesta aunque el contenido esté mal. Un folio ocupado no valida el cuerpo: es un reenvío, no una emisión.
- El folio es por empresa. El mismo número en otra empresa es otro documento.
- Da igual quién lo envió. El documento es de la empresa, no del sistema que lo emitió: si el folio lo envió antes otro sistema que también atiende a esa empresa, o se envió por otra vía, el reenvío se contesta igual, según su estado. No es un error por «ser de otro», y la respuesta no indica quién lo envió.
- Un documento borrado sigue ocupando su folio.
- Dos peticiones simultáneas con el mismo folio: una crea el documento y la otra recibe la respuesta de duplicado; no hay carrera posible.
Ciclo de vida de un número¶
| Situación | El número… | Qué hacer |
|---|---|---|
422 de validación (no se creó nada) |
sigue libre | Corrija y reenvíe con el mismo número. |
| Sin respuesta (corte, timeout) | puede o no estar usado | Reenvíe el mismo folio: no se duplica. |
| Recibido, en proceso o aceptado | en uso | Nada: consulte el estado. |
Rechazado por la DGII (rejected_dgii) |
quemado: el comprobante es nulo | Emita el corregido con otro folio. Si sequence_reusable es true, la DGII da la secuencia por no utilizada: anúlela. |
Rechazado en validación, ya creado (rejected_validation) |
no se usó ante la DGII | Otro folio para el corregido y anule el que no usó. |
| Un número que no va a utilizar (hueco) | libre, pero sin usar | Anúlelo para no dejar un hueco en su numeración. |
Si factura con el Facturador Web¶
El Facturador Web lleva la numeración por usted: la configura por empresa y por tipo (siguiente número, rango, vencimiento) y envía cada e-NCF a esta API. Esta página es para quien integra su propio sistema.