Giraloja

API da loja

Para o programador do lojista montar o próprio site com o estoque em tempo real. Mudanças no sistema aparecem na hora, sem precisar importar XML.

Começo rápido

  1. O lojista cria uma chave em Configurações › Site e API.
  2. Use a pública (pk_…) no navegador, restrita ao domínio do site. Use a secreta (sk_…) só no servidor.
  3. Chame a API com o cabeçalho Authorization: Bearer SUA_CHAVE.
curl https://revenda.promozap.tech/api/v1/carros?ordem=menor_preco&preco_max=80000 \
  -H "Authorization: Bearer pk_SUA_CHAVE"
<script src="https://revenda.promozap.tech/sdk/loja.js"></script>
<script>
  const loja = new ApiLoja({ chave: "pk_SUA_CHAVE", base: "https://revenda.promozap.tech" });
  const { carros } = await loja.carros({ ordem: "menor_preco" });
  await loja.enviarContato({ nome: "Ana", telefone: "41999990000", carro_id: carros[0].id, assunto: "financiamento" });
</script>

Rotas

Base: https://revenda.promozap.tech/api/v1 · Especificação completa: openapi.json

GET/lojaDados da loja: nome, contatos, endereço, horário e cor.
GET/carrosCarros à venda, com filtros (marca, modelo, busca, preco_min, preco_max, ano_min, ano_max, km_max, cambio, combustivel, carroceria), ordem e paginação.
GET/carros/{id}Um carro com todas as fotos e opcionais.
GET/marcasMarcas e modelos disponíveis, com contagem, para montar filtros.
POST/contatosContato do cliente: vira negociação no sistema e é distribuído a um vendedor.

Exemplo de resposta

{
  "carros": [{
    "id": "8f0c…", "marca": "Chevrolet", "modelo": "Onix", "versao": "LT 1.0 Turbo",
    "ano_fabricacao": 2021, "ano_modelo": 2022, "km": 38500, "cambio": "Automático",
    "preco": 74900, "preco_centavos": 7490000, "situacao": "a_venda",
    "fotos": ["https://revenda.promozap.tech/arquivos/p/…"], "url": "https://revenda.promozap.tech/loja/sua-loja/carro/8f0c…"
  }],
  "pagina": 1, "por_pagina": 24, "total": 37, "paginas": 2
}

Erros

Sempre no formato { "erro": { "codigo": "...", "mensagem": "..." } }: 401 chave inválida, 403 chave pública numa operação secreta, 404 não encontrado, 422 dados inválidos, 429 limite (240/min pública, 600/min secreta, 10 contatos/min por IP).

Webhooks

O sistema avisa o seu servidor na hora em que algo muda, e você não precisa ficar consultando a API. Cadastre o endereço em Configurações › Site e API.

  • carro.publicadoCarro colocado à venda
  • carro.atualizadoPreço, fotos ou dados do carro mudaram
  • carro.reservadoCarro reservado
  • carro.vendidoCarro vendido
  • carro.removidoCarro saiu do site (devolvido, escondido ou transferido)
  • contato.recebidoNovo contato recebido

Responda 2xx em até 10 segundos. Se falhar, reenviamos em 1, 5, 30, 120 e 720 minutos. Confira a assinatura:

import { createHmac, timingSafeEqual } from "node:crypto";

function assinaturaValida(corpoBruto, cabecalho, segredo) {
  const { t, v1 } = Object.fromEntries(cabecalho.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // 5 minutos
  const esperado = createHmac("sha256", segredo).update(`${t}.${corpoBruto}`).digest("hex");
  return timingSafeEqual(Buffer.from(esperado), Buffer.from(v1));
}
// req.headers["x-assinatura"]  ·  segredo: whsec_… (aparece ao criar o webhook)