Integrar PIX no checkout da sua loja é mais simples do que parece: um POST pra criar a cobrança e um webhook pra receber o status. Este guia mostra o caminho do zero — funciona em qualquer linguagem (Node, PHP, Python, Ruby, Go, .NET, Elixir) porque o contrato é só HTTP + JSON.
Passo 1 — Pegar sua chave de API
Depois de criar a conta e ter o cadastro aprovado, abra Projetos no painel e copie a API key do projeto Default. Você a usa como usuário em HTTP Basic; a senha fica em branco. Cada projeto tem a sua chave — separe ambientes (produção / staging) criando projetos diferentes.
Passo 2 — Criar uma cobrança
Faça um POST para o endpoint de criação. O valor é em centavos (R$ 19,90 = 1990) e o external_id deve ser único na sua loja — usamos pra idempotência (chamar a mesma criação duas vezes não duplica a cobrança).
curl -X POST 'https://vanillapag.com/v1/payment-transaction/create' \
-H 'Authorization: Basic '$(echo -n 'sua-api-key:x' | base64) \
-H 'Content-Type: application/json' \
-d '{
"amount": 1990,
"external_id": "pedido-12345",
"customer": {
"name": "Cliente Exemplo",
"email": "[email protected]",
"document": "12345678901"
}
}'
A resposta traz o qr_code (payload copia-e-cola), a qr_code_image (URL pública do PNG do QR) e o id interno da transação. Tudo em menos de 300 ms.
Passo 3 — Renderizar o QR no checkout
No seu checkout, mostre o QR e o copia-e-cola lado a lado:
- QR Code visual: use a
qr_code_imagedireto numa<img>, ou gere um SVG localmente a partir doqr_codecom qualquer lib de QR (qrcode.js no browser, qrcode em Node, endroid/qr-code em PHP). - Botão "Copiar código": copia o
qr_code(a string PIX) — clientes em mobile preferem colar no app do banco em vez de escanear. - Polling opcional: chame
GET /v1/payment-transaction/info/{id}a cada 3–5 s pra atualizar a tela se quiser feedback imediato. O webhook ainda é a fonte autoritativa.
Passo 4 — Receber o webhook (status final)
Exponha um endpoint público no seu servidor que aceite POST JSON. Configure a URL em Projetos → Webhook URL. Quando o cliente pagar (em segundos, normalmente), enviamos:
{
"id": "tx_2sQfgT...",
"status": "PAID",
"amount": 1990,
"payment_method": "pix",
"customer": { "name": "...", "email": "...", "document": "..." },
"paid_at": "2026-05-15T17:24:11Z"
}
Verifique o header X-Signature com HMAC-SHA256 usando o webhook_secret da sua credencial antes de processar — assim você sabe que o evento veio da gente, não de um atacante. Veja o tutorial de verificação HMAC com código pronto em Node, PHP e Python.
Responda 2xx em até 10 segundos. Em caso de falha (não-2xx ou timeout), tentamos de novo automaticamente com backoff: 30 s, 2 min, 8 min, 30 min, 2 h.
Idempotência: o detalhe que evita venda duplicada
Webhook pode chegar duas vezes (retry após timeout, replay de teste, etc.). Use o id da transação como chave única no seu banco antes de liberar o pedido:
// Pseudo-código
if (await db.findOrder({ vanillaTxId: event.id })) {
return res.status(200).send("já processado");
}
await db.markOrderPaid(event.external_id);
await db.saveVanillaTx(event.id);
Próximos passos
- Veja a documentação completa da API com todos os endpoints e exemplos.
- Configure split de pagamentos se sua loja é marketplace.
- Saiba como funciona o antifraude integrado.