GoZap Analytics

Receta

Integrar un punto de venta en una tarde

Toda la integración se puede seguir con curl y nada más. Lo que esta receta agrega sobre la guía de API es el otro lado del mostrador: qué hace quien administra el venue mientras quien programa escribe.

Vas a lograrTu punto de venta acreditando puntos y quemando cupones en tiempo real
TardaUna tarde de trabajo, más el trámite del aviso si hace falta
Hace faltaAlguien que pueda tocar el software de la caja
Participan TúQuien programaLa caja

Antes de nada, una pregunta que decide si esto toma una tarde o una semana: ¿tu proveedor va a recibir nombres y correos?

Si sí, es una transferencia de datos personales y tiene que estar nombrado en tu aviso de privacidad antes del primer dato. No se arregla después. Si no —y la mayoría de las integraciones no lo necesitan— arrancas hoy.

1
Primera hora

Crear la llave, en modo prueba

Tú

⚙️ Configuración → 🔌 Integraciones → ➕ Nueva integración. Modo prueba siempre la primera vez: guarda lo que manden para que lo veas, pero no mueve saldos reales.

Marca solo los permisos que necesiten. Empieza con menos de lo que te pidan: agregar uno después es rotar la llave, un minuto; quitar uno que ya usaron en producción rompe su integración un viernes.

La llave se muestra una sola vez. Mándala por un gestor de contraseñas o por teléfono, no por WhatsApp. Si dudas de cómo llegó, rótala: es gratis.

Sabes que quedó cuando la integración aparece en la lista con su pista de llave y dice «Todavía sin usar».

2
Primera hora, después de mandar el correo

La primera llamada, siempre ping

Quien programa

Con la llave en una variable de entorno, nunca en el código:

export GZ_KEY=gz_test_ehyjhn45u7d34uk7zq7qc4ugbaskjmt5

curl -X POST https://app.gzanalytics.com/api/v1/ping \
  -H "Authorization: Bearer $GZ_KEY" \
  -H "Content-Type: application/json"

Contesta contra qué programa quedó la llave, con qué permisos y en qué modo:

{
  "ok": true,
  "data": {
    "integracion": "Punto de venta",
    "programa": "Fan Pass · Estadio Metropolitano",
    "modo": "vivo",
    "permisos": [
      "fan:leer",
      "tx:escribir"
    ],
    "hora": "2026-08-21T05:15:22.282Z"
  }
}

Que esto sea lo primero no es ceremonia: contesta de un golpe las tres preguntas que hacen perder una tarde entera —¿la llave llegó bien?, ¿apunta al programa correcto?, ¿estoy en pruebas o en vivo?

Sabes que quedó cuando "modo": "prueba". Si dice vivo, para y avisa antes de mandar nada más.

3
Media tarde

Resolver al fan y registrar una venta

Quien programa

Dos llamadas. La primera dice quién trae el QR; la segunda registra la venta.

curl -X POST https://app.gzanalytics.com/api/v1/fan/resolve \
  -H "Authorization: Bearer $GZ_KEY" -H "Content-Type: application/json" \
  -d '{"fan":"GZM26-2T69D"}'

curl -X POST https://app.gzanalytics.com/api/v1/tx \
  -H "Authorization: Bearer $GZ_KEY" -H "Content-Type: application/json" \
  -d '{"id_externo":"TICKET-9001","fan":"GZM26-2T69D","importe":"1,500.50"}'

El campo fan acepta lo que sea que dé el escáner —Fan ID, token del QR, la URL completa, un código de cupón o el correo—, así que no hay que normalizar nada del lado de la caja.

200 OK
{
  "ok": true,
  "data": {
    "duplicado": false,
    "tx": 1,
    "puntos_otorgados": 1500,
    "saldo": 1543,
    "fan": {
      "id": "GZM26-2T69D",
      "correo": "fan@ejemplo.mx"
    }
  }
}

El único detalle que decide si esta integración es buena o mala: id_externo tiene que ser el folio del ticket, y tiene que ser el mismo en cada reintento. Un identificador nuevo por intento convierte cada reintento en una venta nueva, y ese es exactamente el bug que la idempotencia existe para evitar. Cómo funciona.

Sabes que quedó cuando "duplicado": false la primera vez y true la segunda, con puntos_otorgados: 0. Prueben mandarlo dos veces a propósito.

4
Media tarde, en paralelo

Mirar la bitácora con ellos

Tú

Mientras prueban, abre Integraciones → 📋 Bitácora. Cada llamada con su ruta, su código de respuesta, cuánto tardó y un resumen.

Esta pantalla es tu mejor herramienta en esta relación. Cuando tu proveedor diga «se los mandamos y no llegó», la respuesta está ahí en cinco segundos y sin pedirle registros a nadie. Se conserva 30 días.

Si ves códigos 4xx repetidos, míralos juntos: los de autorización son de la llave o los permisos —tuyos—, los de formato son de su código.

Sabes que quedó cuando la fila de la integración muestra llamadas en las últimas 24 h y cero con error.

5
Antes de cerrar el día

El manejador de errores, que casi nadie escribe

Quien programa

Los doce códigos caen en cuatro reacciones. No hace falta una rama por código:

switch (cuerpo.error.codigo) {
  // Esperan y vuelven, con el MISMO id_externo.
  case 'demasiadas_llamadas':
  case 'error_interno':
    return reintentarConBackoff();

  // La persona no está registrada: es acción de caja, no de código.
  case 'fan_no_encontrado':
    return pedirRegistroEnElPortal();

  // Nuestra llave. Alerta al equipo, no a la cajera.
  case 'no_autorizado':
  case 'sin_permiso':
    return alertarSoporte(cuerpo.error);

  // Bug propio: cuerpo mal armado.
  default:
    return registrarBug(cuerpo.error);
}

No pongan el mensaje de la API en la pantalla de la caja. Está escrito para quien depura. La cajera necesita «pide a la persona que se conecte al WiFi», no fan_no_encontrado. El catálogo completo.

Sabes que quedó cuando ramifican sobre error.codigo, no sobre error.mensaje. El texto puede cambiar; el código no.

6
Al día siguiente

Pasar a vivo

Tú

Crea una llave nueva en modo en vivo y entrégasela. Su código no cambia: solo el valor de la variable de entorno.

Deja la de prueba viva unos días — les sirve para seguir probando sin ensuciar saldos reales.

Sabes que quedó cuando la respuesta de ping dice "modo": "vivo" y una venta de prueba mueve el saldo de verdad. Compruébalo con tu propio Fan ID, no con el de un cliente.

Qué gana el venue con esto

Tres cosas que antes eran trabajo manual y ahora no existen:

AntesAhora
Pegar la lista de canjes a mano al día siguiente Entran solos, en el momento del canje
Los puntos solo suben por visitar Suben con el gasto real, que es lo que hace volver a la gente
«Se los mandamos y no llegó» La bitácora lo contesta en cinco segundos

Si el punto de venta también emite los códigos de tus promociones, puede depositarlos él mismo con la llave de inventario, y se acabó el archivo que alguien tiene que pegar.