PixToMe LogoPixToMe
Dashboard

Documentação da API PixToMe

Introdução

A API REST do PixToMe cria e consulta cobranças PIX. Respostas em JSON UTF-8, valores em centavos (inteiros) e horários em ISO 8601 UTC.

Base URL
1https://api.pixtome.com/v1
Fluxo em 4 passos
  1. 1Crie a cobrança — POST /deposits do seu servidor com o CPF/CNPJ do pagador.
  2. 2Receba o QR Code — a API retorna pix.br_code (string EMV copia-e-cola).
  3. 3Exiba como QR — renderize com qualquer lib de QR Code.
  4. 4Confirme — webhook deposit.confirmed ou polling em GET /deposits/:id.

Em erros temporários (5xx) use exponential backoff com jitter. Sem o header Idempotency-Key, repetir o mesmo POST /deposits abre outra cobrança — guarde o id. Com Idempotency-Key, a mesma chave e o mesmo corpo devolvem a cobrança original (200, header Idempotency-Replayed: true) e não criam outro PIX.

Quickstart — receber seu primeiro PIX

Cinco passos para sair do zero e receber um pagamento real:

  1. Crie sua conta e complete o perfil com CPF/CNPJ em Configurações. Sem isso o provedor rejeita as cobranças (exigência do BACEN).
  2. Gere uma chave de API em API & Webhooks. A chave pix_live_… só aparece uma vez. Guarde em um cofre, nunca no front-end.
  3. Crie a cobrança com POST /deposits a partir do seu servidor, com o CPF/CNPJ do pagador e um header Idempotency-Key. A resposta traz pix.br_code.
  4. Exiba o QR Code renderizando o br_code.
  5. Receba a confirmação pelo webhook deposit.confirmed ou por polling em GET /deposits/:id até status confirmed.
Limites por cobrança: R$ 10,00 a R$ 500,00. Limite diário por pagador: R$ 6.000,00 por CPF/CNPJ (reseta à meia-noite, horário de Brasília). Você pode gerar vários QR Codes para o mesmo cliente até o teto diário dele. Cada cobrança confirmada desconta R$ 0,99 do saldo; o 1% incide só no saque (uma venda de R$ 1.000,00 deixa R$ 999,01 disponíveis; sacar esse saldo custa 1% = R$ 9,99 e o lojista recebe R$ 989,02). Saldo confirmado fica em hold de 3 dias antes de poder ser sacado.

Health check

Endpoint público (sem autenticação) para monitorar disponibilidade. O campo build identifica o release publicado.

GET/health
cURL
1curl https://api.pixtome.com/v1/health
200
1{
2 "status": "ok",
3 "version": "1",
4 "build": "2026-10-13.3",
5 "time": "2026-06-17T13:40:00.000Z"
6}

Autenticação

Cada requisição, exceto GET /health, precisa do header Authorization. Crie chaves no painel em API & Webhooks; o texto puro só aparece uma vez. Rotas desconhecidas respondem 404 e métodos errados respondem 405 sem exigir a chave.

Authorization
1Authorization: Bearer pix_live_<48 chars hex>

Não há sandbox — chaves pix_test_… também geram cobranças PIX reais. Nunca exponha a chave no front-end.

Criar cobrança

Cria uma cobrança PIX e devolve o BR Code (copia-e-cola). A cobrança expira em 60 minutos — o mesmo prazo do painel.

O header opcional Idempotency-Key (1–128 caracteres: letras, dígitos e . _ : ~ -) torna o POST seguro para repetir. A mesma chave com o mesmo corpo devolve a cobrança original (200, header Idempotency-Replayed: true) sem gerar outro PIX. Corpo diferente com a mesma chave responde 409 IDEMPOTENCY_MISMATCH. Enquanto a primeira ainda não terminou, a resposta é 409 IDEMPOTENCY_IN_PROGRESS.

POST/deposits
ParâmetroTipoDescrição
amount_brlnumber, obrigatórioValor em reais (ex.: 49.90). Mínimo 10,00; máximo 500,00.
descriptionstringOpcional, no máximo 80 caracteres. A PixToMe grava e devolve este campo no painel, no GET e nos webhooks. Não é enviado ao provedor e não entra no QR Code PIX.
customer.namestringNome do pagador (opcional, máx. 80).
customer.tax_numberstring, obrigatórioCPF (11 dígitos) ou CNPJ (14). Sem ele a cobrança responde 422.

description é só da PixToMe. O provedor não recebe esse texto e ele não aparece para o pagador no PIX.

O CPF/CNPJ do pagador é obrigatório para gerar o QR Code PIX. Colete o documento antes de chamar a API. Aceitamos com ou sem pontuação (390.533.447-05 ou 39053344705); os dígitos são validados no servidor.
1curl -X POST https://api.pixtome.com/v1/deposits \
2 -H "Authorization: Bearer $PIXTOME_KEY" \
3 -H "Content-Type: application/json" \
4 -H "Idempotency-Key: pedido-1024" \
5 -d '{
6 "amount_brl": 49.90,
7 "description": "Pedido #1024",
8 "customer": {
9 "name": "João Silva",
10 "tax_number": "390.533.447-05"
11 }
12 }'
201
1{
2 "id": "8f9a3b7c-1234-4abc-9def-1234567890ab",
3 "amount_cents": 4990,
4 "description": "Pedido #1024",
5 "status": "pending",
6 "pix": {
7 "br_code": "00020101021226540014br.gov.bcb.pix0116loja@pixtome.com..."
8 },
9 "customer": {
10 "name": "João Silva",
11 "tax_number": "***.***.***-05"
12 },
13 "created_at": "2026-06-17T13:40:00.000Z",
14 "expires_at": "2026-06-17T14:40:00.000Z",
15 "confirmed_at": null
16}

O id é um UUID. O tax_number da resposta vem sempre mascarado. O documento completo fica guardado para conciliação e compliance.

Consultar cobrança

Devolve o status atual. O status muda pelo webhook do provedor e por uma reconciliação periódica. Faça polling a cada 3–5 segundos ou, de preferência, escute o webhook.

GET/deposits/:id
1curl https://api.pixtome.com/v1/deposits/8f9a3b7c-1234-4abc-9def-1234567890ab \
2 -H "Authorization: Bearer $PIXTOME_KEY"
200
1{
2 "id": "8f9a3b7c-1234-4abc-9def-1234567890ab",
3 "amount_cents": 4990,
4 "description": "Pedido #1024",
5 "status": "confirmed",
6 "pix": {
7 "br_code": "00020101021226540014br.gov.bcb.pix0116loja@pixtome.com..."
8 },
9 "customer": {
10 "name": "João Silva",
11 "tax_number": "***.***.***-05"
12 },
13 "created_at": "2026-06-17T13:40:00.000Z",
14 "expires_at": "2026-06-17T14:40:00.000Z",
15 "confirmed_at": "2026-06-17T13:42:10.000Z"
16}

Status possíveis: pending, confirmed, expired, error, refunded (estorno/MED depois do pagamento; pode ocorrer semanas depois).

Listar cobranças

Lista as cobranças mais recentes da conta, da mais nova para a mais antiga.

GET/deposits
ParâmetroTipoDescrição
limitintegerQuantidade de itens (1 a 100). Padrão: 20.
cURL
1curl "https://api.pixtome.com/v1/deposits?limit=10" \
2 -H "Authorization: Bearer $PIXTOME_KEY"
200
1{
2 "data": [
3 { "id": "8f9a3b7c-1234-4abc-9def-1234567890ab", "amount_cents": 4990, "status": "confirmed", "...": "..." },
4 { "id": "a1b2c3d4-5678-4abc-9def-1234567890cd", "amount_cents": 12000, "status": "pending", "...": "..." }
5 ]
6}

Renderizar o QR Code

O campo pix.br_code é a string BR Code (EMV) — a mesma que o cliente cola no app do banco. Renderize com qualquer biblioteca.

npm
1npm install qrcode.react
React
1import { QRCodeSVG } from "qrcode.react";
2
3export function PixCheckout({ deposit }) {
4 return (
5 <div className="flex flex-col items-center gap-3">
6 <QRCodeSVG value={deposit.pix.br_code} size={256} level="M" />
7 <button onClick={() => navigator.clipboard.writeText(deposit.pix.br_code)}>
8 Copy PIX code
9 </button>
10 <p>Expira em {new Date(deposit.expires_at).toLocaleTimeString()}</p>
11 </div>
12 );
13}

Em HTML puro use qrcode (QRCode.toDataURL). No servidor, gere PNG/SVG e sirva como imagem.

Configurar webhook

Sem webhook você precisa fazer polling. Com webhook, a PixToMe avisa seu servidor em segundos quando o cliente paga.

  1. Exponha um endpoint HTTPS público (ex.: https://seu-dominio.com/webhooks/pixtome).
  2. Em API & Webhooks, cadastre a URL. Cada endpoint tem o próprio secret — guarde como PIXTOME_WEBHOOK_SECRET. Até 10 endpoints por conta; o mesmo id de evento vai para todos os ativos.
  3. Valide o HMAC antes de processar o payload. Responda 2xx em até 10 segundos.
  4. Trate o evento de forma idempotente: o mesmo id pode chegar mais de uma vez (até 3 tentativas em ~8 s).
Endpoint Express (Node.js)
1import express from "express";
2import { verifySignature } from "./verify.js";
3
4const app = express();
5const processed = new Set(); // use Redis/DB in production
6
7// raw body is required for the HMAC
8app.post("/webhooks/pixtome",
9 express.raw({ type: "application/json" }),
10 async (req, res) => {
11 const sig = req.header("X-Pixtome-Signature");
12 const raw = req.body.toString("utf8");
13 if (!sig || !verifySignature(raw, sig, process.env.PIXTOME_WEBHOOK_SECRET)) {
14 return res.status(401).send("invalid signature");
15 }
16 const evt = JSON.parse(raw);
17 if (processed.has(evt.id)) return res.sendStatus(200); // idempotent
18 processed.add(evt.id);
19
20 if (evt.event === "deposit.confirmed") {
21 // fulfill the order — evt.data.id, evt.data.amount_cents
22 }
23 res.sendStatus(200);
24 },
25);

Em desenvolvimento, exponha o localhost com ngrok ou Cloudflare Tunnel. URLs privadas são bloqueadas.

Eventos por webhook

A PixToMe envia POST para a URL cadastrada em API & Webhooks. Responda 2xx em até 10 s. Até 3 tentativas em ~8 s. Headers: X-Pixtome-Signature, X-Pixtome-Event, User-Agent: PixToMe-Webhook/1.

  • deposit.confirmed — pagamento confirmado. Se o valor divergir, chega deposit.amount_mismatch e nada é creditado.
  • deposit.expired — expirou sem pagamento.
  • deposit.canceled — cancelada pelo pagador, pelo parceiro ou pelo provedor (não é expiração).
  • deposit.failed — falha antes de o valor ser creditado.
  • deposit.will_refund — PIX na fila de reembolso; o valor não é creditado.
  • deposit.under_bank_review — bloqueio preventivo do banco; o valor não é creditado.
  • deposit.refunded — pagamento confirmado estornado depois (estorno/MED).
  • deposit.amount_mismatch — o valor pago não bate com amount_cents.
Payload
1{
2 "id": "evt_a3f0c1d27b8e4f5a6b7c8d9e",
3 "event": "deposit.confirmed",
4 "created_at": "2026-06-17T13:42:11.000Z",
5 "data": {
6 "id": "8f9a3b7c-1234-4abc-9def-1234567890ab",
7 "amount_cents": 4990,
8 "status": "confirmed",
9 "customer": { "tax_number": "***.***.***-12" },
10 "confirmed_at": "2026-06-17T13:42:10.000Z"
11 }
12}

Assinatura HMAC

Cada webhook traz X-Pixtome-Signature com o HMAC-SHA256 do corpo bruto e o secret daquele endpoint. Compare sempre em tempo constante.

Header
1X-Pixtome-Signature: t=1718630531,v1=8e3...c4
Node.js
1import crypto from "node:crypto";
2
3export function verifySignature(rawBody, header, secret) {
4 const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
5 const expected = crypto
6 .createHmac("sha256", secret)
7 .update(`${parts.t}.${rawBody}`)
8 .digest("hex");
9 return crypto.timingSafeEqual(
10 Buffer.from(expected),
11 Buffer.from(parts.v1),
12 );
13}
Python
1import hmac, hashlib
2
3def verify(raw_body: bytes, header: str, secret: str) -> bool:
4 parts = dict(p.split("=") for p in header.split(","))
5 expected = hmac.new(
6 secret.encode(),
7 f"{parts['t']}.".encode() + raw_body,
8 hashlib.sha256,
9 ).hexdigest()
10 return hmac.compare_digest(expected, parts["v1"])

Códigos de erro

Todas as respostas de erro usam o mesmo formato:

error
1{
2 "error": {
3 "code": "VALIDATION_FAILED",
4 "message": "amount must be > 0",
5 "details": { "field": "amount_brl" }
6 }
7}
ParâmetroTipoDescrição
400INVALID_JSONCorpo não é um JSON válido.
400IDEMPOTENCY_KEY_INVALIDIdempotency-Key fora do formato (1–128: letras, dígitos e . _ : ~ -).
401MISSING_AUTH / INVALID_KEYChave de API ausente, inválida ou revogada.
403ACCOUNT_SUSPENDEDConta suspensa.
404NOT_FOUNDCobrança inexistente ou rota desconhecida. Rota errada não exige autenticação.
405METHOD_NOT_ALLOWEDMétodo não permitido nessa rota (Allow lista os métodos). Não exige autenticação.
409IDEMPOTENCY_MISMATCHA mesma Idempotency-Key já foi usada com outro corpo.
409IDEMPOTENCY_IN_PROGRESSA cobrança dessa chave ainda está sendo criada. Retry-After: 2.
409PSP_OUTCOME_EXPIREDO provedor não confirmou a cobrança e a janela de recuperação fechou. Nada foi creditado. Use uma Idempotency-Key nova.
413PAYLOAD_TOO_LARGECorpo maior que 16 KB.
422VALIDATION_FAILEDParâmetro inválido (ex.: valor fora de R$ 10,00–R$ 500,00).
422VALIDATION_FAILED (customer.tax_number)CPF/CNPJ ausente, com tamanho errado ou dígitos inválidos.
422PAYER_BLOCKEDCPF/CNPJ recusado pelo compliance do provedor PIX.
422PROVIDER_REJECTEDO provedor recusou a cobrança. details.provider_code traz o código.
429RATE_LIMITEDMais de 6 cobranças por minuto na conta. Retry-After: 60.
429GLOBAL_RATE_LIMITEDLimite por minuto do provedor. Retry-After: 60.
500MISCONFIGUREDConfiguração interna ausente. Fale com o suporte.
500INTERNAL_ERRORA cobrança foi criada no provedor, mas não foi salva. Repita com a mesma Idempotency-Key.
502PSP_ERRORFalha temporária no provedor. Use exponential backoff.
503PSP_OUTCOME_UNKNOWNO provedor não confirmou se a cobrança nasceu. Outro PIX não foi aberto. Repita com a mesma Idempotency-Key. Retry-After: 60.
503PSP_BUSYProvedor ocupado. Respeite o Retry-After.
503PSP_UNAVAILABLEProvedor em manutenção. Respeite o Retry-After.