Para integrar pagamentos pelo Claude Code, você aponta heropay.tech/llms.txt e a documentação em docs.heropay.tech no CLAUDE.md do projeto e manda um prompt em português com o contrato da API. O Claude Code escreve no seu próprio repositório a rota que chama POST /payment_links, a tabela de pedidos e o webhook com validação HMAC, na stack que você já usa. Você testa com curl no sandbox, cadastra o webhook, troca a chave e vá pro ar. Pix a R$ 0, boleto a R$ 0 e cartão em até 12x.
Criar conta sandbox Ler a documentação
O essencial em 60 segundos
- O Claude Code integra o HeroPay pela API REST pública. Ele aprende o contrato por dois lugares: o llms.txt do site (
heropay.tech/llms.txt), que resume o HeroPay para IAs e aponta para a documentação, e a própria documentação, com a referência de cada endpoint. - O código que vai para produção mora no seu repo, na sua stack (Next.js, Express, Rails, Django, Laravel ou outra). O que cobra o seu cliente é a rota que o Claude Code escreve e você revisa.
- O fluxo tem três peças: uma rota de servidor que chama
POST /payment_linkse devolve a URL do checkout, uma tabela de pedidos e um webhook que valida o headerX-HeroPay-Signature(HMAC SHA-256 do corpo) antes de liberar acesso. - Durante o desenvolvimento, o próprio Claude Code roda os
curlde teste no terminal, com a chave lida do ambiente e com a sua aprovação a cada comando. - O HeroPay cobra R$ 0 por Pix e R$ 0 por boleto; no cartão, 3,49% por transação aprovada, em até 12x. Sem mensalidade, ativação ou mínimo (preços).
- Uma seção HeroPay no
CLAUDE.mddo projeto faz o Claude Code lembrar das regras (centavos, headerAccept, webhook como fonte de verdade) em toda sessão, sem você repetir. - O que o HeroPay não tem hoje: MCP server publicado (está em desenvolvimento), plugin no marketplace do Claude Code, login por OAuth e chave restrita por escopo. A integração funciona sem nada disso, e a página explica como proteger a chave.
Como integrar pagamentos pelo Claude Code com o HeroPay?
São sete passos. Os quatro primeiros deixam o código escrito; o resto depende de quanto você quer testar antes de ir ao ar.
Passo 1: crie a conta sandbox e guarde a chave no ambiente
Crie a conta em app.heropay.tech e copie o token de API nas configurações da conta, seção API. O token é um Bearer JWT. No sandbox a URL base é https://api.beta.heropay.tech; em produção, https://api.heropay.tech.
Coloque a chave no .env do projeto (ou no gerenciador de segredos que você já usa) e confirme que ele está no .gitignore:
# .env (nunca versionado)
HEROPAY_API_URL=https://api.beta.heropay.tech
HEROPAY_API_KEY=seu-jwt-do-sandbox
HEROPAY_WEBHOOK_SECRET=segredo-de-assinatura-do-webhookNão cole o token no chat do Claude Code. Ele fica no ambiente, e o Claude trabalha com o nome da variável, nunca com o valor.
Passo 2: confirme a chave com um curl
Antes de pedir qualquer código, prove que a chave e os headers estão certos. Você pode rodar o comando você mesmo ou pedir ao Claude Code que rode (ele pede aprovação antes de executar comandos no terminal):
set -a; source .env; set +a
curl -s -X POST "$HEROPAY_API_URL/payment_links" \
-H "Authorization: Bearer $HEROPAY_API_KEY" \
-H "Accept: application/vnd.herospark.com; version=1" \
-H "Content-Type: application/json" \
-d '{"payment_link":{"name":"Teste Claude Code","description":"Link de teste","price_cents":500,"absorbs_fees":false,"max_installments":1,"payment_methods":["pix","credit_card","bank_slip"],"src":"teste-local"}}'A resposta 201 traz data.offer.url, o checkout pronto. 401 é chave ausente ou sem Bearer; 422 costuma ser valor abaixo de 500 centavos. Essa resposta real é o melhor insumo para o Claude Code: ela mostra os nomes verdadeiros dos campos, sem adivinhação.
Um detalhe: o comando lê a chave pela variável $HEROPAY_API_KEY, que o shell expande. O valor não aparece no comando que o Claude escreve nem precisa entrar na conversa.
Passo 3: ensine o HeroPay ao projeto pelo CLAUDE.md
O Claude Code lê o CLAUDE.md da raiz do projeto no começo de cada sessão. Se ainda não tem um, rode /init e o Claude cria. Depois acrescente o bloco abaixo (explicado em detalhe na seção Por que colocar o HeroPay no CLAUDE.md):
## Pagamentos (HeroPay)
- Referência: https://heropay.tech/llms.txt (visão geral) e https://docs.heropay.tech (referência da API). Não invente endpoint nem campo que não esteja na documentação.
- Base: HEROPAY_API_URL (sandbox https://api.beta.heropay.tech, produção https://api.heropay.tech).
- Toda chamada leva: Authorization: Bearer $HEROPAY_API_KEY e Accept: application/vnd.herospark.com; version=1.
- A chave só é lida no servidor, via variável de ambiente. Nunca em código de cliente, em log ou em commit.
- Dinheiro é inteiro em centavos (price_cents: 19700 = R$ 197,00). Mínimo de um link: 500. Parcelas de 1 a 12, mínimo R$ 1,99 por parcela.
- O preço sai do servidor. O cliente manda só o identificador do produto.
- Pagamento se confirma pelo webhook spark_payment_confirmed, nunca pelo redirect do checkout.
- Webhook: validar X-HeroPay-Signature (HMAC SHA-256 do corpo bruto com HEROPAY_WEBHOOK_SECRET) antes de parsear o JSON; comparar em tempo constante; deduplicar por pagamento + gatilho.
- O campo src do link volta em cart.src em todo webhook: use o id do pedido.
- Testes contra a API só com a chave de sandbox. Pergunte antes de cadastrar webhook ou de chamar qualquer endpoint que não seja de leitura.Passo 4: mande o prompt pronto
Abra o Claude Code na raiz do projeto (claude) e, se quiser revisar antes de qualquer arquivo ser alterado, entre no modo de plano com Shift+Tab. Copie o prompt inteiro e troque só o que está entre colchetes.
Quero aceitar pagamentos neste projeto usando a API HeroPay. Siga as regras da seção "Pagamentos (HeroPay)" do CLAUDE.md. Use https://heropay.tech/llms.txt como visão geral e https://docs.heropay.tech como referência da API. Não invente endpoints nem campos.
CONTEXTO DO PRODUTO
- O que vendo: [ex.: "Plano Pro anual do meu SaaS de agendamento"]
- Identificador: [ex.: plano-pro-anual]
- Preço: [ex.: R$ 197,00]
- Parcelamento no cartão: até [12]x
- Métodos: Pix, cartão e boleto
0. ANTES DE ESCREVER CÓDIGO
- Leia o projeto e me diga a stack, o ORM, onde ficam as rotas de servidor e como os testes rodam. Siga os padrões que já existem aqui; não adicione framework novo.
- Rode (com a minha aprovação) um curl de POST {HEROPAY_API_URL}/payment_links no sandbox criando um link de teste de R$ 5,00 (price_cents 500), lendo a chave de $HEROPAY_API_KEY, e me mostre a resposta. Use essa resposta real para confirmar os nomes dos campos (data.id, data.offer.url).
- Me mostre o plano de arquivos antes de alterar qualquer coisa.
1. CONFIGURAÇÃO
- Crie um módulo de configuração que lê HEROPAY_API_URL, HEROPAY_API_KEY e HEROPAY_WEBHOOK_SECRET do ambiente e falha na inicialização se faltar alguma.
- Adicione as três ao .env.example com valores de exemplo, nunca reais. Confirme que .env está no .gitignore.
- A chave nunca aparece em código de cliente, em variável com prefixo público (NEXT_PUBLIC_, VITE_, EXPO_PUBLIC_), em log ou em mensagem de erro.
2. BANCO DE DADOS (migration no ORM do projeto)
- Tabela products: key (único), name, description, price_cents (inteiro). Cadastre o produto acima numa seed.
- Tabela orders: id, user_id, product_key, amount_cents (inteiro), status (pending, paid, refunded, canceled; padrão pending), checkout_url, heropay_payment_link_id, paid_at (nulo), created_at.
- Tabela heropay_events: payment_id, trigger, received_at, com índice único em (payment_id, trigger). É o registro de idempotência.
3. ROTA POST /api/checkout (servidor)
- Exige usuário autenticado. Recebe só product_key. Recuse qualquer preço vindo do cliente.
- Busca o preço em products, cria o pedido pending e chama POST {HEROPAY_API_URL}/payment_links com os headers:
Authorization: Bearer {HEROPAY_API_KEY}
Accept: application/vnd.herospark.com; version=1
Content-Type: application/json
- Corpo:
{
"payment_link": {
"name": "<nome do produto>",
"description": "<descrição do produto>",
"price_cents": <inteiro em centavos, mínimo 500>,
"absorbs_fees": false,
"max_installments": [12],
"payment_methods": ["pix", "credit_card", "bank_slip"],
"src": "<id do pedido>"
}
}
- absorbs_fees false repassa os juros do parcelamento ao comprador; true faz eu absorver para vender sem juros. O src aceita só letras, números e . _ - ~.
- Salve data.id em heropay_payment_link_id e data.offer.url em checkout_url. Devolva ao cliente só checkout_url e o id do pedido.
- Timeout de 10 segundos. Não repita a chamada automaticamente: POST /payment_links não é idempotente e cria um link novo a cada chamada. Em erro da API, registre status e corpo no log (sem headers) e devolva mensagem amigável.
4. ROTA POST /api/webhooks/heropay/:trigger (servidor, pública)
- Cada gatilho será cadastrado com a própria URL: /api/webhooks/heropay/<gatilho>. Leia o gatilho do caminho.
- Leia o corpo BRUTO antes de qualquer parser de JSON. Calcule HMAC SHA-256 do corpo bruto com HEROPAY_WEBHOOK_SECRET e compare com o header X-HeroPay-Signature em tempo constante, checando o tamanho antes. Confira na documentação de webhooks o formato da assinatura (hex ou base64); se não estiver claro, aceite os dois e me avise. Se não bater ou faltar o header, responda 401 sem processar.
- Só depois parseie o JSON. O id do pedido vem em cart.src; o id do pagamento vem no objeto payment (confirme o nome do campo na documentação).
- Idempotência: insira (payment_id, trigger) em heropay_events; se já existir, responda 200 e não faça mais nada.
- spark_payment_confirmed: marque o pedido como paid e grave paid_at, só se ele estiver pending e se o valor pago bater com amount_cents (confira na documentação o campo de valor e se ele vem em reais ou em centavos). Se não bater, registre no log e não libere.
- refunded e chargeback_request: marque como refunded e revogue o acesso.
- cart.src desconhecido: registre no log e responda 200.
- Responda 2xx rápido. Trabalho pesado (e-mail, provisionamento) vai para a fila que o projeto já usa; se não houver fila, faça depois de gravar o status.
- Em ambiente de desenvolvimento, salve o corpo bruto do primeiro evento de cada gatilho em test/fixtures/heropay/<gatilho>.json (sem dados reais de produção).
5. CLIENTE
- Botão "Comprar" chama /api/checkout e redireciona para checkout_url.
- Página /pedido/:id mostra "Aguardando pagamento" enquanto status = pending e consulta o próprio backend a cada 5 segundos. Com status = paid, mostra "Pagamento confirmado".
- Nunca libere acesso porque o comprador voltou do checkout. Quem libera é o status paid gravado pelo webhook.
6. TESTES (no framework de testes do projeto)
- Assinatura válida responde 200; inválida ou ausente responde 401 e não altera nada.
- O mesmo evento enviado duas vezes marca o pedido como pago uma vez só.
- /api/checkout ignora preço enviado pelo cliente.
- Nenhum teste chama a API real: faça mock do cliente HTTP.
7. ENTREGA
- Rode o linter e os testes e me mostre o resultado.
- Me dê os comandos curl para: criar um pedido local, simular webhook com assinatura inválida e reenviar uma fixture assinada.
- NÃO cadastre webhook sem me perguntar. Não crie nada fora do que foi pedido.Se o seu produto é assinatura, troque o bloco "CONTEXTO DO PRODUTO" por um plano recorrente e peça period: "monthly" (ou quarterly, semiannual, annual) no corpo do link. Detalhes no FAQ de assinatura.
Passo 5: teste as rotas locais com curl
Com o app rodando, teste as rotas que o Claude Code escreveu:
# 1. Cria um pedido (use a sessão de um usuário de desenvolvimento)
curl -s -X POST http://localhost:3000/api/checkout \
-H "Content-Type: application/json" \
-H "Cookie: <sessão do usuário de dev>" \
-d '{"product_key":"plano-pro-anual"}'
# 2. Webhook forjado: tem que responder 401 e não mudar nada
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
"http://localhost:3000/api/webhooks/heropay/spark_payment_confirmed" \
-H "Content-Type: application/json" \
-H "X-HeroPay-Signature: assinatura-falsa" \
-d '{"cart":{"src":"qualquer-coisa"}}'Se o passo 2 responder 200, o webhook está aberto para qualquer um marcar pedido como pago. Não siga adiante sem corrigir.
Passo 6: cadastre o webhook e feche o ciclo
O HeroPay precisa de uma URL pública. Em desenvolvimento, exponha a porta local com um túnel (cloudflared, ngrok ou similar):
cloudflared tunnel --url http://localhost:3000
# devolve algo como https://abc-123.trycloudflare.comCadastre um webhook por gatilho com POST /webhook. Você pode pedir ao Claude Code que rode o laço abaixo; ele mostra o comando e espera sua aprovação:
TUNEL="https://abc-123.trycloudflare.com"
for trigger in spark_payment_confirmed refunded chargeback_request; do
curl -s -X POST "$HEROPAY_API_URL/webhook" \
-H "Authorization: Bearer $HEROPAY_API_KEY" \
-H "Accept: application/vnd.herospark.com; version=1" \
-H "Content-Type: application/json" \
-d "{\"webhook\":{\"trigger\":\"$trigger\",\"webhook_url\":\"$TUNEL/api/webhooks/heropay/$trigger\",\"request_method\":\"post\"}}"
doneCopie o segredo de assinatura do webhook, exibido no painel, para HEROPAY_WEBHOOK_SECRET e reinicie o app. A documentação de webhooks descreve a assinatura em detalhe.
Agora feche o ciclo:
- Abra o
checkout_urldo pedido do passo 5 e faça uma compra de teste no checkout do sandbox. - Veja o evento
spark_payment_confirmedchegar no log e o pedido virarpaid. A fixture fica salva emtest/fixtures/heropay/spark_payment_confirmed.json. - Reenvie a mesma fixture assinada, como se fosse uma retentativa. Tem que responder
200sem liberar em dobro:
F=test/fixtures/heropay/spark_payment_confirmed.json
SIG=$(openssl dgst -sha256 -hmac "$HEROPAY_WEBHOOK_SECRET" "$F" | awk '{print $NF}')
curl -s -w "\n%{http_code}\n" -X POST \
"http://localhost:3000/api/webhooks/heropay/spark_payment_confirmed" \
-H "Content-Type: application/json" \
-H "X-HeroPay-Signature: $SIG" \
--data-binary @"$F"O openssl gera a assinatura em hexadecimal; se a sua rota aceitar só base64, troque por openssl dgst -sha256 -hmac "$HEROPAY_WEBHOOK_SECRET" -binary "$F" | base64. Use --data-binary e não -d: o -d remove quebras de linha, muda os bytes do corpo e a assinatura deixa de bater.
Para pausar os disparos sem perder a configuração, use PUT /webhook/{id}/disable; para religar, enable.
Passo 7: troque a chave e vá pro ar
No ambiente de produção (Vercel, Fly, Render, Kubernetes ou onde o app roda), configure HEROPAY_API_URL=https://api.heropay.tech, o token de produção em HEROPAY_API_KEY e o segredo do webhook de produção. Cadastre os webhooks de novo, agora na API de produção e na URL definitiva do app. Sem fila de homologação: o código que passou no sandbox é o que roda em produção.
No seu terminal de desenvolvimento, continue com a chave de sandbox. A chave de produção fica só no ambiente de deploy.
O que o Claude Code vai gerar no seu repositório?
Com o prompt acima, o Claude Code monta cinco peças, na stack que já existe no projeto. Revise cada uma antes do merge.
| Peça | Onde fica | O que faz |
|---|---|---|
Módulo de configuração + .env.example | Servidor | Lê as três variáveis e falha cedo se faltar alguma |
Migrations products, orders, heropay_events | Banco do projeto | Preço no servidor, status do pedido e registro de idempotência |
POST /api/checkout | Rota de servidor | Chama POST /payment_links com src = id do pedido e devolve a URL do checkout |
POST /api/webhooks/heropay/:trigger | Rota de servidor pública | Valida X-HeroPay-Signature, deduplica e atualiza o pedido |
| Testes de assinatura, idempotência e preço | Suíte do projeto | Garantem que as regras continuam valendo depois da próxima refatoração |
A validação do webhook é a parte que mais vale revisar. Em Node, ela fica parecida com isto (Next.js App Router, que entrega o corpo bruto com req.text()):
// app/api/webhooks/heropay/[trigger]/route.ts
import crypto from "node:crypto";
function assinaturaValida(raw: string, recebida: string, segredo: string) {
const hmac = () => crypto.createHmac("sha256", segredo).update(raw);
// confira o formato (hex ou base64) na documentação de webhooks e mantenha só o certo
const esperadas = [hmac().digest("hex"), hmac().digest("base64")];
const r = Buffer.from(recebida);
return esperadas.some((e) => {
const b = Buffer.from(e);
return r.length === b.length && crypto.timingSafeEqual(r, b);
});
}
export async function POST(
req: Request,
{ params }: { params: Promise<{ trigger: string }> },
) {
const raw = await req.text(); // corpo bruto, antes de qualquer JSON.parse
const recebida = req.headers.get("x-heropay-signature") ?? "";
if (!assinaturaValida(raw, recebida, process.env.HEROPAY_WEBHOOK_SECRET!)) {
return new Response(null, { status: 401 });
}
const { trigger } = await params;
const evento = JSON.parse(raw);
const pedidoId = evento.cart?.src; // o src que você mandou no link
// insere (payment_id, trigger) em heropay_events; se já existe, responde 200 e para
return new Response(null, { status: 200 });
}O truque do campo src: o que você manda nele ao criar o link é salvo no carrinho e volta em cart.src em todos os webhooks daquela compra. Mandando o id do pedido, o webhook sabe exatamente qual linha atualizar, sem casar por e-mail ou valor.
E o MCP server do HeroPay?
Está em desenvolvimento e ainda não foi publicado. Quando sair, ele vai ser anunciado na página de IA e na documentação. Até lá, desconfie de qualquer pacote ou comando de instalação que se apresente como MCP oficial do HeroPay.
Na prática, o Claude Code não precisa dele para integrar. Tudo que um MCP faria no desenvolvimento, o Claude Code já faz com o terminal, sob a sua aprovação:
- Descobrir o contrato real antes de escrever código: o Claude roda o
curldo passo 2, cria um link de R$ 5 no sandbox e usa a resposta verdadeira, em vez de adivinhar o formato. - Depurar o webhook: "a venda de teste confirmou mas o pedido não virou paid; consulta
GET /sales/unitaryno sandbox e compara com o log da rota". - Preparar ambiente de PR: um link por branch com
srcidentificando o PR, para testar o fluxo inteiro no preview.
Por que colocar o HeroPay no CLAUDE.md do projeto?
Porque o Claude Code esquece o que você disse na sessão anterior, mas não esquece o CLAUDE.md. O arquivo na raiz do projeto é lido no começo de cada sessão e vira a memória do repositório: convenções, comandos, regras. Sem ele, cada pedido novo ("adiciona um plano mensal", "cria um cupom de lançamento") é uma nova chance de o Claude mandar 197 em vez de 19700, esquecer o header Accept ou liberar acesso pelo redirect.
O bloco do passo 3 foi escrito para isso. Cada linha evita um erro que custa dinheiro:
| Linha do CLAUDE.md | Erro que ela evita |
|---|---|
Referência no llms.txt e na documentação | Endpoint ou campo inventado a partir do treino |
Header Accept com version=1 | Integração que muda sozinha quando sai versão nova da API |
| Chave só no servidor | Token no bundle do navegador |
| Centavos, mínimo 500, parcela mínima R$ 1,99 | Link de R$ 1,97 recusado com 422, ou 12x num ticket de R$ 10 |
| Preço sai do servidor | Plano comprado por R$ 5 editando a requisição |
| Webhook como fonte de verdade | Acesso liberado para quem só voltou da página de obrigado |
| HMAC antes do parse, tempo constante, dedupe | Evento forjado ou liberação em dobro na retentativa |
src = id do pedido | Conciliação por e-mail ou valor, que quebra no primeiro caso real |
| Testes só com sandbox, perguntar antes de escrever | Evento de produção desviado para uma URL de teste |
Três boas práticas para o bloco continuar útil:
- Versione o
CLAUDE.md. Ele é código de time: quem entra no projeto e abre o Claude Code já recebe as regras. - Não coloque segredo nele. O arquivo vai para o git; só nomes de variáveis, nunca valores.
- Atualize quando a integração mudar. Adicionou assinatura? Acrescente a linha "Recorrência:
periodnoPOST /payment_links; ciclo de vida pelos gatilhossubscription_*".
O mesmo bloco funciona no AGENTS.md que Codex e outras ferramentas leem, e nas regras do Cursor. Veja a integração com o Cursor.
Integrar pagamento pelo Claude Code é seguro?
É tão seguro quanto o cuidado com a chave. O Claude Code não tem credencial própria no HeroPay: ele age pelos comandos que você aprova, com a chave que você deixou no ambiente.
- A chave abre a conta inteira. A API tem endpoints de saque e de estorno, e o token os autoriza. Por isso: chave de sandbox no desenvolvimento, chave de produção só no ambiente de deploy, e nenhum
curlcontra a API de produção na sessão do Claude Code. - Aprovação antes de executar. O Claude Code pede sua confirmação antes de rodar comandos no terminal. Não coloque
curlcontra a API do HeroPay em nenhuma lista de aprovação automática. - Chave fora da conversa e fora do repo. Os comandos usam
$HEROPAY_API_KEY, expandida pelo shell. Para impedir que o Claude abra o.envcom a ferramenta de leitura, bloqueie em.claude/settings.json:
{
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}- Cuidado com conteúdo externo. Uma página, issue ou e-mail lido pelo Claude pode trazer instrução maliciosa escondida, o chamado prompt injection. É mais um motivo para manter a aprovação manual em qualquer comando que fale com a API.
- Revise o diff do webhook. É a única rota pública que muda status de pagamento. Os testes do passo 4 são o mínimo; leia o código.
O que o HeroPay ainda não tem, dito com clareza: o token é único por conta e não expira; não há chave restrita por escopo nem login por OAuth (a Stripe tem os dois). Se desconfiar de vazamento, regenere o token no painel e atualize o ambiente.
Dá para cobrar sem escrever código no repositório?
Dá, e o próprio Claude Code resolve. Se você só quer validar se alguém paga antes de construir o fluxo:
- Peça no Claude Code: "Roda o curl de
POST /payment_linkspara criar um link de R$ 97 da pré-venda do Plano Pro, com Pix e cartão em até 12x, srcpre-venda". A resposta traz a URL do checkout. - Cole a URL no botão da landing, na bio ou no WhatsApp.
- Pergunte depois: "Consulta
GET /sales/unitarye me diz quantas vendas o link da pré-venda teve".
Como isso cobra gente de verdade, a chave precisa ser a de produção: aprove cada comando e tire a chave do ambiente do terminal quando terminar. Se preferir não usar terminal, o mesmo link sai pelo painel. O limite desse caminho: seu app não sabe quem pagou, então a liberação de acesso é manual. Quando as vendas começarem, o prompt do passo 4 transforma isso no fluxo completo. Mais sobre o link de pagamento.
Quais são as armadilhas mais comuns ao integrar pagamento pelo Claude Code?
Parsear o JSON antes de validar a assinatura
É o bug que mais aparece em código gerado. Express com express.json(), Next.js com req.json(), Rails com params: todos entregam o corpo já interpretado, e o HMAC calculado sobre um JSON re-serializado não bate com o que o HeroPay assinou. O Claude "resolve" desligando a validação, e o webhook fica aberto. Leia o corpo bruto (express.raw, req.text(), request.raw_post, request.body no Django) e só parseie depois de validar.
Chave em variável pública do front
NEXT_PUBLIC_, VITE_ e EXPO_PUBLIC_ vão para o bundle que qualquer pessoa baixa pelo navegador. Com o token, alguém cria links, lê suas vendas e consulta seu saldo. Depois da geração, peça: "Procure qualquer uso de HEROPAY_API_KEY fora de código de servidor". A resposta certa é nenhuma.
Chave colada em arquivo versionado
Quem cola o token literal no CLAUDE.md, num script de teste ou num exemplo de curl publica a chave no git. Use sempre $HEROPAY_API_KEY e deixe o valor no ambiente. Se já commitou, regenere o token no painel: apagar o commit não desfaz o vazamento.
Reais onde a API espera centavos
price_cents é inteiro: R$ 197,00 é 19700. Mandar 197 cria um pedido de R$ 1,97, que a API recusa com 422 porque o mínimo é 500. Guarde centavos no banco e só formate na tela.
Confirmar pelo redirect e não pelo webhook
Voltar para a página de obrigado não prova pagamento: o Pix pode ser pago minutos depois no celular e qualquer um digita a URL de sucesso. A fonte de verdade é o spark_payment_confirmed. Confie no evento, não no redirect.
Webhook sem idempotência
A retentativa automática pode entregar o mesmo evento mais de uma vez. Sem o índice único em (payment_id, trigger), você libera acesso em dobro ou manda dois e-mails. O reenvio da fixture no passo 6 existe para provar que isso não acontece.
Repetir POST /payment_links em timeout
A v1 não tem Idempotency-Key: cada chamada cria um link novo. Retry automático de cliente HTTP em POST gera links órfãos. Grave o id retornado e, em timeout, consulte GET /payment_links antes de criar de novo.
Webhook cadastrado no ambiente errado
Cadastrou na API de produção e está testando no sandbox (ou o contrário)? O evento nunca chega. Cada ambiente tem seus webhooks e seu segredo. Liste com GET /webhook no ambiente certo antes de depurar código.
Assinatura esperando só cartão
Links de recorrência (period: monthly, annual etc.) aceitam cartão, boleto e Pix. Na assinatura via Pix, o comprador autoriza o Pix Automático uma vez e as cobranças seguintes caem sozinhas. Se o Claude Code restringir a recorrência a cartão por ler um exemplo antigo, aponte esta regra no CLAUDE.md.
Claude Code com HeroPay, Stripe, Mercado Pago ou AbacatePay: qual escolher?
Todos estão se movendo rápido no eixo Claude Code. A tabela mostra como cada um conecta hoje.
| HeroPay | Stripe | Mercado Pago | AbacatePay | |
|---|---|---|---|---|
| Como entra no Claude Code | API REST + llms.txt e documentação no CLAUDE.md; MCP em desenvolvimento | MCP remoto claude mcp add --transport http stripe https://mcp.stripe.com/ ou plugin | Plugin claude plugin install mercadopago, com MCP | MCP oficial e llms.txt |
| Autenticação | Chave da conta em variável de ambiente | OAuth ou chave de agente | Conta conectada pelo plugin | Chave de API |
| Pix | R$ 0 | 1,19%, só por convite | Ver site oficial | R$ 0,80 |
| Cartão | 3,49%, até 12x | 3,99% + R$ 0,39 | Ver site oficial | 3,50% + R$ 0,60 à vista (4,00% em 2-6x, 4,50% em 7-12x) |
| Boleto | R$ 0 | R$ 3,45 | Ver site oficial | R$ 2,50 |
Verificado em set/2026. Fontes: heropay.tech/precos, docs.stripe.com/mcp, stripe.com/br/pricing, anúncio do Mercado Pago para Claude Code, docs.abacatepay.com, abacatepay.com. Taxas do Mercado Pago não comparadas aqui por variarem por prazo de recebimento.
Onde os outros estão à frente, com honestidade: a Stripe tem servidor MCP remoto com OAuth e chave específica para IA, e o Mercado Pago tem plugin com comandos prontos, incluindo um que audita a integração contra o checklist oficial. O HeroPay ainda não tem MCP publicado, plugin nem OAuth. Onde o HeroPay ganha: Pix e boleto a R$ 0 para qualquer conta, checkout com parcelamento, 2 cartões e recuperação de carrinho, e uma API REST pequena o bastante para caber num prompt. Comparativos completos em Stripe vs HeroPay e AbacatePay vs HeroPay.
Quanto custa integrar pagamento pelo Claude Code?
O HeroPay não cobra pelo llms.txt, pela documentação nem por chamada de API. Você paga por transação aprovada: Pix R$ 0, boleto R$ 0 e cartão 3,49%, em até 12x. Numa venda de R$ 197 no cartão, a tarifa é R$ 6,88; no Pix, R$ 0, e os R$ 197 inteiros entram no saldo.
| 100 vendas de R$ 197 por mês | Pix | Cartão |
|---|---|---|
| HeroPay | R$ 0 | R$ 787,53 |
| Stripe BR | R$ 234,43 (1,19%, só por convite) | R$ 825,03 |
Verificado em set/2026. Fontes: heropay.tech/precos, stripe.com/br/pricing.
Do lado da Anthropic, o Claude Code exige plano pago do Claude ou créditos de API; o HeroPay não interfere nisso. A conta completa por método está em preços.
Perguntas frequentes
Como usar o Claude Code para integrar pagamento no meu projeto?
Abra o Claude Code na raiz do repositório, acrescente ao CLAUDE.md a seção de pagamentos apontando heropay.tech/llms.txt e a documentação em docs.heropay.tech, e mande o prompt pronto desta página. O Claude Code lê sua stack e escreve no próprio repo a rota que chama POST /payment_links, as migrations de pedidos e o webhook com validação HMAC, além dos testes. Você testa com curl no sandbox, cadastra o webhook por um túnel e paga uma compra de teste. Para ir ao ar, troca a chave e a URL base pelas de produção.
O HeroPay tem MCP server para o Claude Code?
Ainda não publicado: o MCP server do HeroPay está em desenvolvimento. A integração não depende dele. O Claude Code lê o llms.txt e a documentação, escreve o código que chama a API REST e roda no terminal os curl de teste que você aprovar, com a chave lida do ambiente. Isso cobre o que um MCP faria no desenvolvimento: criar um link de teste, conferir se a venda entrou, cadastrar o webhook. Quando o MCP for publicado, o anúncio sai na página de IA e na documentação.
O que o llms.txt do HeroPay faz no Claude Code?
O heropay.tech/llms.txt é um arquivo de texto feito para IAs: resume o que é o HeroPay, lista as páginas do site com descrição e aponta para a documentação da API em docs.heropay.tech. Referenciado no CLAUDE.md, ele dá ao Claude Code o mapa de onde buscar cada informação. O contrato que mais importa (endpoint, headers, corpo em centavos, validação do webhook) já vai escrito no bloco do CLAUDE.md e no prompt desta página, para o Claude não depender de adivinhação.
O Claude Code pode mexer no meu dinheiro?
Só pelos comandos que você aprovar, com a chave que você deixou no ambiente. O token do HeroPay dá acesso à conta inteira, incluindo endpoints de saque e estorno, então a regra é simples: chave de sandbox no terminal de desenvolvimento, chave de produção só no ambiente de deploy, e aprovação manual em qualquer curl contra a API. O código que o prompt desta página gera cria links e lê webhooks; ele não chama saque nem estorno. No sandbox, nada disso envolve dinheiro real.
Onde guardo a chave de API quando uso o Claude Code?
No ambiente, nunca no chat nem no código. Para o app, use o .env (fora do git) ou o gerenciador de segredos do seu deploy, com o nome HEROPAY_API_KEY. Os comandos de teste usam $HEROPAY_API_KEY, expandida pelo shell, então o valor não entra na conversa. Bloqueie a leitura do .env pelo Claude em .claude/settings.json com permissions.deny. Se a chave vazar, regenere o token no painel do HeroPay e atualize o ambiente.
Funciona com qualquer stack: Next.js, Rails, Django, Laravel?
Funciona. A API é REST com JSON e dois headers, então qualquer linguagem com cliente HTTP integra. O prompt desta página pede que o Claude Code primeiro identifique a stack, o ORM e o padrão de rotas do projeto e siga o que já existe, sem adicionar framework novo. A documentação tem exemplos em 18 linguagens e a OpenAPI é pública. O cuidado que muda por stack é ler o corpo bruto do webhook antes do parser de JSON.
Como testo o webhook localmente com o Claude Code?
Exponha a porta do app com um túnel (cloudflared ou ngrok), cadastre a URL pública no sandbox por curl em POST /webhook, um gatilho por URL, e faça uma compra de teste. O prompt manda o app salvar o corpo bruto do primeiro evento como fixture. Com ela, você reenvia o evento assinado com openssl dgst -sha256 -hmac e curl --data-binary, provando que a assinatura bate e que a segunda entrega não libera em dobro. Um curl com assinatura falsa precisa responder 401.
O Claude Code consegue integrar assinatura recorrente?
Consegue. Peça no prompt um link com period (monthly, quarterly, semiannual ou annual) no POST /payment_links, com renovação ilimitada ou limitada por frequency_limit. A recorrência aceita cartão, boleto e Pix; no Pix, o comprador autoriza o Pix Automático uma vez e as cobranças seguintes caem sozinhas. Peça também as rotas para os gatilhos subscription_activate, subscription_update e subscription_cancel, que avisam seu app sobre o ciclo de vida, e o cancelamento por POST /recurring_payment/cancel. Mais em assinaturas.
Quanto custa usar o HeroPay com o Claude Code?
O HeroPay não cobra pelo llms.txt, pela documentação nem por chamada de API, e o sandbox é gratuito. Você paga por transação aprovada: Pix R$ 0, boleto R$ 0 e cartão 3,49%, em até 12x, sem mensalidade, ativação ou mínimo. Numa venda de R$ 197 no cartão, a tarifa é R$ 6,88; no Pix, R$ 0. O Claude Code em si depende de um plano pago do Claude ou de créditos de API da Anthropic, cobrados à parte pela Anthropic.
Posso compartilhar a configuração com o meu time?
Pode. Versione o CLAUDE.md com a seção HeroPay e o .env.example com os nomes das variáveis, sem valores. Cada pessoa cria a própria conta sandbox e coloca o próprio token no .env local. Assim, qualquer pessoa que abrir o Claude Code no repositório recebe as mesmas regras (centavos, header Accept, webhook assinado como fonte de verdade) e integra do mesmo jeito, sem nenhuma chave circulando pelo git.
O mesmo fluxo funciona no Cursor, no Codex ou no Lovable?
Funciona, com o mesmo contrato: rota de servidor com a chave, POST /payment_links, webhook assinado confirmando. O bloco do CLAUDE.md pode ir para as regras do Cursor ou para o AGENTS.md que o Codex lê, e o llms.txt serve para Claude, ChatGPT, Cursor, Lovable e outros. No Lovable, a chamada fica numa edge function. Veja a integração com o Lovable, a integração com o Cursor e a página de IA.
Qual a diferença entre integrar o HeroPay e o Stripe pelo Claude Code?
A Stripe tem MCP remoto (mcp.stripe.com), com OAuth ou chave específica para IA. O HeroPay entra pela API REST: o Claude Code lê o llms.txt e a documentação, escreve o código e testa com curl; o MCP do HeroPay está em desenvolvimento e ainda não há OAuth. A diferença que pesa no bolso é o preço: no HeroPay, Pix e boleto custam R$ 0 e o cartão 3,49%; na Stripe Brasil, o cartão é 3,99% + R$ 0,39, o boleto R$ 3,45 e o Pix 1,19%, só por convite (verificado em set/2026).
Comece agora
Crie a conta sandbox, cole o bloco no CLAUDE.md e mande o prompt. A primeira venda de teste sai em minutos, no seu repositório, sem fila de homologação. Quando passar no sandbox, troque a chave e vá pro ar.