Flujos de integración

Manejo de errores

Un integrador robusto trata los errores como un escenario esperado, no como una excepción. Esta guía agrupa los patrones que necesitas implementar para producir una integración estable contra la API y el SRI.

Clasifica el error por origen

Antes de reaccionar, decide en cuál de estas tres categorías cae el error:

  1. Cliente — tu petición está mal (4xx). No reintentes; corrige.
  2. Servidor / infraestructura — 429, 503, timeouts. Reintenta con backoff.
  3. SRI — recepción o autorización rechazada. Lee el detalle, corrige y reemite.

Patrón general (pseudocódigo)

javascript
async function call(method, path, body) {
  const res = await fetch(BASE + path, {
    method,
    headers: { 'X-API-Key': KEY, 'Content-Type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  });

  if (res.status === 204) return null;
  const payload = await res.json();

  if (res.ok) return payload.data ?? payload;

  // Map by HTTP status
  if (res.status === 401 || res.status === 403) throw new AuthError(payload);
  if (res.status === 422)                       throw new ValidationError(payload);
  if (res.status === 404)                       throw new NotFoundError(payload);
  if (res.status === 429)                       throw new RateLimitError(payload, res.headers.get('Retry-After'));
  if (res.status >= 500)                        throw new UpstreamError(payload);

  throw new ApiError(payload);
}

Validación previa

  • Antes de un POST /documents, valida que business_id, customer_id e items[].item_id existan en tu lado.
  • Confirma que la fecha del comprobante esté dentro de la ventana aceptada por el SRI (no a más de N días vista, según resolución vigente).
  • Asegúrate de que el cliente tenga email antes de llamar a email:send.

Cómo leer un Problem Details

json
{
  "type": "about:blank",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "El RUC del cliente no es válido.",
  "errors": [
    { "field": "customer_id", "message": "El RUC del cliente no es válido." }
  ],
  "instance": "urn:uuid:9f2c..."
}

errors[].field es exactamente el nombre del campo que falló: úsalo para resaltar el input correspondiente en tu UI, o para construir un mapa de validación.

Reintentos con backoff

javascript
async function withRetry(fn, { tries = 5 } = {}) {
  let delay = 1000;
  for (let attempt = 1; attempt <= tries; attempt++) {
    try {
      return await fn();
    } catch (err) {
      const retriable =
        err instanceof RateLimitError ||
        err instanceof UpstreamError ||
        err.name === 'TimeoutError';

      if (!retriable || attempt === tries) throw err;

      const wait = err.retryAfter
        ? Number(err.retryAfter) * 1000
        : delay;

      await new Promise(r => setTimeout(r, wait));
      delay *= 2;
    }
  }
}

Errores específicos del SRI

Mensaje típicoSignificadoAcción
"FIRMA INVÁLIDA"El certificado .p12 está vencido o corrupto.Sube una firma nueva en POST /businesses/{id}/files.
"CLAVE DE ACCESO REGISTRADA"El SRI ya recibió un comprobante con la misma clave.Consulta el documento (GET /documents/{id}) y procede como si ya estuviera emitido.
"SECUENCIAL EN USO"Otro comprobante en el SRI ya usó ese número.Alinea el secuencial con PUT /sequences/{id} y reemite.
"RECEPCIÓN PENDIENTE"Aún no hay respuesta de autorización.Llama PUT /documents/{id} con { "verify": true } tras unos minutos.