Para criar uma loja virtual com IA, você pede a um agente de código que escreva o catálogo de produtos, o carrinho e o checkout passo a passo; uma configuração típica é Next.js, um banco de dados e um provedor de pagamento como o Stripe. O agente escreve código rápido, mas quem define as regras é você: os preços são calculados no servidor, os pagamentos são confirmados por webhook e dados de cartão nunca são guardados. Decidir antes se uma plataforma hospedada como a Shopify já resolve o que você precisa faz parte do trabalho.
Este guia começa por essa decisão e depois mostra, em ordem, como montar uma loja própria com um agente: modelo de dados, carrinho, checkout, webhooks, estoque, e-mails, páginas legais e deploy. Cada etapa tem prompts que você pode copiar. No final há uma lista dos erros que a IA mais comete em e-commerce e um checklist de segurança.
Primeira decisão: plataforma hospedada ou projeto próprio?
A resposta honesta muitas vezes é “plataforma hospedada”. Shopify, WooCommerce e plataformas parecidas cuidam de pagamentos, estoque, integrações de frete, impostos e atualizações de segurança para você.
| Plataforma hospedada | Projeto próprio (com um agente de código) | |
|---|---|---|
| Tempo até a primeira venda | Dias | Semanas |
| Pagamentos, segurança, atualizações | Responsabilidade da plataforma | Responsabilidade sua |
| Liberdade de design e fluxo | Até onde vão temas e apps | Ilimitada |
| Estrutura de custos | Mensalidade, às vezes taxa por transação | Hospedagem + taxas do provedor de pagamento + seu tempo |
| Portabilidade | Presa à plataforma | O código é seu |
Um projeto próprio faz sentido quando seu fluxo de vendas não é suportado (por exemplo, assinaturas mais um configurador sob encomenda), quando você está adicionando uma loja dentro de um app que já existe ou quando quer aprender e ter controle total. É esse o caminho deste guia. Se preferir começar com um site institucional simples, leia antes como criar um site com IA.
1. Stack e configuração
Para um projeto de vibe coding, sugiro uma stack que os agentes conhecem bem e que é muito documentada:
- Next.js (App Router): páginas, código de servidor e rotas de API em um só projeto.
- PostgreSQL: um serviço gerenciado (Supabase, Neon e afins) ou Docker localmente.
- Um ORM (Prisma ou Drizzle): schema e migrations ficam em arquivos, então você e o agente leem da mesma fonte.
- Um provedor de pagamento: o Stripe é a escolha comum; em alguns países, provedores locais são o padrão (na Turquia, por exemplo, iyzico ou PayTR). O que eles têm em comum é que o cartão é digitado no formulário do provedor e o resultado chega ao seu servidor por notificação.
- Um serviço de e-mail transacional: para confirmações de pedido e avisos de envio.
npx create-next-app@latest store
cd store
git status # create-next-app usually initialises git; if not: git init
claude
2. O primeiro prompt: plano antes do código
Dizer a um agente “cria uma loja para mim” te dá tudo de uma vez, com as partes críticas passadas por cima. Peça um plano primeiro:
We're building a small ecommerce site with Next.js (App Router), PostgreSQL and Prisma.
Payments will use Stripe Checkout (card data must never reach our server).
Don't write code yet. First produce a plan covering:
1. Data model: product, product variant (size/colour), order, order item, stock.
2. Pages: product list, product detail, cart, checkout return pages, a simple admin.
3. Payment flow: from cart to creating a checkout session to marking the order paid via webhook.
4. Which operations must happen on the server, and why.
Rules:
- Store prices as integers in the smallest currency unit (cents), never floats.
- Never trust a price, total or discount amount sent from the client.
- Secrets live only in .env; no secret ever reaches client code.
Write the plan and wait for my approval.
Leia o plano, corrija o que não te agradar e depois implemente por partes: modelo de dados, depois catálogo, depois carrinho, pagamentos por último. Faça um commit depois de cada parte.
3. O banco de produtos
Algumas coisas que eu observo no modelo de dados:
- Dinheiro é inteiro. R$ 14,90 é guardado como
1490. O Stripe e a maioria dos provedores já esperam valores na menor unidade da moeda. - Os itens do pedido copiam o preço. O pedido guarda o nome e o preço do produto no momento da compra, para que uma mudança de preço amanhã não reescreva pedidos antigos.
- O estoque fica na variante. “Camiseta azul, tamanho M” tem sua própria linha de estoque.
- O status do pedido é uma lista explícita:
pending,paid,shipped,cancelled,refundede assim por diante.
Quando o agente escrever uma migration, leia o arquivo. Se ela apagar uma tabela ou uma coluna que já tem dados, pare e pergunte.
4. O carrinho
O carrinho, no navegador (ou no banco, para usuários logados), deve guardar só IDs de produto/variante e quantidades. Preços e totais aparecem no carrinho, mas sempre vêm do servidor.
Implement the cart. Store only a list of {variantId, quantity} in localStorage.
The cart page fetches current prices and the total from the server.
Out-of-stock or deleted products show in the cart with a warning.
Limit quantity to 1–10 and enforce that on the server too.
5. Checkout: os preços são sempre calculados no servidor
Regra número um do e-commerce: nunca confie em um preço vindo do cliente. Todo valor no navegador pode ser alterado; qualquer pessoa pode abrir o DevTools e mudar o total para R$ 1. O fluxo certo:
- O cliente envia ao servidor só a lista de
variantIdequantity. - O servidor lê o preço e o estoque de cada item no banco e calcula o total por conta própria.
- O servidor cria um pedido com status
pending. - O servidor cria uma sessão de pagamento com o provedor (uma Stripe Checkout Session ou o formulário de pagamento do provedor local) e anexa o ID do pedido a ela.
- O cliente é redirecionado para a página ou iframe do provedor e digita o cartão ali.
Uma ideia resumida do código de servidor:
// app/api/checkout/route.ts (sketch)
const items = await db.variant.findMany({ where: { id: { in: cart.map(c => c.variantId) } } })
const lineItems = cart.map(c => {
const v = items.find(i => i.id === c.variantId)
if (!v || v.stock < c.quantity) throw new Error('Out of stock')
return { price: v.priceCents, quantity: c.quantity } // price from the DB, not the client
})
Cupons de desconto seguem a mesma regra: o código vem do cliente, mas se ele é válido e quanto ele desconta é decidido no servidor.
6. Webhooks: pago ou não?
Um cliente chegando à sua página de “pagamento aprovado” não prova que o pagamento passou; essa página pode ser aberta à mão, e o cliente pode ter fechado a aba. A fonte da verdade é a notificação que o provedor envia ao seu servidor (um webhook no Stripe, muitas vezes chamado de callback em outros provedores).
Deixe isso explícito para o agente no endpoint de webhook:
Write the Stripe webhook endpoint (/api/webhooks/stripe):
- Verify the signature with STRIPE_WEBHOOK_SECRET; reject unsigned or invalid requests.
- Use the raw request body for signature verification.
- On checkout.session.completed, read the order ID from metadata, and inside one
database transaction mark the order "paid" and decrement stock.
- Make it idempotent: if the same event arrives twice, the second time changes nothing.
- Compare the amount paid with the order total; if they differ, flag the order and log it.
Para testar localmente, a Stripe CLI consegue encaminhar os eventos para a sua máquina:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
No modo de teste do Stripe, cartões de teste como 4242 4242 4242 4242 permitem rodar o fluxo inteiro sem dinheiro de verdade. Outros provedores também têm sandbox; peça ao agente para ler a documentação deles sobre como verificar a assinatura ou o hash da notificação.
7. Estoque
O estoque é onde duas pessoas podem comprar o último item no mesmo instante. Os agentes costumam escrever “lê e depois grava”, o que deixa uma condição de corrida no meio. Em vez disso, faça a verificação e a baixa em uma única consulta atômica:
UPDATE variants SET stock = stock - 2
WHERE id = 'var_123' AND stock >= 2;
-- if zero rows were affected, there wasn't enough stock
Baixar o estoque quando o pagamento é confirmado (no webhook) é a opção simples; para itens muito limitados, você também pode segurar uma reserva curta quando a sessão de checkout abre. Diga ao agente explicitamente qual das duas você quer.
8. E-mails
Você precisa de pelo menos dois: uma confirmação de pedido e um aviso de envio. Envie a confirmação a partir do webhook, não da página de sucesso, para que ela só saia para pedidos realmente pagos. A chave de API do serviço de e-mail fica no servidor. Se você pular os registros SPF/DKIM que o provedor de e-mail pede no seu domínio de envio, seus e-mails podem cair no spam.
9. Páginas legais
Não é código, mas faz parte da loja. O que é obrigatório depende de onde você e seus clientes estão, mas a maioria das lojas precisa de:
- Uma política de privacidade (cobrindo o que você coleta e por quê, além da GDPR ou equivalentes locais quando se aplicam)
- Um aviso de cookies onde for exigido
- Termos de venda
- Uma política de reembolso e devolução, incluindo qualquer prazo legal de arrependimento
- Dados do vendedor: razão social, endereço e informações de contato
Se você vende na Turquia, conte com um aviso de privacidade KVKK, um contrato de venda a distância e um formulário de informações prévias que o cliente aprova antes de fazer o pedido. Você pode pedir ao agente que adicione as caixas de consentimento no checkout e guarde o consentimento junto com o pedido. A IA pode rascunhar esses textos, mas peça a um advogado ou contador que os revise antes de publicar, e pergunte a eles sobre emissão de notas e obrigações fiscais.
10. Deploy
Colocar o app Next.js na Vercel e o banco em um serviço PostgreSQL gerenciado é o caminho mais curto. Antes do lançamento:
- Cadastre as variáveis de ambiente (URL do banco, chaves de pagamento e de e-mail, segredo do webhook) no painel da sua hospedagem.
- Registre a URL do webhook de produção no painel do provedor de pagamento; não misture chaves de teste e de produção.
- Rode as migrations em produção de forma deliberada, e faça um backup antes.
- Faça um pequeno pedido real em produção, reembolse e confira o fluxo inteiro (e-mail, estoque, status do pedido) com seus próprios olhos.
O que a IA erra em e-commerce
- Calcular o total no cliente e enviá-lo ao servidor. O mais perigoso. Procure no código um
priceoutotalvindo do cliente e remova. - Marcar o pedido como pago na página de sucesso. Sem webhook, o status do pedido não deveria mudar.
- Pular a verificação da assinatura do webhook, ou fazer o parse do corpo como JSON antes de verificar e depois desativar a verificação porque “não funciona”.
- Float para dinheiro. O problema do
0.1 + 0.2vai parar nas notas. - Sem idempotência. O mesmo webhook chega duas vezes, o estoque cai duas vezes, saem dois e-mails.
- Um admin desprotegido. Ele cria uma página
/admin, mas esquece as verificações de autorização nas rotas de API. Garanta que toda API de admin confira o papel do usuário no servidor. - Ir para produção com chaves de teste, ou o contrário, usar chaves de produção durante o desenvolvimento.
Segurança
- Nunca guarde, logue ou colete dados de cartão com um formulário seu. Use a página ou o formulário de pagamento hospedado pelo provedor; isso mantém o seu escopo de PCI DSS o menor possível.
- Segredos no
.env, com o.envno.gitignore. Nunca coloque uma chave secreta (comosk_...) no código do cliente nem em variáveis de ambiente públicas (no Next.js, as com prefixoNEXT_PUBLIC_). - Nunca cole chaves de API no chat. Diga ao agente o nome da variável, não o valor.
- Leia o que o agente executa. Em um terminal conectado a um banco de produção, não aprove automaticamente migrations,
DROPs ouUPDATEs em massa. - Leia cada diff, principalmente o código de pagamento e de autenticação. Um segundo par de olhos é essencial aqui; code review com IA explica como montar isso.
- Colete o mínimo possível de dados pessoais, e mantenha o que coletar com acesso restrito.
Fazendo isso com o AgentVera
Manter vários agentes separados ajuda em um projeto de loja, e eu faço isso com o AgentVera:
- Backend e interface em worktrees separadas. Um agente Claude Code trabalha em pagamentos, webhooks e modelo de dados enquanto um agente Codex monta as páginas de produto e a interface do carrinho. Cada um fica na sua git worktree, todos em um só workspace.
- Gerenciador de banco de dados. Veja as tabelas, pedidos e estoque que o agente criou no gerenciador de banco de dados sem abrir outra ferramenta; ele suporta PostgreSQL, MySQL e SQLite.
- DB Guard. Ele analisa as migrations que o agente escreveu ao fim de um turno; o DB Guard mostra logo de cara riscos como um
DROPou umUPDATEsemWHERE. - Code review e previews. Quando um turno termina, o code review põe um segundo modelo para olhar; os ambientes de preview rodam o servidor de desenvolvimento de cada worktree no seu próprio endereço. Mesmo assim, você lê o diff de pagamento antes do merge.
Nada disso acerta as coisas por você; só facilita ver o que mudou.
Checklist rápido
- Plataforma hospedada ou projeto próprio decidido de propósito
- Preços são inteiros na menor unidade; itens do pedido copiam o preço
- O carrinho guarda só IDs e quantidades; o total é calculado no servidor
- Pedidos viram “pagos” só por um webhook com assinatura verificada; o webhook é idempotente
- O estoque é baixado com uma consulta atômica
- O e-mail de confirmação sai pelo webhook; SPF/DKIM configurados
- Privacidade, termos, política de reembolso e dados do vendedor no ar e revisados
- Nenhum dado de cartão em lugar nenhum; segredos só no servidor
- Um pedido real feito e reembolsado em produção
Resumindo
Dá para criar uma loja virtual com IA, e um agente vai escrever a maior parte dela rápido. Mas o que torna uma loja confiável não é algo que o agente faz sozinho: preços calculados no servidor, pagamentos confirmados por webhook, estoque baixado de forma atômica, nenhum dado de cartão guardado e as páginas legais certas. Coloque essas regras no seu primeiro prompt, teste cada etapa no modo de teste e sempre leia o código de pagamento antes de fazer o merge.