Loy API · piloto com parceiros Documentação para quem desenvolve a integração.

Webhooks

Com webhooks, o Loy avisa o seu sistema quando algo acontece — um cliente novo, uma visita, uma recompensa conquistada ou resgatada — sem você precisar ficar consultando a API.

Os webhooks entram em funcionamento em breve no piloto. Esta página já descreve como vão funcionar.

1. Cadastre um endereço

curl -X POST https://loynow.com/api/v1/webhook_endpoints \
  -H "Authorization: Bearer $LOY_API_KEY" -H "Content-Type: application/json" \
  -d '{"webhook_endpoint": {"url": "https://hooks.seusistema.com/loy",
       "event_types": ["visit.recorded", "reward.earned"]}}'

A resposta traz o secret (whsec_…) uma única vez — guarde-o para verificar a assinatura. O endereço precisa ser https:// e público; endereços internos são recusados. Use POST /webhook_endpoints/{id}/test para receber um evento ping na hora.

2. Eventos

EventoQuandodata
customer.createdCliente cadastrado (app ou API)cliente
visit.recordedVisita paga registrada, ou marcada como paga depoisvisita
reward.earnedRecompensa conquistada (programa, aniversário, sazonal, reativação ou indicação)recompensa
reward.redeemedRecompensa resgatada (app ou API)recompensa

O corpo de cada aviso:

{
  "id": "evt_8Kd2Qz…",
  "type": "reward.earned",
  "created_at": "2026-10-10T14:03:11-03:00",
  "data": {
    "id": "rwd_2Pq8Xs4K",
    "customer_id": "cus_4fRk9P2xQ",
    "code": "LOY-8KD2QZ",
    "status": "available",
    "…": "…"
  }
}

data tem o mesmo formato que a API devolve para aquele recurso.

3. Verifique a assinatura

Cada aviso traz Loy-Signature: t=<unix>,v1=<hex>, onde v1 é o HMAC-SHA256 do texto "#{t}.#{corpo bruto}" com o seu secret. Recuse avisos com assinatura diferente ou com t mais antigo que 5 minutos.

# Ruby
timestamp, signature = header.scan(/(?:t|v1)=([^,]+)/).flatten
expected = OpenSSL::HMAC.hexdigest("SHA256", secret, "#{timestamp}.#{raw_body}")
valid = Rack::Utils.secure_compare(expected, signature) && (Time.now.to_i - timestamp.to_i).abs < 300
// Node.js
const [t, v1] = header.split(",").map((part) => part.split("=")[1]);
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
  && Math.abs(Date.now() / 1000 - Number(t)) < 300;

4. Responda rápido e trate repetição

  • Responda com qualquer 2xx em até 5 segundos; processe depois, se precisar.
  • Sem 2xx, o Loy tenta de novo em 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h.
  • O mesmo evento pode chegar mais de uma vez: use Loy-Event-Id para ignorar repetidos.
  • Depois de 20 falhas seguidas ao longo de mais de um dia, o endereço é pausado e a empresa é avisada. Corrija e reative com POST /webhook_endpoints/{id}/enable.

O acesso é liberado pela equipe do Loy. Pedir acesso.