Pix

Referência

A cobrança imediata gera um QR Code Pix preenchendo apenas o valor, sem precisar cadastrar produto ou cliente antes. Este guia explica os campos aceitos, a resposta com o QR Code, a regra de COBV (Pix com vencimento) e como consultar o status depois.

Esta rota não tem idempotência. Duas chamadas com o mesmo corpo criam duas cobranças diferentes. O campo externalTxid identifica loja, caixa ou vendedor, não serve como chave de deduplicação. Controle duplicidade no seu lado ou use POST /v1/charges, que responde 409 DUPLICATE_CHARGE.

O que é a cobrança imediata

POST /v1/charges/pix (escopo charges/write) cria um QR Code de cobrança na sua própria conta. É a rota mais simples do grupo Pix: só amount é obrigatório.

A mesma rota também aceita um array split para dividir o valor com outras contas ValidaPay no momento do pagamento. Esse uso avançado está documentado em Split de pagamentos: Referência.

Campos do corpo

CampoObrigatórioDescrição
amountSimValor da cobrança em reais, com até duas casas decimais (ex.: 10.00). Múltiplo de R$0,01, mínimo R$0,01.
paymentMethodNãoSempre "pix" nesta rota. É o valor padrão quando o campo é omitido.
expirationNãoVencimento no formato YYYY-MM-DD. Não aceita data passada. Transforma a cobrança em COBV (Pix com vencimento).
externalTxidNãoIdentifica a loja, o caixa ou o vendedor responsável pela cobrança. Não é chave de idempotência.
metadataNãoObjeto livre para correlacionar com o seu pedido. Volta na resposta e no payload do webhook payment.success.
customer.documentNumberCondicionalCPF ou CNPJ do pagador. Ver regra de COBV abaixo.
customer.nameCondicionalExige expiration preenchido (COBV).
customer.cepCondicionalExige expiration preenchido (COBV).
customer.phoneNãoTelefone do pagador em E.164 (ex.: +5511999998888).
customer.emailNãoE-mail do pagador.
splitNãoDivisão automática do valor entre recebedores. Ver Split de pagamentos.

Resposta e QR Code

Os campos vêm na raiz da resposta, emv e qrCode, não aninhados sob pix. O qrCode já é uma data URL PNG pronta para exibir; não é preciso gerar a imagem a partir do emv no seu lado. Se você enviar metadata na criação, ele volta na resposta e no payload do webhook payment.success: é a forma recomendada de amarrar o pagamento ao seu pedido.

JSON
{
  "amount": 10.00,
  "externalTxid": "loja-01-caixa-03",
  "metadata": { "orderId": "pedido-1001" }
}
JSON
{
  "chargeId": "cha_1771511282731_9p1wo3tql",
  "emv": "00020101021226910014br.gov.bcb.pix2569qrcode.pix.celcoin.com.br/pixqrcode/v2/77e66fbad26b0b294eeb56c7c7c29f5204000053039865802BR5909ValidaPix6013Florianopolis62070503***6304BA13",
  "qrCode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
  "metadata": { "orderId": "pedido-1001" }
}

Cobrança com vencimento (COBV)

Enviar expiration transforma a cobrança em COBV (Pix com vencimento). A regra é condicional e em bloco: name e cep dentro de customer só são aceitos junto com expiration. E, havendo expiration com qualquer um dos três campos (documentNumber, name, cep) preenchido, o trio inteiro passa a ser obrigatório.

JSON
{
  "amount": 149.90,
  "expiration": "2026-12-31",
  "customer": {
    "documentNumber": "12345678901",
    "name": "Joao da Silva",
    "cep": "01310100"
  }
}
JSON
{
  "error": {
    "message": "name e cep do customer exigem expiration (COBV)",
    "code": "INVALID_DATA",
    "details": [
      {
        "message": "name e cep do customer exigem expiration (COBV)",
        "path": ["customer"]
      }
    ],
    "timestamp": "2026-02-18T22:19:31.013Z"
  }
}

O erro acima acontece quando name ou cep são enviados sem expiration.

Consultando o status

GET /v1/charges/:chargeId (escopo charges/read) retorna o estado atual da cobrança pelo chargeId recebido na criação.

JSON
{
  "chargeId": "cha_1771453171013_fp6iocaxb",
  "status": "PAID",
  "amount": 0.2,
  "paymentType": "PIX",
  "emv": "00020101021226910014br.gov.bcb.pix2569qrcode.pix.celcoin.com.br/pixqrcode/v2/bfc2182e025f97f17f843ae1fe8a895204000053039865802BR5909ValidaPix6013Florianopolis62070503***63049C4E",
  "paidAt": "2026-02-18T22:22:50.031Z",
  "createdAt": "2026-02-18T22:19:31.013Z"
}

Status possíveis

StatusSignificado
PENDINGCobrança criada, aguardando o pagamento do QR Code.
PAIDPix recebido e confirmado pelo banco.
EXPIREDO prazo de expiration (COBV) passou sem pagamento.
CANCELEDCobrança cancelada antes do pagamento.
REFUNDED / PARTIALLY_REFUNDEDTotal ou parcialmente devolvida depois de paga.

Devoluções mudam o status para REFUNDED ou PARTIALLY_REFUNDED. Veja Devoluções: Referência.

Webhook de confirmação

Quando o Pix é pago, a ValidaPay dispara payment.success (variante "Cobrança avulsa (Pix direto)") para a URL de webhook configurada, com chargeId, amount, paymentId (o End-to-End ID), paidAt, metadata e os dados do pagador em payer. Campos completos e exemplo de payload em Webhooks.

Erros comuns

codeStatusQuando acontece
INVALID_DATA400Corpo não passou na validação: amount ausente, expiration em formato ou data inválida, ou regra de COBV violada (customer incompleto).
CHARGE_NOT_FOUND404Na consulta de status: chargeId não existe, foi excluído, ou pertence a uma conta que a sua não pode acessar.
MISSING_CHARGE_ID400chargeId vazio na consulta de status.

Perguntas frequentes

externalTxid evita que eu gere a mesma cobrança duas vezes?
Não. A rota não tem idempotência e externalTxid serve só para identificar a loja, o caixa ou o vendedor responsável. Duas chamadas com o mesmo corpo criam duas cobranças distintas. Se precisar de proteção contra duplicidade, controle isso do seu lado ou use POST /v1/charges, que responde 409 DUPLICATE_CHARGE.
Posso enviar o nome e o CEP do pagador sem definir um vencimento?
Não. name e cep dentro de customer só são aceitos junto com expiration. Enviá-los sem expiration retorna 400 INVALID_DATA com a mensagem "name e cep do customer exigem expiration (COBV)".
O QR Code retornado já é uma imagem pronta para exibir?
Sim. O campo qrCode já vem como data URL de PNG em base64 (data:image/png;base64,...), pronto para um <img src>. Não é preciso gerar a imagem a partir do emv no seu lado.
Como sei que a cobrança foi paga sem depender só do webhook?
Faça polling em GET /v1/charges/:chargeId e verifique o campo status. O webhook payment.success é o caminho recomendado para não fazer polling, mas a consulta de status sempre reflete o estado mais atual.
O valor pode ser enviado em centavos?
Não. amount é sempre em reais, com até duas casas decimais (ex.: 10.00, nunca 1000).
Essa página foi útil?