Saltearse al contenido

Facturar en Ecuador

Estados de un comprobante

Toda factura emitida por la API pasa por esta máquina de estados:

Diagrama de estados: pendiente pasa a enviado, y de ahí a autorizado, no autorizado o error de envíopendienteenviadoautorizadono_autorizadoerror_envioPOST /retry
Del envío a la autorización. Los estados en verde y rojo son finales; error_envio se reintenta solo.

Olympus aceptó la factura, la numeró y le asignó su clave de acceso. Está construyendo y firmando el XML. Es el estado con el que responde POST /invoices/issue.

Qué hacer: nada. Espera unos segundos y consulta.

El SRI recibió el comprobante y lo está procesando. Falta su respuesta de autorización.

Qué hacer: seguir consultando, espaciando los intentos.

El SRI lo autorizó. El comprobante tiene validez tributaria. Llegan numero_autorizacion, fecha_autorizacion y los enlaces al PDF, al XML y a la página pública de verificación. Si el comprador tenía correo, ya le llegó el RIDE.

Qué hacer: guardar la autorización en tu sistema. Has terminado.

El SRI lo rechazó. mensajes[] dice por qué, con los códigos del propio SRI.

Qué hacer: leer el motivo. Algunos se arreglan reintentando (POST /invoices/{id}/retry); otros exigen corregir la factura desde Olympus. Ver Errores del SRI.

No se pudo entregar al SRI: su servicio no respondió, hubo un problema de red o la firma falló. No significa rechazo.

Qué hacer: normalmente nada. Olympus reintenta solo cada pocas horas. Si tienes prisa, POST /invoices/{id}/retry.

La factura se anuló en Olympus. La anulación ante el SRI es un trámite que el contribuyente hace en el portal del SRI; la API no anula comprobantes.

En la práctica:

PercentilTiempo hasta autorizado
Habitual2–10 segundos
A vecesHasta 1 minuto
Cierres de mes y horas puntaVarios minutos

El SRI es un servicio externo: su disponibilidad no depende de Olympus. Diseña tu integración asumiendo que puede tardar.

Una espera con intervalos crecientes:

import time
ESPERAS = [3, 5, 8, 13, 21, 34, 55] # segundos
def esperar_autorizacion(client, factura_id):
for espera in ESPERAS:
time.sleep(espera)
factura = client.get(f"/invoices/{factura_id}").json()
if factura["estado"] in {"autorizado", "no_autorizado"}:
return factura
return factura # Sigue en curso: revísala más tarde con un proceso de fondo.

Mejor aún: no esperes en la petición del usuario. Da la venta por buena con el 202, guarda el id y deja que un proceso de fondo actualice el estado. El cliente recibe su factura por correo en cuanto se autorice.

Un trabajo diario que repasa lo que no terminó bien:

# Rechazadas en los últimos 7 días: requieren atención humana.
rechazadas = client.get("/invoices", params={"estado": "no_autorizado", "desde": hace_una_semana}).json()
# Atascadas: enviadas hace más de una hora sin respuesta.
pendientes = client.get("/invoices", params={"estado": "enviado"}).json()