Tema
Tipos de documento
Once tipos implementados. La regla que decide cuál usar casi siempre es una sola: a quién le vendes y si esa persona necesita deducir crédito fiscal. Los demás cubren traslado, exportación, retención, liquidación y donación.
Cuál usar
¿Le compras tú a alguien que no es contribuyente inscrito?
│
└── sí ──▶ 14 Factura de Sujeto Excluido
│
no
│
¿Es una exportación?
│
└── sí ──▶ 11 Factura de Exportación
│
no
│
¿Es un traslado de bienes, sin venta?
│
└── sí ──▶ 04 Nota de Remisión
│
no
│
¿Tu cliente es contribuyente inscrito y va a deducir el IVA?
│
├── sí ──▶ 03 Comprobante de Crédito Fiscal
└── no ──▶ 01 Factura
¿Hay que corregir un documento ya sellado?
│
├── devolver mercancía de 01, 11 o 14 ──▶ Evento de Retorno (tipoEvento 18)
├── el cliente de un CCF (u otro con crédito) devuelve o se le rebaja ──▶ 05 Nota de Crédito
└── hay que cobrarle de más ────────────▶ 06 Nota de DébitoRetención (07), liquidación (08/09) y donación (15) no salen de esa pregunta: cada uno documenta una operación distinta de una venta.
La tabla
| 01 Factura | 03 CCF | 05 Nota de Crédito | 06 Nota de Débito | 14 FSE | |
|---|---|---|---|---|---|
precioUni lleva IVA | sí | no | no | no | no (sin IVA) |
| Tratamiento del IVA | dentro del ítem | tributo aparte (20) | tributo aparte | tributo aparte | no lleva |
| Receptor obligatorio | no | sí | sí | sí | sí |
| Campos del receptor | — | NIT, nombre, actividad, dirección | ídem | ídem | tipo y número de documento, nombre, dirección |
| Tipo de documento fijo | — | — | 36 (NIT) | 36 (NIT) | — |
| NRC del emisor | no | no | sí | sí | no |
| Documentos relacionados | prohibido | prohibido | 1 a 50 | 1 a 50 | prohibido |
| Máximo de ítems | 2000 | 2000 | 2000 | 2000 | 2000 |
| 04 Remisión | 07 Retención | 08 Liquidación | 09 DCL | 11 Exportación | 15 Donación | |
|---|---|---|---|---|---|---|
| Tratamiento del IVA | sin IVA | IVA retenido por línea | gravada / exenta / exportación | IVA de la liquidación | exportación | sin venta |
| Receptor | con bienTitulo (CAT-025) | NIT/NRC | CAT-032 domicilio | NIT, correo | país, tipo de persona | país, CAT-032 |
| Líneas | productos a trasladar | DTE relacionados | DTE relacionados | un solo cuerpo (no lista) | productos exportados | tipoDonacion (CAT-026) |
| Máximo de ítems | 2000 | 500 | 500 | 1 | 2000 | 2000 |
| Relacionados | opcionales | por línea | por línea | no | opcionales | otrosDocumentos |
No codifiques estas tablas. Pídelas:
bash
curl -s "$API/api/v1/dte/tipos-documento" -H "Authorization: Bearer $CLAVE"Es la misma con la que valida el servidor. Si cambia con la normativa, tu integración se entera sin desplegar.
precioUni: el error del 13 %
Es el campo que más se equivoca al integrar, y el peor, porque no falla: produce un documento que sella correctamente con un total distinto del que cobraste.
Factura (01): precioUni = 11.30 → total 11.30, IVA implícito 1.30
CCF (03): precioUni = 10.00 → total 11.30, IVA desglosado 1.30El mismo bien, el mismo total al cliente, dos números distintos en el campo. Si mandas 11.30 en un CCF, el cliente acaba pagando 12.77.
Si tus precios están guardados con IVA incluido —que es lo normal en un punto de venta—, para el CCF hay que dividir entre 1.13:
javascript
const precioParaElDTE = reglas.precioConIva
? precioConIva
: redondear(precioConIva / 1.13, 6);Guarda seis decimales en la división. Redondear a dos en cada línea hace que la suma se desvíe unos centavos del total, y ahí es donde aparece un rechazo por totales que no cuadran.
01 · Factura
Para consumidor final. El receptor entero es opcional: quien pasa por la caja y no quiere dar su nombre igual tiene derecho a su factura.
json
{
"tipoDte": "01",
"items": [
{"descripcion": "Almuerzo ejecutivo", "cantidad": 2, "uniMedida": 59,
"precioUni": 8.50, "tipoItem": 2}
],
"condicionOperacion": 1,
"formaPago": "01"
}Si el cliente sí quiere que aparezcan sus datos, manda el receptor con lo que tengas. Nada es obligatorio aquí.
03 · Comprobante de Crédito Fiscal
Para vender a un contribuyente inscrito que va a deducir el IVA. Su receptor va completo, porque su declaración tiene que cuadrar con la tuya.
json
{
"tipoDte": "03",
"receptor": {
"nit": "06140702191120",
"nrc": "654321",
"nombre": "CLIENTE, S.A. DE C.V.",
"codActividad": "46900",
"descActividad": "Venta al por mayor",
"direccion": {
"departamento": "06", "municipio": "23", "distrito": "14",
"complemento": "COLONIA ESCALON, SAN SALVADOR"
},
"telefono": "22222222",
"correo": "contabilidad@cliente.com"
},
"items": [
{"descripcion": "Servicio de consultoría", "cantidad": 1, "uniMedida": 59,
"precioUni": 100.00, "tipoItem": 2}
],
"condicionOperacion": 2,
"formaPago": "05"
}precioUni sin IVA. El total de este documento es 113.00.
05 · Nota de Crédito
Resta. Se usa cuando el cliente devuelve, cuando se le concede un descuento posterior, o cuando hay que corregir a la baja un documento sellado.
json
{
"tipoDte": "05",
"receptor": { "...igual que en el CCF..." },
"documentosRelacionados": [
{"numeroDocumento": "2F380579-2A15-42E8-9ADF-4EA97AE4DA3A"}
],
"items": [
{"descripcion": "Servicio de consultoría", "cantidad": 1, "uniMedida": 59,
"precioUni": 100.00, "tipoItem": 2}
]
}Tres reglas que hay que tener claras:
Solo ajusta documentos que transfieren crédito fiscal. Los tipos ajustables son 03, 05, 06, 07, 08, 09 y 11. Nunca 01, 04 ni 14. Una Factura no transfiere crédito, así que no hay crédito que devolver; intentarlo se rechaza aquí, que es mejor que descubrirlo en un rechazo de Hacienda que cuesta un correlativo.
Para cancelar una Factura entera, se invalida: POST /api/v1/dte/documentos/{cg}/invalidar. Para devolver mercancía de una Factura, Factura de Exportación o FSE vigentes, el Evento de Retorno: POST /api/v1/dte/documentos/{cg}/retorno. Un CCF se ajusta con Nota de Crédito, no con retorno.
Con varios relacionados, cada línea dice a cuál ajusta. Con uno solo se puede omitir; con varios, numeroDocumento dentro de cada ítem es obligatorio, porque nadie más puede adivinar la correspondencia.
El documento ajustado tiene que estar sellado. Antes del sello no hay crédito fiscal que ajustar, y el rechazo lo dice con esas palabras.
06 · Nota de Débito
Igual que la de crédito pero suma: un cargo que faltó, un ajuste al alza, intereses por mora. Las mismas reglas de relacionados.
14 · Factura de Sujeto Excluido
Es una compra, no una venta. La emite quien compra, a alguien que no es contribuyente inscrito: un proveedor informal, un servicio ocasional.
Por eso el «receptor» es el sujeto excluido al que le compraste, y va sin NRC ni actividad económica — justamente porque no es contribuyente.
json
{
"tipoDte": "14",
"receptor": {
"tipoDocumento": "13",
"numDocumento": "012345678",
"nombre": "JUAN PEREZ",
"direccion": {
"departamento": "06", "municipio": "23", "distrito": "14",
"complemento": "SAN SALVADOR"
}
},
"items": [
{"descripcion": "Servicio de albañilería", "cantidad": 1, "uniMedida": 59,
"precioUni": 300.00, "tipoItem": 2}
],
"retencionRenta": 0.10
}retencionRenta acepta 0 o 0.10. El 10 % es el Art. 162 del Código Tributario, pero no siempre aplica: depende del monto y del tipo de servicio. Consúltalo con el contador del contribuyente antes de fijarlo en tu código.
No lleva IVA.
Invalidar en vez de ajustar
Cuando el documento entero está mal —se emitió a quien no era, se duplicó—, se invalida:
bash
curl -s -X POST "$API/api/v1/dte/documentos/$CG/invalidar" \
-H "Authorization: Bearer $CLAVE" \
-H "Content-Type: application/json" \
-d '{
"tipoAnulacion": 2,
"motivo": "La operación se rescindió a solicitud del cliente",
"nombreResponsable": "MARIA LOPEZ",
"tipoDocResponsable": "36",
"numDocResponsable": "06140702191120",
"nombreSolicita": "JUAN PEREZ",
"tipoDocSolicita": "13",
"numDocSolicita": "012345678"
}'tipoAnulacion: 1 error en la información, 2 rescindir la operación, 3 otro.
tipoAnulacion: 3lo rechaza Hacienda con el código 096 en una Factura. Comprobado contra el ambiente de pruebas. Los tipos 1 y 2 sellan sin problema. Si necesitas anular una Factura, usa el que corresponda de esos dos.
Invalidar no borra: el correlativo sigue consumido y el documento queda con su historia. Es un evento que Hacienda registra sobre él.
04 · Nota de Remisión
Traslado de bienes sin valor fiscal. No transfiere crédito y una NC/ND no la ajusta. El receptor lleva bienTitulo (CAT-025: a título de qué se remiten los bienes). Los documentos relacionados son opcionales.
json
{
"tipoDte": "04",
"receptor": {
"tipoDocumento": "36",
"numDocumento": "06140101011011",
"nombre": "COMERCIAL LA CEIBA, S.A. DE C.V.",
"bienTitulo": "04"
},
"items": [
{"descripcion": "Cajas de producto", "cantidad": 10, "uniMedida": 59,
"precioUni": 1.00, "tipoItem": 1}
]
}bienTitulo 04 es depósito; el catálogo CAT-025 tiene el resto. Pídelo en GET /api/v1/dte/catalogos/CAT-025.
11 · Factura de Exportación
Receptor extranjero: país (CAT-020), nombre del país, tipo de persona (CAT-029). Del emisor: recinto fiscal (CAT-027), régimen (CAT-028) y tipo de ítem exportado. Del resumen: Incoterms (CAT-031). El IVA no es el tributo 20 doméstico.
Es ajustable por Nota de Crédito o Débito. Un retorno de mercancía exportada va por Evento de Retorno, y país, recinto, régimen y tipo de exportación tienen que coincidir con el original.
json
{
"tipoDte": "11",
"receptor": {
"nombre": "ACME IMPORTS LLC",
"codPais": "US",
"nombrePais": "Estados Unidos",
"tipoPersona": 2
},
"tipoItemExpor": 1,
"recintoFiscal": "01",
"tipoRegimen": "EX",
"regimen": "EX1",
"codIncoterms": "09",
"descIncoterms": "FOB-Libre a bordo",
"items": [
{"descripcion": "Café oro", "cantidad": 100, "uniMedida": 59,
"precioUni": 10.00, "tipoItem": 1}
]
}07 · Comprobante de Retención
Las líneas no son productos: cada ítem es un DTE sellado sobre el que se retiene IVA (tipoDte, tipoGeneracion, numeroDocumento, fechaEmision, montoSujetoGrav, codigoRetencionMH). Máximo 500 líneas. El receptor es contribuyente (NIT/NRC). Es ajustable por NC/ND.
json
{
"tipoDte": "07",
"receptor": { "nit": "06140101011011", "nrc": "123456", "nombre": "..." },
"items": [
{
"tipoDte": "03",
"tipoGeneracion": 1,
"numeroDocumento": "EL-CG-DEL-CCF",
"fechaEmision": "2026-08-06",
"montoSujetoGrav": 100.00,
"codigoRetencionMH": "22"
}
]
}codigoRetencionMH 22 es retención del 1 % (CAT-006). El 13 % es C4.
08 · Comprobante de Liquidación
Estructura parecida a la retención: líneas ligadas a DTE, máximo 500. El receptor lleva codDomiciliado (CAT-032). tipoModelo y tipoOperacion van fijos en 1: este tipo no admite contingencia.
09 · Documento Contable de Liquidación
No tiene resumen ni lista de ítems. El cuerpo es un objeto con el período y los montos de la liquidación. Exige extension (nombEntrega, docuEntrega; codEmpleado opcional): quién genera el documento.
json
{
"tipoDte": "09",
"receptor": {
"nit": "06140101011011", "nombre": "...",
"correo": "conta@ceiba.test", "tipoEstablecimiento": "02"
},
"liquidacion": {
"periodoInicio": "2026-07-01",
"periodoFin": "2026-07-31",
"valorOperaciones": 1000.00,
"porcentComision": 5
},
"extension": {
"nombEntrega": "MARIA LOPEZ",
"docuEntrega": "012345678"
}
}15 · Comprobante de Donación
Cada línea lleva tipoDonacion (CAT-026: 1 efectivo, 2 bien, 3 servicio) y, si aplica, depreciación. otrosDocumentos es obligatorio. tipoOperacion fijo en 1. El receptor identifica país y domicilio (CAT-032).
json
{
"tipoDte": "15",
"receptor": {
"nombre": "FUNDACION EJEMPLO",
"codPais": "SV",
"nombrePais": "El Salvador",
"codDomiciliado": 1
},
"items": [
{"descripcion": "Donación en especie", "cantidad": 1, "uniMedida": 59,
"precioUni": 50.00, "tipoItem": 1, "tipoDonacion": 2}
]
}Evento de Retorno (tipoEvento 18)
No es un tipoDte. No consume correlativo. No invalida el DTE original ni genera crédito fiscal al receptor. Solo aplica a Factura (01), Factura de Exportación (11) y FSE (14). Un CCF se ajusta con Nota de Crédito.
bash
curl -s -X POST "$API/api/v1/dte/documentos/$CG/retorno" \
-H "Authorization: Bearer $CLAVE" \
-H "Content-Type: application/json" \
-d '{"items":[{"numItem":1,"cantidad":1}]}'items vacío devuelve todas las líneas del original. Varios retornos sobre el mismo DTE si el acumulado no supera el valor original. El plazo es de tres meses desde el sello.
Con un retorno vigente no se puede invalidar la factura: hay que invalidar el retorno primero. Un error en el retorno se corrige con Evento de Invalidación, no con otro retorno.
En una FEX, país, recinto, régimen y tipo de exportación tienen que coincidir con el original; el builder los copia, no los inventa.