Documentación

Integración con POS

Conecta tu punto de venta con Xtarly Rewards para acreditar puntos o sellos automáticamente cuando un cliente realiza una compra.

La integración con POS permite que tu sistema de punto de venta registre transacciones directamente vía una API REST. Cada vez que un cliente paga, tu POS llama al endpoint de Xtarly y el cliente recibe sus puntos o sellos al instante — sin necesidad de escanear manualmente.

¿No quieres programar? Hay 15 conectores automáticos — Loyverse, Poster, Square, Clover, Toast, Bsale, Lightspeed, Odoo, Shopify, Alegra, CleanCloud, Epos Now, Mercado Pago, Clip y SumUp — que conectas en minutos desde el panel de integraciones POS, sin código.

La API REST para POS es una función del plan Premium: integrar tu propio sistema con Xtarly por código. Es distinta de conectar un POS del catálogo, que está disponible desde el plan Shared y no requiere programar — ver panel de integraciones POS. En caja siempre puedes registrar las ventas desde la app cashier, en cualquier plan.

Obtener tu API key

  1. Abre el dashboard de tu organización y ve a Configuración → General.
  2. Desplázate hasta la sección Integración con POS.
  3. Haz clic en Generar API key. La clave se muestra una sola vez — cópiala de inmediato y guárdala de forma segura (por ejemplo, en las variables de entorno de tu POS).
  4. Si la clave se ve comprometida, haz clic en Rotar para invalidar la clave anterior y generar una nueva. Si ya tienes una clave viva, puedes rotarla aunque cambies de plan: nunca te quedas sin forma de reemplazar una credencial filtrada.

La API key solo se muestra una vez al generarse. Si la pierdes, deberás rotar la clave y actualizar todas las integraciones que la usaban.

URL base

Todos los endpoints POS se sirven desde tu dominio de Xtarly:

https://www.xtarly.com/api/integrations/pos

Autenticación

Incluye tu API key en cada solicitud mediante el header X-API-Key:

X-API-Key: xtarly_pos_<tu_clave>

Las solicitudes sin una clave válida devuelven 401 Unauthorized.


Endpoints

Registrar una transacción

POST /api/integrations/pos/transaction

Llama a este endpoint cuando un cliente completa una compra. Xtarly calcula los puntos o sellos ganados según tu programa de recompensas activo y los acredita al cliente.

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
amountnumber✓Total de la compra en la unidad monetaria más pequeña (por ejemplo, centavos para MXN/USD).
customerIdstring✓ (o customerEmail)ID de cliente en Xtarly.
customerEmailstring✓ (o customerId)Correo electrónico registrado del cliente.
metadataobject—Objeto libre opcional adjunto a la transacción (por ejemplo, { "ticket": "1234" }).

Proporciona customerId o customerEmail — al menos uno es obligatorio.

Ejemplo de solicitud

curl -X POST https://www.xtarly.com/api/integrations/pos/transaction \
  -H "Content-Type: application/json" \
  -H "X-API-Key: xtarly_pos_<tu_clave>" \
  -d '{
    "amount": 35000,
    "customerEmail": "cliente@ejemplo.com",
    "metadata": { "ticket": "T-00412" }
  }'

Respuesta exitosa 200 OK

{
  "success": true,
  "data": {
    "transactionId": "txn_abc123",
    "earnedPoints": 35,
    "earnedStamps": 0,
    "customerPoints": 210,
    "customerStamps": 0
  }
}
CampoDescripción
transactionIdID único de la transacción registrada.
earnedPointsPuntos acreditados en esta transacción.
earnedStampsSellos acreditados en esta transacción (programas de sellos).
customerPointsTotal de puntos del cliente después de esta transacción.
customerStampsTotal de sellos del cliente después de esta transacción.

Consultar un cliente

GET /api/integrations/pos/customer/:id

Devuelve el saldo y nivel actual de un cliente. Útil para mostrar el estado de fidelización en el punto de venta antes o después de una transacción.

Ejemplo de solicitud

curl https://www.xtarly.com/api/integrations/pos/customer/cus_abc123 \
  -H "X-API-Key: xtarly_pos_<tu_clave>"

Respuesta exitosa 200 OK

{
  "success": true,
  "data": {
    "id": "cus_abc123",
    "name": "María García",
    "email": "cliente@ejemplo.com",
    "points": 210,
    "stamps": 0,
    "tier": null
  }
}

Endpoints para el punto de venta

La misma API key da acceso a los endpoints que usa un punto de venta conectado: identificar al cliente en la caja, ver qué puede aplicar hoy y canjear cupones o premios en el momento del cobro.

EndpointPara qué sirve
GET /pingComprueba que la API key es válida y devuelve el nombre del programa.
GET /programTipo de programa activo (POINTS, STAMPS o TIERS) y cómo se llama la unidad ("puntos" o "sellos").
POST /accrueAcredita una venta del POS. Idempotente por saleId.
GET /customer/by-phone?phone=Busca al cliente por teléfono.
GET /customer/by-qr?payload=Busca al cliente con el QR de su tarjeta escaneado en la caja.
GET /customer/by-email?email=Busca al cliente por correo (sin distinguir mayúsculas).
GET /customer/benefits?customerId=Todo lo que ese cliente puede aplicar hoy: cupones disponibles y premios con veredicto.
GET /coupon/by-qr?payload=Resuelve un cupón escaneado y dice si se puede canjear.
GET /coupon/by-code?code=Lo mismo, con el código escrito a mano.
POST /coupon/redeemAplica un cupón a la venta. Idempotente por saleId.
POST /reward/redeemCanjea un premio y descuenta los puntos o sellos. Idempotente por saleId.

Los cuatro endpoints de búsqueda de cliente devuelven la misma forma: id, name, email, phone, points, stamps y tier (el nombre del nivel, o null).

Acreditar una venta desde el POS

POST /api/integrations/pos/accrue
CampoTipoRequeridoDescripción
saleIdstring✓Id de la venta en tu POS. Es la clave de idempotencia: la misma venta nunca acredita dos veces.
customerPhonestring✓Teléfono del cliente.
amountCentavosnumber✓Total de la venta en centavos (entero).
occurredAtstring✓Fecha y hora de la venta.
branchNamestring—Nombre de la sucursal donde se cobró.
itemsarray—Líneas del ticket; se guardan tal cual en la transacción.

La respuesta trae status: ACCRUED cuando se acreditó (con pointsAccrued y stampsAccrued), SKIPPED si esa venta ya se había procesado o no hay programa activo, y CUSTOMER_NOT_FOUND si ningún cliente tiene ese teléfono.

branchName se resuelve contra el nombre de tus sucursales activas en Xtarly (sin distinguir mayúsculas). Con eso el sello o los puntos quedan registrados en la sucursal correcta y no aparecen «sin sucursal» en la actividad. Si no coincide con exactamente una sucursal, la transacción se guarda sin sucursal.

Qué puede aplicar el cliente hoy

GET /api/integrations/pos/customer/benefits?customerId=cus_abc123

Devuelve, en una sola llamada, el tipo de programa, el cliente, sus cupones disponibles y todos los premios con el veredicto ya calculado: attainable dice si lo puede canjear ahora, y si no, blockedReason y blockedMessage explican por qué (le faltan puntos, no alcanza el nivel, ya lo usó este ciclo…).

Cada premio incluye además un objeto benefit con la semántica ejecutable del descuento — el tipo, el valor y los productos del menú a los que aplica — para que el POS lo aplique solo en lugar de dejarle la cuenta al cajero.

Canjear un cupón o un premio

POST /api/integrations/pos/coupon/redeem
POST /api/integrations/pos/reward/redeem

Para un cupón manda couponId, saleId, amountCentavos y, opcionalmente, customerId y branchName. Un cupón marcado como de mostrador se puede canjear sin customerId.

Para un premio manda rewardId, customerId, saleId y, opcionalmente, amountCentavos y branchName.

Ambos responden status: "REDEEMED" con el redemptionId, y DUPLICATE si esa misma venta ya había canjeado. El canje de premio devuelve además pointsSpent, stampsSpent y el saldo del cliente después del canje.

Todas las condiciones las valida el servidor: monto mínimo, nivel requerido, vigencia, tope de canjes por cliente y saldo. El POS no decide si un cupón procede — pregunta y obedece la respuesta.


Cálculo de puntos

Los puntos o sellos acreditados por transacción dependen del tipo de programa activo:

Tipo de programaCálculo
Puntosfloor(amount / currencyUnit × pointsPerCurrency)
NivelesIgual que Puntos, multiplicado por el multiplicador del nivel del cliente.
Sellos1 sello por transacción, sin importar el monto.

Configuras currencyUnit y pointsPerCurrency en Configuración → Programa.

Códigos de error

CódigoHTTPDescripción
UNAUTHORIZED401API key ausente o inválida.
VALIDATION_ERROR400Falta amount o el identificador del cliente.
NOT_FOUND404No se encontró ningún cliente con el ID o correo dado en tu organización.
BAD_REQUEST400Tu organización no tiene un programa de recompensas activo.