Idempotencia
Reintentar sin pagar dos veces.
Repite una petición con la misma Idempotency-Key y obtienes la misma respuesta, sin una segunda operación. Es obligatoria en cada POST o DELETE con efecto: pagos, cancelaciones, alta y baja de beneficiarios, cobros y direcciones de depósito.
Reglas
| Situación | Respuesta |
|---|---|
| Misma clave y mismo cuerpo | La misma respuesta, con Idempotent-Replayed: true |
| Misma clave y otro cuerpo | 422 idempotency_key_reused, en producción también pasados 7 días |
| La primera sigue en curso | 409 idempotency_in_progress con Retry-After |
La primera respondió 202 en un alta | El resultado en cuanto exista, no el mismo 202. Aplica a cobros, direcciones de depósito y beneficiarios |
| Falta la clave | 400 idempotency_key_required |
| Clave fuera de largo o duplicada | 400 idempotency_key_invalid |
La clave mide entre 8 y 200 caracteres y su respuesta se conserva 7 días. Después, la misma clave con el mismo cuerpo se comprueba otra vez sin crear una segunda operación. Va firmada: cambiarla invalida la firma. El alcance es por empresa, ambiente y operación.
Deriva la clave de tu identificador interno
No uses valores al azar. Si tu proceso se reinicia, debe calcular la misma clave. pago-factura-1042 sirve; un UUID nuevo en cada intento no. external_ref no deduplica por sí solo.
Ante un timeout
Repite con la misma clave. Nunca la cambies: una clave nueva es una orden nueva.
Qué hacer con la clave tras un rechazo
Todo depende de si el rechazo quedó registrado. retryable te lo dice: un rechazo registrado siempre llega con false, aunque su código admita reintentos en otros casos.
| Rechazo | Qué pasó | Clave |
|---|---|---|
retryable: true: 422 in_review, 409 payment_in_flight, 422 rail_unavailable, 422 beneficiary_not_approved, 500, 503 | No se creó ninguna operación, o no se sabe | La misma, cuando la causa pase |
retryable: false: 422 insufficient_funds, 422 limit_exceeded, 422 amount_below_minimum, 422 payment_rejected, 422 in_review | El rechazo quedó registrado con esa clave | Una nueva: la misma repite el rechazo |
409 quote_changed, 409 quote_expired | No se creó ningún pago | Una nueva, con otra cotización: el cuerpo cambió |
400 invalid_request con payer.<campo> en POST /v1/collections | No se creó nada, pero la clave conserva ese cuerpo | Una nueva para el cuerpo corregido |
422 idempotency_key_reused | La clave ya identifica otra operación | Corrige tu integración |
El error in_review y el estado in_review son distintos
- El error
422 in_reviewconretryable: trueresponde a tu petición antes de ejecutarla y no haypay_. Repite con la misma clave tras la revisión. - El mismo error con
retryable: falsequedó registrado al ejecutar: el pago quedafailed, confailure_code: in_review. Esa clave repite el rechazo, así que usa una nueva tras la revisión. - El estado
in_reviewes de un pago que ya existe. Ese pago sigue en curso: no lo vuelvas a crear, consúltalo.
Qué significa cada resultado
202 processingno es fallo. Elpay_se conserva y se consulta.failed: el pago no se hizo y no queda dinero en tránsito. Para intentarlo de nuevo, usa una clave nueva.returned: el saldo ya volvió.
Errores comunes
- Generar una clave nueva tras un
401o403. Esos errores no dicen si el pago ocurrió: consulta elpay_. - Reutilizar una clave para otro pago: responde
422 idempotency_key_reused.