Skip to main content
Crear un cobro no es una operación idempotente por naturaleza: dos llamadas con el mismo cuerpo crean dos recursos distintos. Para que puedas reintentar sin duplicar y conciliar tus operaciones contra las de TapiPay, la API sigue el patrón de idempotencia por header (el mismo enfoque que Stripe).

Cómo funciona

Envía el header Idempotency-Key en tus peticiones de creación. Es opcional, y tu cuerpo (body) queda limpio: la información de control no se mezcla con los datos del recurso.
La respuesta siempre incluye el campo externalRequestId, hayas enviado o no la key:
  • Si enviaste Idempotency-Key: externalRequestId es exactamente el valor que mandaste.
  • Si no la enviaste: el backend genera un externalRequestId (un UUID) y te lo devuelve, para que lo uses en consultas y conciliación futuras.
En los dos casos el debtId es debt_ + externalRequestId.

Deduplicación permanente

El externalRequestId es una llave única permanente dentro de tu organización: existe una restricción de unicidad sin vencimiento (no hay TTL ni ventana temporal).
Reintentar con una Idempotency-Key ya usada no devuelve el recurso original: devuelve un error 409 RESOURCE_CONFLICT. El recurso no se duplica y recibes una señal explícita de que la key ya estaba ocupada.
409 RESOURCE_CONFLICT
Por eso la key debe ser única por intención de operación: usa una key distinta para cada cobro que quieras crear, y reusa la misma solo cuando estás reintentando exactamente la misma operación tras un timeout o un error de red.

Doble función: idempotencia y conciliación

El externalRequestId cumple dos roles a la vez:

Idempotencia

Protege contra duplicados cuando reintentas una petición que falló o expiró.

Conciliación

Es la llave externa de la deuda. Puedes filtrar y listar por ella: GET /debts?externalRequestId=....

Dónde aplica cada llave

Cada recurso de creación tiene su propia llave externa.

Suscripciones

La llave de una suscripción es externalSubscriptionId, que va en el cuerpo y es única por organización. Repetirla devuelve 409 RESOURCE_CONFLICT. POST /subscriptions no usa el header Idempotency-Key. Las deudas que genera la suscripción usan externalRequestId = <externalSubscriptionId>-cycle-<n>, con n desde 0, así que puedes ubicar la del primer ciclo con GET /debts?externalRequestId=SUB-2026-007-cycle-0. Ver Suscripciones.

Ligas de pago

La llave de una liga es externalPaymentLinkId:
  • Si la envías en el cuerpo, se usa ese valor y el header Idempotency-Key se ignora.
  • Si no la envías pero mandas el header Idempotency-Key, el valor del header se usa como externalPaymentLinkId.
  • Si no envías ninguno de los dos, la liga no tiene llave externa: externalPaymentLinkId viene en null y cada request crea una liga nueva.
Repetir un externalPaymentLinkId devuelve 409 RESOURCE_CONFLICT y no se crea ninguna deuda. Ver Ligas de pago.
La idempotencia se aplica por organización. La misma llave en dos organizaciones distintas no interfiere entre sí.