Ir al contenido

Conceptos

Antes de integrar conviene fijar cinco ideas. Todo lo demás (transferencias, multi-usos, reconciliación) se deriva de ellas.

Un boleto en el espejo tiene tres datos distintos que no conviene confundir:

ConceptoCampoQué es¿Puede cambiar?
IdentidadexternalRefTu ID del boleto. Es la clave de idempotencia y de todas las consultas.No. Si cambia, para nosotros es otro boleto.
CredencialqrContentLo que está impreso o renderizado en el QR que se escanea en puerta.Sí: una reemisión cambia el QR sin cambiar el boleto.
TitularholderRefEl ID estable de la persona dueña del boleto en tu sistema.Sí: una transferencia cambia el titular.

holderName acompaña a holderRef solo para mostrarlo al operador; no participa en ninguna comparación.

  • externalRef es opcional en el schema, pero sin él no puedes anular (void), consultar el boleto ni transferirlo: el boleto queda identificado solo por su qrContent. Envíalo siempre.
  • qrContent se normaliza en el servidor antes de guardarse y antes de compararse en puerta: trim, y si es una URL http(s) con parámetro chl, el código real es ese parámetro. Detalle en la referencia del bulk.
EstadoQuién lo produceSignificado
validTú (default en el bulk y en el feed)Puede entrar. En boletos multi-uso, sigue valid mientras queden usos.
redeemedSolo la puertaYa entró (o agotó sus usos). Nunca se acepta en un import; un boleto redimido no se pisa.
voidTú (bulk con status: "void" o /tickets/void)Anulado. La puerta responde VOID.

Un boleto admite maxUses entradas (1 por defecto, hasta 1000). Cada lectura válida consume un uso y dispara un webhook ticket.redeemed con uses y max_uses; la lectura que agota el cupo cambia el estado a redeemed. Los boletos multi-uso pueden quedar sellados al titular de su primer uso. Detalle en Multi-usos.

Tu llave pertenece a un proveedor (tu ticketera). Cada experiencia (evento) de Gate puede validar contra un único proveedor, y ese enlace lo configura el equipo de alpadevs.

  • Toda petición de boletos va acompañada de un experienceId (UUID).
  • Si la experiencia no está enlazada a tu proveedor, o no existe, recibes 403 EXPERIENCE_NOT_LINKED. No distinguimos entre “no existe” y “no es tuya”.
  • Un boleto (externalRef) vive en una sola experiencia; no se mueve de evento por import (EXPERIENCE_MISMATCH).

Entrega “al menos una vez” e idempotencia

Sección titulada «Entrega “al menos una vez” e idempotencia»

Los dos sentidos de la integración son idempotentes:

  • Tú → Gate. POST /tickets/bulk es un upsert por externalRef: reenviar la misma fila actualiza, nunca duplica. POST /tickets/void responde already_void si repites. Puedes reenviar tu inventario completo con seguridad.
  • Gate → tú. El webhook se entrega al menos una vez: puedes recibir el mismo evento repetido (reintento tras un timeout, confirmación perdida). eventId es estable entre reintentos: guárdalo y descarta los repetidos respondiendo 2xx.

El pull GET /v1/partner/redemptions complementa al webhook: aunque tengas webhook, úsalo para reconciliar y cubrir cualquier evento perdido.