Ir al contenido

Idempotencia

Una red falla en el peor momento: enviaste la factura y la respuesta no llegó. ¿Se emitió? Si reintentas a ciegas, puedes emitir dos. La cabecera Idempotency-Key lo resuelve: la primera petición con una llave crea el recurso, y repetirla devuelve ese mismo recurso.

Ventana de terminal
curl https://api.emitay.com/v1/invoices \
-H "Authorization: Bearer $EMITAY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: factura-pedido-8412" \
-d '{
"series": "F001",
"customer": { "document_number": "20100066603", "name": "CLIENTE S.A." },
"items": [
{
"description": "Servicio de consultoría",
"quantity": 2,
"unit_price": "50.00"
}
],
"metadata": { "pedido": "8412" }
}'
  • La primera vez responde 201. Las siguientes, 200 con el mismo comprobante como está ahora (ya con el veredicto de SUNAT, si llegó).
  • No se compara el cuerpo: la llave identifica la operación. Usa un valor que ya tengas y sea único para lo que emites: el id del pedido, de la venta, del cobro.
  • Una petición rechazada (422) no registra la llave: corrige y reintenta con la misma.

La llave vale por un recurso. Si usas la del pedido para su factura, usa otra para su nota de crédito (nota-pedido-8412). La misma llave en una petición de otro tipo responde 409 conflict nombrando el comprobante que ya creó, en lugar de devolvértelo como si hubieras emitido la nota.

En todo POST que crea algo: emitir cualquier comprobante, anular, enviar por correo, crear un endpoint de webhook y crear un layout.

La llave de un comprobante no caduca. La de los demás recursos se recuerda 30 días.

Toda llamada del SDK que crea algo lleva una Idempotency-Key. Si no das una, genera la suya y la repite en cada reintento automático: un corte de red en mitad de una emisión no duplica la factura.

Da la tuya cuando la llamada misma se puede repetir: un trabajo que corre dos veces, un proceso que se reinicia, un usuario que pulsa otra vez.

Llave generada (por defecto) Llave propia (idempotencyKey)
Reintentos del SDK ante un fallo de red No duplican No duplican
Volver a ejecutar tu código para el mismo pedido Emite otro comprobante Devuelve el mismo
Respuesta ¿Reintentar?
Sin respuesta, 5xx Sí, con la misma Idempotency-Key
429 Sí, tras los segundos de Retry-After
4xx (salvo 429) No: la petición fallará igual hasta que la corrijas

El SDK hace exactamente esto: reintenta dos veces, con una pausa que crece, solo lo que se puede repetir sin hacerlo dos veces.

import { Emitay } from "emitay";
const emitay = new Emitay(process.env.EMITAY_API_KEY, {
maxRetries: 2, // reintentos de cada llamada; 0 los desactiva
timeoutMs: 60_000, // cuánto espera una respuesta
});