Saltearse al contenido

Facturar en Ecuador

Impuestos (IVA)

Cada línea lleva su impuesto en impuestos[]. En Ecuador, y en esta versión de la API, ese impuesto es siempre el IVA (código 2 del SRI).

{
"descripcion": "Servicio de soporte mensual",
"cantidad": 1,
"precio_unitario": 100.00,
"impuestos": [{ "codigo": "2", "codigo_porcentaje": "4" }]
}

El campo que manda es codigo_porcentaje:

codigo_porcentajeTarifaCuándo se usa
00 %Bienes y servicios gravados con tarifa cero
212 %Tarifa histórica (antes de la subida al 15 %)
314 %Tarifa histórica (2016)
415 %Tarifa general vigente
55 %Tarifa reducida
6—No objeto de IVA
7—Exento de IVA
88 %Tarifa especial (feriados turísticos)
1013 %Tarifa especial

Consúltala siempre al día desde la API:

Ventana de terminal
curl https://olympus.atharix.com/api/v1/catalogs/tax-rates -H "X-API-Key: $OLYMPUS_API_KEY"
{
"data": [
{ "codigo": "2", "codigo_porcentaje": "4", "tarifa": 15.0, "nombre": "IVA 15%" },
{ "codigo": "2", "codigo_porcentaje": "0", "tarifa": 0.0, "nombre": "IVA 0%" }
]
}
"impuestos": [{ "codigo": "2", "codigo_porcentaje": "4" }]

Olympus deduce la tarifa (15 %) y calcula el importe. Es la forma más robusta: si mañana cambia algo en el cálculo, tu integración no necesita tocarse.

"impuestos": [{ "codigo": "2", "tarifa": 15 }]

Olympus deduce el codigo_porcentaje correspondiente. Útil si tu sistema guarda porcentajes y no códigos del SRI.

"impuestos": [
{ "codigo": "2", "codigo_porcentaje": "4", "tarifa": 15, "base_imponible": 100.00, "valor": 15.00 }
]

Olympus comprueba que todo cuadra y rechaza la emisión si no (422 totals_mismatch, tolerancia 0,01). Es la opción más segura cuando tu sistema ya calculó los impuestos y quieres garantizar que se emite exactamente eso.

Una línea sin impuestos se trata como IVA 0 % (codigo_porcentaje 0):

{ "descripcion": "Producto con tarifa cero", "cantidad": 1, "precio_unitario": 50.00 }

Por línea:

base = (cantidad × precio_unitario) − descuento
IVA = base × tarifa ÷ 100 (redondeado a 2 decimales, medio hacia arriba)

Y la factura:

total_sin_impuestos = Σ bases
iva = Σ IVA de cada línea
importe_total = total_sin_impuestos + iva

Dos líneas de 33,33 al 15 %:

MétodoCálculoIVA
Por línea (correcto)round(33,33 × 0,15) × 2 = 5,00 × 210,00
Al final (incorrecto)round(66,66 × 0,15)10,00

Aquí coinciden, pero con 33,35: por línea da 5,00 + 5,00 = 10,00; al final, round(66,70 × 0,15) = 10,01. Un céntimo, y la emisión se rechaza.

Cada línea lleva la suya; no hay problema en mezclarlas:

{
"items": [
{
"descripcion": "Servicio de consultoría",
"cantidad": 1, "precio_unitario": 100.00,
"impuestos": [{ "codigo": "2", "codigo_porcentaje": "4" }]
},
{
"descripcion": "Libro técnico",
"cantidad": 1, "precio_unitario": 20.00,
"impuestos": [{ "codigo": "2", "codigo_porcentaje": "0" }]
}
],
"totales": { "total_sin_impuestos": 120.00, "importe_total": 135.00 }
}

El XML que se envía al SRI lleva el desglose por tarifa, agrupado como exige la ficha técnica.

El descuento va en importe y reduce la base antes de aplicar el IVA:

{
"descripcion": "Licencia anual",
"cantidad": 2,
"precio_unitario": 25.00,
"descuento": 5.00,
"impuestos": [{ "codigo": "2", "codigo_porcentaje": "4" }]
}
base = (2 × 25,00) − 5,00 = 45,00
IVA = 45,00 × 0,15 = 6,75

Si manejas porcentajes, conviértelos tú: descuento = subtotal × porcentaje ÷ 100, redondeado a dos decimales. El descuento no puede superar el subtotal de la línea.

Esta versión acepta un solo impuesto por línea, y tiene que ser IVA. El ICE y el IRBPNR llegarán más adelante; si los envías, la respuesta es 422 unsupported_tax.

Mientras tanto, un negocio que necesite ICE puede emitir esas facturas desde la aplicación web de Olympus.