Reintentos seguros y orderNumber

API v1

El API de Tilopay no es idempotente. No existe una llave de idempotencia ni un reintento que devuelva la transacción original. Si venís de otros procesadores, este es el supuesto que tenés que desarmar antes de escribir código.

orderNumber es único para siempre#

orderNumber es único por comercio a lo largo de toda su operación, para siempre. No se reinicia por día, por mes ni por temporada.

Si se repite, la nueva transacción se rechaza con la respuesta "Transacción duplicada". No devuelve la transacción original: devuelve un rechazo.

El problema del timeout#

Cuando una llamada de pago se cae por red o por timeout, no sabés si la transacción se creó o no. Y ninguna de las dos salidas intuitivas sirve:

Qué haríasQué pasa
Reintentar con el mismo orderNumberRechazo por duplicado, incluso si la primera sí pasó
Reintentar con un orderNumber nuevoRiesgo de doble cobro

Ante un timeout de red no hay reintento seguro.

Qué hacer entonces#

Consultá el estado antes de decidir:

  1. Llamá a POST /api/v1/consult con el orderNumber original.
  2. Si la transacción existe, usá su resultado. No reintentés.
  3. Si no existe, ahí sí podés reintentar — y podés reusar el mismo orderNumber, porque no se consumió.
pago → timeout

        └─→ consult(orderNumber original)
              ├─ existe  → usar ese resultado
              └─ no existe → reintentar

Consecuencias de diseño#

  • Generá el orderNumber en tu sistema antes de llamar al pago y persistilo. Si lo generás al vuelo, después de un timeout no tenés con qué consultar.
  • Nunca derives el orderNumber de algo que se pueda repetir (número de carrito reciclado, timestamp truncado, contador reiniciable).
  • Un "Transacción duplicada" no significa que el cobro falló: significa que ese orderNumber ya se usó. Consultá antes de mostrarle un error al cliente.

Última verificación: 2026-08-28 · Responsable: equipo-integraciones

Ver como Markdown crudo