Reintentos exponenciales
Las llamadas a la API pueden fallar por causas transitorias: timeout de red, rate limit (429) o un 5xx puntual de upstream. La estrategia recomendada es reintentar con backoff exponencial + jitter, reutilizando siempre la misma Idempotency-Key para que un reintento que sí llegó al servidor no genere un comprobante duplicado.
Implementación completa para Node.js con axios. Debe notarse que los errores 4xx distintos de 429 no se reintentan: indican un problema del request que ningún reintento puede resolver.
import axios from 'axios';
async function emitirRobusta(facturaData) {
const idempotencyKey = crypto.randomUUID();
const maxReintentos = 5;
for (let intento = 0; intento < maxReintentos; intento++) {
try {
const { data } = await axios.post(
'https://api.pos.lxsyscr.com/api/v1/facturas',
facturaData,
{
headers: {
'X-Api-Key': process.env.LXS_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey
},
timeout: 30000
}
);
return data;
} catch (err) {
const status = err.response?.status;
// Errores definitivos: no reintentar
if (status >= 400 && status < 500 && status !== 429) {
throw err;
}
// Último intento
if (intento === maxReintentos - 1) throw err;
// Backoff
const retryAfter = err.response?.headers['retry-after'];
const waitMs = retryAfter
? parseInt(retryAfter) * 1000
: Math.min(1000 * Math.pow(2, intento), 30000) + Math.random() * 1000;
await new Promise(r => setTimeout(r, waitMs));
}
}
}Si el servidor devuelve el header Retry-After, debe respetarse siempre: tiene prioridad sobre el cálculo de backoff propio. Ver también códigos de error e idempotencia.