Anulación de Secuencias (ANECF)
Permite anular ante la DGII rangos de e-NCF que no fueron utilizados o no fueron aceptados, mediante el formato de Anulación de e-NCF (ANECF v1.0). Facturo genera el documento ANECF, lo firma con el certificado de la empresa y lo envía a la DGII.
POST /api/v1/companies/{company_id}/emission/cancel-ranges
Reglas de negocio de la DGII
- Solo secuencias no utilizadas: la DGII acepta ANECF únicamente para números que no fueron aceptados previamente. Un comprobante ya aceptado se neutraliza con una Nota de Crédito Electrónica (E34), no con ANECF.
- 13 caracteres exactos: todo e-NCF tiene el formato
[Serie 1][Tipo 2][Secuencia 10], por ejemploE310000000001. - Series válidas: de
EaZ, exceptoP. - Orden ascendente: la parte numérica de
from_encfdebe ser menor o igual que la deto_encf.
Cuerpo de la petición
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
details | array | Sí | Anulaciones agrupadas por tipo de e-CF. |
details[].ecf_type | integer | Sí | Tipo de e-CF (31, 32, 33, 34, 41, 43, 44, 45, 46, 47). |
details[].sequence_ranges | array | Sí | Rangos a anular. |
details[].sequence_ranges[].from_encf | string | Sí | e-NCF inicial (13 caracteres). |
details[].sequence_ranges[].to_encf | string | Sí | e-NCF final (13 caracteres). Igual a from_encf para anular un solo número. |
details[].line_number | integer | No | Número de línea del detalle. |
dgii_env | string | No | testecf, certecf o ecf. |
company_id | string | No | UUID de la empresa (ya va en la ruta). |
Facturo convierte el cuerpo al XML ANECF v1.0 de la DGII: cada elemento de details es una Anulacion (máximo 10 por petición) y cada rango una Secuencias (SecuenciaeNCFDesde / SecuenciaeNCFHasta). Facturo calcula CantidadeNCFAnulados y la fecha de anulación.
Anular un solo e-NCF
curl -X POST \
"https://ecf.facturord.app/api/v1/companies/$FACTURO_COMPANY_ID/emission/cancel-ranges" \
-H "X-API-Key: $FACTURO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dgii_env": "testecf",
"details": [
{
"ecf_type": 31,
"sequence_ranges": [
{ "from_encf": "E310000000001", "to_encf": "E310000000001" }
]
}
]
}'
Anular varios rangos y tipos en una sola petición
{
"dgii_env": "testecf",
"details": [
{
"ecf_type": 31,
"sequence_ranges": [
{ "from_encf": "E310000000010", "to_encf": "E310000000020" },
{ "from_encf": "E310000000035", "to_encf": "E310000000035" }
]
},
{
"ecf_type": 32,
"sequence_ranges": [
{ "from_encf": "E320000000100", "to_encf": "E320000000150" }
]
}
]
}
Respuesta
{
"rnc": "101672919",
"code": "1",
"name": "Aprobada",
"total_cancelled": 1,
"messages": [],
"signed_xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>...",
"signed_xml_path": "..."
}
| Campo | Tipo | Descripción |
|---|---|---|
rnc | string | RNC del emisor. |
code | string | Código de respuesta de la DGII. |
name | string | Descripción del código (ej.: Aprobada). |
total_cancelled | integer | Cantidad total de secuencias anuladas. |
messages | string[] | Mensajes devueltos por la DGII. |
signed_xml | string | null | XML ANECF firmado enviado a la DGII. |
signed_xml_path | string | null | Ruta interna del XML ANECF firmado. |
¿ANECF o Nota de Crédito?
| Situación | Acción |
|---|---|
| El e-NCF nunca se envió, o la DGII no lo aceptó | Anular con ANECF (este endpoint) |
| Secuencias saltadas, dañadas o vencidas | Anular el rango con ANECF |
| El comprobante ya fue aceptado por la DGII | Emitir una Nota de Crédito Electrónica (E34) |
Con los clientes oficiales
Los clientes oficiales incluyen atajos para este endpoint:
| Método | Descripción |
|---|---|
cancel_ranges / CancelRangesAsync / cancelRanges | Envía uno o varios detalles por tipo de e-CF |
cancel_single_sequence / CancelSingleSequenceAsync / cancelSingleSequence | Anula un único e-NCF |
cancel_sequence_range / CancelSequenceRangeAsync / cancelSequenceRange | Anula un rango continuo |
from ecf_client import FacturoClient, ECFType, DGIIEnv
client = FacturoClient(api_key="...", company_id="...")
res = client.cancel_sequence_range(
ecf_type=ECFType.E31_CREDITO_FISCAL,
from_encf="E310000000010",
to_encf="E310000000020",
dgii_env=DGIIEnv.TESTECF,
)
print(res.code, res.name, res.total_cancelled)