Crie uma chave de API
Em Desenvolvedores, crie uma chave vk_test_ com os escopos charges:write e webhooks:write. O segredo aparece uma única vez.
Abrir DesenvolvedoresAPI Pix v1
Sua loja, ERP, CRM ou SaaS cria cobranças e carnês, manda o link ou o QR ao pagador, e recebe a confirmação por webhook. Tudo o que está nesta página é o que a API faz hoje — campos, erros e limites conferidos contra o código.
Valores são inteiros em centavos. Nunca use ponto flutuante para dinheiro. Campos desconhecidos são recusados com 400.
Use /llms.txt (esta documentação em markdown) e https://api.pagueo.com.br/api/docs-json (OpenAPI 3) como fonte de verdade. Envie somente os campos descritos; o ambiente vem da chave, não do corpo. Mantenha a mesma Idempotency-Key em retries. Considere uma cobrança paga apenas quando status for PAID em GET /charges/:id ou num webhook charge.paid com assinatura válida.
Primeira integração
Crie uma chave de TESTE no painel, guarde-a no servidor, crie uma cobrança, simule o pagamento e veja o status virar PAID.
Em Desenvolvedores, crie uma chave vk_test_ com os escopos charges:write e webhooks:write. O segredo aparece uma única vez.
Abrir DesenvolvedoresPOST /charges com amountCents, description, externalId (o id do seu pedido) e uma Idempotency-Key estável.
Em TEST, POST /charges/:id/simulate-payment paga a cobrança pelo mesmo caminho da produção. Libere o pedido só com status PAID.
curl --request POST 'https://api.pagueo.com.br/api/v1/charges' \
--header 'Authorization: Bearer vk_test_sua_chave' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: pedido-1033' \
--data '{
"amountCents": 14990,
"description": "Pedido #1033",
"externalId": "pedido-1033",
"expiresInSeconds": 3600
}'qrCodeUrl vem null — é o simulate-payment que exercita o resto do caminho, inclusive o webhook.Fluxo real
A PAGUEO conversa com o provedor de liquidação; sua aplicação conversa só com a PAGUEO. Duas formas de saber que entrou: o webhook assinado, ou a consulta.
qrCodeUrl · pixCopyPaste · publicUrlA criação devolve PENDING. Exibir um QR não é confirmação de pagamento.
charge.paid (assinado) ou GET /charges/:idO webhook chega em segundos. Se preferir certeza dupla, ao receber o evento consulte a cobrança antes de liberar.
Credenciais
Toda chamada privada usa Bearer token. A conta é a da chave: não existe tenantId na API, e o ambiente (TEST ou LIVE) também vem da chave.
Authorization: Bearer vk_live_…Nunca em frontend, aplicativo ou repositório. Uma chave vazada se revoga no painel e se recria.
vk_test_… cria em TEST · vk_live_… em LIVEQuem opera várias lojas tem uma chave por loja. O campo environment no corpo é aceito por compatibilidade e ignorado.
charges:readleiturasimConsultar cobranças, carnês e a linha do tempo de cada uma; enviar a cobrança por e-mail.
charges:writeescritanãoCriar cobranças e carnês, baixar, conferir no provedor e simular pagamento (TEST).
customers:readleiturasimListar e consultar clientes (pagadores).
customers:writeescritanãoCadastrar e editar clientes.
webhooks:readleituranãoListar os endpoints de webhook e o histórico de entregas.
webhooks:writeescritanãoCadastrar e remover endpoints, girar o segredo e reenviar entregas.
balance:readleituranãoLer o saldo da conta.
transfers:readleituranãoListar e consultar Pix enviados e pedidos de saque.
transfers:writeescritanãoReservado ao painel: envio de Pix e pedido de saque com chave de API respondem 403.
bills:readleituranãoConsultar contas pagas e ler um código de barras.
bills:writeescritanãoReservado ao painel: pagar conta com chave de API responde 403.
"Padrão: sim" é o que uma chave recebe quando POST /api-keys vem sem scopes. Peça só o que a integração usa; escopo faltando responde 403 Escopo X não concedido.
Endpoint principal
Uma cobrança gera QR Code, Pix copia e cola e uma página pública para compartilhar por WhatsApp, e-mail ou checkout.
/chargescharges:writeamountCentsintegersimValor em centavos de BRL, de 1 a 100.000.000 (R$ 0,01 a R$ 1.000.000,00). Ex.: 14990 = R$ 149,90.
descriptionstring ≤ 140simO que está sendo cobrado; aparece na cobrança e para o pagador. Obrigatória, exceto quando vier chargeItemId. Descrição que indique atividade proibida (apostas, armas, drogas, pirâmide…) é recusada com 400 PROHIBITED_BUSINESS_CATEGORY.
externalIdstring ≤ 100nãoO id do pedido no SEU sistema. Volta em toda resposta e em todo webhook: é a sua chave de conciliação.
customerIdstringnãoCliente cadastrado na conta (POST /customers). Nome, documento e e-mail dele vão ao provedor. Inexistente responde 404.
expiresInSecondsintegernãoValidade do QR, de 60 a 2.592.000 segundos (30 dias). Sem o campo: 3600 (1 hora).
payerNamestring ≤ 120nãoNome do pagador quando não há customerId.
payerDocumentstring ≤ 20nãoCPF ou CNPJ do pagador quando não há customerId. Máscara é aceita e descartada.
chargeItemIdstringnãoItem do catálogo da conta (cadastrado no painel). Dispensa description. O VALOR não vem do item: mande amountCents sempre.
environmentTEST | LIVEnãoAceito por compatibilidade e IGNORADO: o ambiente vem da credencial. vk_test_ cria em TEST; vk_live_ cria em LIVE.
A mesma forma volta em GET /charges/:id e dentro de todo webhook. Guarde o id junto do pedido.
{
"id": "cmtyv7fek000bpc018ulijzjg",
"status": "PENDING",
"environment": "TEST",
"amountCents": 14990,
"currency": "BRL",
"description": "Pedido #1033",
"reference": null,
"externalId": "pedido-1033",
"pixCopyPaste": "00020126580014br.gov.bcb.pix…",
"qrCodeUrl": "data:image/png;base64,…",
"expiresAt": "2026-09-12T22:00:00.000Z",
"paidAt": null,
"feeCents": null,
"netAmountCents": null,
"publicUrl": "https://pagueo.com.br/p/<token>",
"customer": null,
"chargeItem": null,
"installmentNumber": null,
"paymentPlanId": null,
"createdAt": "2026-09-12T21:00:00.000Z"
}idstringnãoIdentificador da cobrança. Guarde junto do pedido.
statusenumnãoVer a tabela de status. Liberar o pedido só em PAID.
environmentTEST | LIVEnãoEm TEST o Pix NÃO é pagável e qrCodeUrl vem null; use simulate-payment.
pixCopyPastestring | nullnãoO código Pix copia e cola (BR Code).
qrCodeUrlstring | nullnãoA imagem do QR pronta para <img src>: data URI em produção; null em TEST.
publicUrlstringnãoPágina de pagamento hospedada pela PAGUEO, para mandar por WhatsApp ou e-mail.
expiresAtISO 8601 | nullnãoQuando o QR deixa de valer.
paidAtISO 8601 | nullnãoQuando o provedor confirmou o pagamento.
feeCents / netAmountCentsinteger | nullnãoTarifa da PAGUEO e valor líquido. null até a liquidação; 0 é tarifa zero.
customerobjeto | nullnão{ id, name, email, phone } quando a cobrança tem cliente.
chargeItemobjeto | nullnão{ id, name, category } quando veio do catálogo. null em tudo que entra pela API sem chargeItemId.
installmentNumber / paymentPlanIdinteger | string | nullnãoPreenchidos quando a cobrança é parcela de um carnê.
CREATEDRegistrada, sem o QR confirmado pelo provedor ainda. Passageiro.
PENDINGQR emitido, aguardando o pagador. É o status normal logo depois de criar.
PAIDPagamento confirmado pelo provedor. SÓ AQUI o pedido pode ser liberado.
EXPIREDVenceu sem pagamento. Não volta: crie outra cobrança.
CANCELLEDBaixada por você (POST /charges/:id/cancel) ou junto do carnê.
REFUNDEDDevolvida ao pagador. Reservado para conciliação: hoje nenhuma rota da API devolve.
FAILEDO provedor recusou a emissão. Nada foi cobrado.
PENDING. Só marque o pedido como pago em PAID.POST /charges/:id/cancelCancela no provedor e aqui. Só CREATED ou PENDING; cobrança paga responde 409. Corpo opcional: { reason }.
GET /charges/:id/eventsCada transição com origem, payload e horário — criação, webhook, conciliação, baixa.
POST /charges/:id/reconcilePergunta ao provedor o status real (LIVE). Para quando o pagador diz que pagou e a cobrança segue PENDING.
POST /charges/:id/simulate-paymentSó TEST. Marca como paga pelo mesmo caminho da produção: tarifa, eventos e webhook charge.paid.
Cobrança parcelada
O carnê é N cobranças com vencimento (Boleto Pix), emitidas de uma vez. Cada parcela continua pagável depois de vencer, com multa e juros calculados pelo provedor — como um boleto.
/charges/planscharges:writetitlestring ≤ 140simNome do carnê. Cada parcela sai como "<title> - parcela N/T".
installmentAmountCentsintegersimValor de CADA parcela, em centavos (1 a 100.000.000).
installmentCountintegersimQuantidade de parcelas, de 1 a 60. Uma cobrança com vencimento por parcela, todas emitidas de uma vez.
firstDueDateYYYY-MM-DDsimVencimento da primeira parcela; as seguintes vencem no mesmo dia dos meses seguintes.
descriptionstring ≤ 140nãoTexto livre sobre o contrato ou plano.
customerIdstringnãoObrigatório NA PRÁTICA: cobrança com vencimento exige CPF/CNPJ do pagador (regra do arranjo Pix), e é do cliente cadastrado que ele vem. Sem cliente com documento, o provedor recusa.
environmentTEST | LIVEnãoAceito e ignorado: o ambiente vem da credencial.
id, status (ACTIVE, COMPLETED, CANCELLED), totalAmountCents e publicUrl — a página do carnê inteiro.installments[]: number, amountCents, dueDate, status e a charge de cada parcela, com QR, copia e cola e link próprios.document antes.Idempotency-Key para um retry não criar dois carnês.{
"title": "Mensalidade Plano Pro",
"installmentAmountCents": 12500,
"installmentCount": 12,
"firstDueDate": "2026-10-10",
"customerId": "cmtx…cliente"
}/charges/plans/:id/cancelcharges:writeBaixa o carnê no provedor e cancela todas as parcelas ainda PENDING. Parcelas pagas continuam no histórico.
Pagadores
Cadastre quem paga uma vez e reaproveite em cobranças e carnês. É do cadastro que saem nome, documento e e-mail enviados ao provedor.
/customerscustomers:writenamestring 3–120simNome completo, como no documento.
documentstring ≤ 20simCPF ou CNPJ. Máscara é aceita e descartada. É o que permite emitir carnê para este cliente.
phonestring ≤ 30simTelefone com DDD. Aceita máscara e o 55 na frente.
emaile-mail ≤ 160nãoPara onde a cobrança pode ser enviada por e-mail.
externalCodestring ≤ 100nãoO código deste cliente no seu sistema.
identityDocumentstring ≤ 40nãoRG ou outro documento de identidade.
genderFEMALE | MALE | OTHER | UNDISCLOSEDnãoOpcional.
addressStreet, addressNumber, addressComplement, addressNeighborhood, addressCitystringnãoEndereço, campo a campo. Todos opcionais.
addressStateUF (2 letras)nãoSigla do estado.
addressPostalCodestring ≤ 9nãoCEP, com ou sem hífen.
409. Use GET /customers?q= antes, ou guarde o id pelo seu externalCode.GET /customers devolve podeReceberCarne: true quando há documento.PATCH /customers/:id aceita qualquer subconjunto dos campos.{
"name": "Maria da Silva Souza",
"document": "12345678901",
"phone": "11999990000",
"email": "maria@empresa.com.br",
"externalCode": "cliente-1033"
}Eventos
Cadastre um endereço https e receba um POST assinado a cada evento da conta. É o que faz o seu sistema dar baixa sozinho.
/webhook-endpointswebhooks:writeurlhttps, 8–500simEndereço PÚBLICO que vai receber os POSTs. Só https; endereços internos ou privados são recusados; redirecionamentos não são seguidos.
descriptionstring ≤ 120nãoSó para você reconhecer depois (ex.: "ERP produção").
eventsstring[]nãoQuais eventos assinar. Em branco, assina todos. Valores: charge.paid, charge.expired, charge.cancelled, charge.refunded.
charge.paid — O provedor confirmou o pagamento. data.charge.status é PAID e paidAt está preenchido.charge.expired — A cobrança venceu sem pagamento.charge.cancelled — A cobrança foi baixada.charge.refunded — A cobrança foi devolvida (reservado; ver o status REFUNDED).secret (whsec_…) uma única vez. Perdeu? POST /webhook-endpoints/:id/rotate-secret.{
"url": "https://seusistema.com.br/webhooks/pagueo",
"description": "ERP produção",
"events": [
"charge.paid",
"charge.expired"
]
}POST com Content-Type: application/json, cabeçalho x-pagueo-signature: t=<unix>,v1=<hex>, mais x-pagueo-event-id, x-pagueo-event-type e x-pagueo-delivery-attempt. O data.charge tem a mesma forma de GET /charges/:id.
{
"id": "evt_charge_paid_cmtyv7fek000bpc018ulijzjg",
"type": "charge.paid",
"createdAt": "2026-09-12T21:05:10.000Z",
"data": {
"charge": {
"id": "cmtyv7fek000bpc018ulijzjg",
"status": "PAID",
"environment": "TEST",
"amountCents": 14990,
"currency": "BRL",
"description": "Pedido #1033",
"reference": null,
"externalId": "pedido-1033",
"pixCopyPaste": "00020126580014br.gov.bcb.pix…",
"qrCodeUrl": "data:image/png;base64,…",
"expiresAt": "2026-09-12T22:00:00.000Z",
"paidAt": "2026-09-12T21:05:08.000Z",
"feeCents": 178,
"netAmountCents": 14812,
"publicUrl": "https://pagueo.com.br/p/<token>",
"customer": null,
"chargeItem": null,
"installmentNumber": null,
"paymentPlanId": null,
"createdAt": "2026-09-12T21:00:00.000Z"
}
}
}# Cabeçalhos que chegam no seu endpoint:
x-pagueo-signature: t=1789246571,v1=9f2c… # HMAC-SHA256(secret, "<t>.<corpo cru>") em hex
x-pagueo-event-id: evt_charge_paid_cmtyv7fek000bpc018ulijzjg
x-pagueo-event-type: charge.paid
x-pagueo-delivery-attempt: 1
user-agent: PAGUEO-Webhooks/1
# Reproduzir a assinatura no terminal (corpo cru em body.json):
printf '%s.%s' "$T" "$(cat body.json)" | openssl dgst -sha256 -hmac "$PAGUEO_WEBHOOK_SECRET"HMAC-SHA256(secret, "<t>.<corpo cru>") em hex, comparado em tempo constante. Recuse se |agora − t| passar de 300 s. Reserializar o JSON muda espaços e derruba a assinatura.
Qualquer outra resposta, ou demora, vira reentrega com estas esperas em minutos: 0, 1, 5, 30, 120, 360, 1440 (7 tentativas em 24 h). Depois, DEAD_LETTER no histórico, com reenvio manual.
O mesmo evento redescoberto por dois caminhos (webhook do provedor e conciliação) gera um id só. Seu sistema recebe uma vez — ou a repetição com o mesmo id.
Endereços internos são recusados no cadastro e a entrega não segue redirect. Em TEST, simulate-payment dispara charge.paid igual à produção — é assim que se testa o endpoint.
GET /webhook-endpoints/deliveriesAs 50 entregas mais recentes, com as últimas 5 tentativas de cada: status HTTP, latência e erro. É a primeira coisa a olhar quando 'não chegou'.
POST /webhook-endpoints/deliveries/:id/resendReenvia agora — inclusive entregas já em DEAD_LETTER.
Saldo e saída de dinheiro
O saldo da conta, os Pix enviados e as contas pagas são consultáveis pela API. Enviar Pix, pedir saque e pagar conta exigem senha de transferência e código por e-mail — e por isso são operações do painel.
GET /charges/balance · /charges/transfers · /charges/bill-paymentsSaldo (balance:read); Pix enviados com status, quem recebeu e liquidação (transfers:read); contas pagas (bills:read).
POST /charges/transfers · /withdrawals · /bill-paymentsCom chave de API respondem 403 — por desenho. Uma chave vazada não pode tirar dinheiro da conta.
Enquanto um Pix enviado estiver PROCESSING, a consulta pergunta ao provedor e devolve o status real — e, depois da liquidação, o nome, o documento mascarado e a instituição de quem recebeu. Teto: 60 por minuto.
Comportamento
O corpo de erro é o do NestJS: statusCode, message e, em alguns casos, um code estável. Não existe envelope error.
// 401 — sem credencial ou chave inválida
{ "statusCode": 401, "message": "Sessao invalida.", "code": "SESSION_EXPIRED" }
// 400 — validação: message é uma LISTA
{ "statusCode": 400, "message": ["amountCents must be an integer number", "property foo should not exist"], "error": "Bad Request" }
// 403 — escopo
{ "statusCode": 403, "message": "Escopo charges:write não concedido.", "error": "Forbidden" }Campo faltando, tipo errado ou campo DESCONHECIDO — a API recusa propriedades que não existem no contrato. message vem como lista de frases, uma por problema. Corrija e repita com a mesma Idempotency-Key.
A descrição indica atividade que a PAGUEO não cobra (apostas, armas, drogas, pirâmide…). O corpo traz category. Não repita sem mudar o produto.
Falta o Authorization, ou a chave é inválida ou foi revogada. O code é o mesmo da sessão do painel: com chave de API não há o que renovar — confira a chave. Nunca tente outra conta.
"Escopo X não concedido": crie a chave com o escopo certo. Ou a rota só aceita sessão do painel (toda saída de dinheiro).
O id não é desta conta ou não existe. Rota inexistente responde { "message": "Cannot GET /api/v1/…", "statusCode": 404 }.
Idempotency-Key reutilizada com corpo diferente, ou a mesma requisição ainda em andamento; ou transição impossível (baixar cobrança paga, cliente com documento já cadastrado).
Espere e repita com backoff exponencial, mantendo a mesma Idempotency-Key para a mesma operação.
O provedor de liquidação não respondeu, ou a função está desligada na plataforma. A operação PODE ter sido recebida: consulte (GET) antes de criar de novo.
Texto seu, estável por operação (o id do pedido serve). Mesma chave + mesmo corpo em 24 h devolve a MESMA resposta sem criar de novo. Mesma chave + corpo diferente: 409. Chave ainda em andamento: 409 (a reserva expira em 5 min se o processo morrer). Em erro de rede, repita com a mesma chave em vez de gerar outra.
A cobrança pode ter sido criada. Antes de criar outra, repita com a mesma Idempotency-Key ou procure por externalId em GET /charges.
GET /public/*: 60 por minuto, por origem · GET /charges/transfers/:id: 60 por minuto, por usuário · POST /charges/:id/send-email: 30 por hora, por usuário · POST /charges/transfers/key-lookup: 30 por minuto, por usuário. Fora disso não há teto fixo — e mesmo assim trate 429 com backoff.
Mapa da API
Caminhos relativos a https://api.pagueo.com.br/api/v1. Pesquise por objetivo, método, escopo ou caminho. Listagens devolvem { data: [...] } com os 100 itens mais recentes.
/chargescharges:writeCria uma cobrança Pix imediata: QR, copia e cola e link público. Aceita Idempotency-Key./chargescharges:readAs 100 cobranças mais recentes da conta, da mais nova para a mais antiga. Sem paginação./charges/:idcharges:readUma cobrança. É ESTA consulta que decide se o pedido pode ser liberado (status PAID)./charges/:id/eventscharges:readLinha do tempo: cada transição de status, com origem, payload e horário./charges/:id/cancelcharges:writeBaixa uma cobrança CREATED ou PENDING, no provedor e aqui. Corpo opcional: { "reason" }./charges/:id/reconcilecharges:writePergunta ao provedor o status real agora (cobrança LIVE). Para quando o pagador diz que pagou e a cobrança segue PENDING./charges/:id/simulate-paymentcharges:writeSó TEST: marca a cobrança como paga pelo MESMO caminho da produção — tarifa, eventos e webhook charge.paid incluídos./charges/:id/send-emailcharges:readEnvia a cobrança por e-mail ao cliente. Corpo opcional: { "email" }. Teto: 30 por hora./public/charges/:tokenpúblicoO que a página de pagamento mostra (dados do pagador mascarados). Teto: 60 por minuto./charges/planscharges:writeCria o carnê inteiro: uma cobrança com vencimento por parcela, todas emitidas de uma vez. Aceita Idempotency-Key./charges/planscharges:readCarnês da conta, com as parcelas e a cobrança de cada uma./charges/plans/:id/cancelcharges:writeBaixa o carnê e todas as parcelas ainda abertas. Parcelas pagas ficam no histórico./public/plans/:tokenpúblicoA página do carnê: parcelas, vencimentos e status./customers?q=customers:readAté 100 clientes. q busca por nome e e-mail; com 3 ou mais dígitos, também por documento e telefone./customers/:idcustomers:readUm cliente./customerscustomers:writeCadastra um pagador. name, document e phone são obrigatórios./customers/:idcustomers:writeEdita o cadastro; todos os campos são opcionais aqui./webhook-endpointswebhooks:writeCadastra um endereço https. A resposta traz o secret (whsec_…) UMA única vez./webhook-endpointswebhooks:readEndpoints cadastrados, sem o segredo./webhook-endpoints/:idwebhooks:writeRemove o endpoint; entregas pendentes param./webhook-endpoints/:id/rotate-secretwebhooks:writeGira o segredo. O anterior para de valer no mesmo instante./webhook-endpoints/deliveries?endpointId=webhooks:readAs 50 entregas mais recentes, com as últimas 5 tentativas de cada (status HTTP, latência, erro)./webhook-endpoints/deliveries/:id/resendwebhooks:writeReenvia uma entrega agora — inclusive as que já viraram DEAD_LETTER./charges/balancebalance:readSaldo da conta no provedor./charges/withdrawals/balancetransfers:readSaldo disponível para sacar, já descontados os pedidos em aberto./charges/transferstransfers:readOs 100 Pix enviados mais recentes: status, quem recebeu, liquidação e motivo quando não realizado./charges/transfers/:idtransfers:readUm Pix enviado, conferido no banco na hora enquanto estiver PROCESSING. Teto: 60 por minuto./charges/withdrawalstransfers:readPedidos de saque da conta./charges/bill-paymentsbills:readContas (boletos) pagas com o saldo./charges/bill-payments/detailsbills:readLê um código de barras ou linha digitável: beneficiário, vencimento, valor final e se pode ser pago./charges/transfers · /charges/withdrawals · /charges/bill-paymentssessão do painelMovimentam dinheiro e exigem senha de transferência e código por e-mail. Chave de API responde 403 — por desenho, não por falta./auth/loginsessãoLogin do painel: senha e depois código por e-mail (/auth/verify-otp). Integração usa chave de API, nunca sessão./auth/mesessãoUsuário, conta ativa e permissões./tenantssessãoAs contas do usuário e a ativa. Uma chave de API pertence a UMA conta./api-keyssessãoCria uma chave (TEST ou LIVE) com escopos; o segredo aparece uma vez. Mais simples pelo painel, em Desenvolvedores./api-keys/:id/revoke · /api-keys/:id/rotatesessãoRevoga (para de valer, fica na lista) ou gira o segredo (o anterior para de valer)./api-keys/:idsessãoExclui a chave de vez, ativa ou revogada. A auditoria guarda nome, prefixo e ambiente.O contrato completo, com esquemas de requisição e resposta: https://api.pagueo.com.br/api/docs-json (JSON) · interface navegável.
Checklist de produção
Antes de trocar para a chave de produção, confira estes pontos no seu backend.
Variável de ambiente ou cofre. Nunca em frontend, aplicativo ou repositório. Vazou: revogue no painel e crie outra.
Assinatura validada sobre o corpo cru, tolerância de tempo, x-pagueo-event-id como chave de idempotência.
Nunca marque um pedido como pago a partir do navegador ou de um corpo que não veio assinado da PAGUEO.
Idempotency-Key estável por pedido; retry com a mesma chave; consulta antes de criar de novo.
Uma chave por sistema, só com os escopos que ele usa. Leitura não precisa de charges:write.
Guarde id, externalId, status e a hora de cada resposta: é o que permite conciliar e abrir um chamado com fatos.