Skip to main content
Este guia cobre o lado Next.js da Storefront headless. O contrato completo da API (rotas, formatos, erros) está documentado lá — aqui o foco é como estruturar o projeto.

Modelo mental: três fronteiras que não podem se misturar

A chave publishable pode ir para o browser, mas mesmo assim é comum fazer tudo passar pelo servidor Next.js: dá um lugar único para logar request_id e tratar erro. A exceção é o rate limit por IP do checkout (10/min) — se a loja tiver volume alto e concentrado, prefira chamar /checkout/sessions direto do browser com a chave publishable, para não concentrar todas as requisições no IP do seu servidor.

Chamando do browser: o query param key não é opcional

Se alguma chamada sair do navegador (fetch em Client Component, ou uma SPA), inclua a chave publishable como query param além do header:
Isso é necessário porque Authorization não é um header safelisted do CORS: toda requisição com esse header dispara um preflight OPTIONS, e o preflight não carrega Authorization. Sem outro sinal, a API não consegue identificar a loja para checar a allowlist de origens, e responde 403 sem Access-Control-Allow-Origin — o que no console do navegador parece um erro de CORS por origem não cadastrada, mesmo quando a origem está correta. Chamadas server-to-server não têm header Origin, não disparam preflight e não precisam do query param.

Variáveis de ambiente

.env.local
Nenhuma chave usa o prefixo NEXT_PUBLIC_. No Next.js, esse prefixo decide se a variável é embutida no bundle do cliente — prefixar a chave secreta é exatamente como ela vaza. Se você realmente precisar chamar o catálogo direto do browser, crie uma variável separada NEXT_PUBLIC_HUSKPAY_PUBLISHABLE_KEY e use ela nesse caminho. Confirme que .env*.local está no .gitignore.

Um cliente de API mínimo

src/lib/huskpay/client.ts — o import 'server-only' no topo faz o build quebrar se algum Client Component importar este arquivo por engano. É a garantia real contra vazamento de chave; organização de pastas sozinha não é suficiente.
src/lib/huskpay/client.ts

Padrões recomendados

Catálogo em Server Component

Busque produtos com huskpay('/products', { next: { revalidate: 60 } }) diretamente no componente de servidor — sem expor a chave ao cliente.

Checkout via Server Action

Receba o carrinho do cliente, gere um Idempotency-Key (UUID) por tentativa de compra e chame /checkout/sessions no servidor antes de redirecionar.

Pedidos com chave secreta

Só use key: 'secret' em Server Actions ou Route Handlers — nunca em código que pode acabar em um Client Component.

Entrega no webhook

Implemente a entrega do produto em uma Route Handler dedicada para o webhook, validando a assinatura antes de processar. Veja Webhooks.
Reaproveite o mesmo Idempotency-Key apenas entre retries da mesma tentativa de compra do usuário. Um UUID novo por tentativa evita sessões de checkout duplicadas quando a rede falha e o cliente clica em “comprar” de novo.