Vender com PIX ou boleto

Cobre o cliente por PIX ou boleto, mostre o código de pagamento e confirme o pagamento pelo webhook.

Use este guia para cobrar uma vez por PIX ou por boleto. O cliente recebe um código, paga no banco dele e a PagPolar avisa você quando o pagamento for confirmado.

Para cobrar no cartão, veja Vender com cartão de crédito.

Com a chave de Homologação, a cobrança roda no ambiente de testes; com a chave de Produção, gera uma cobrança real.

Visão geral

O diagrama mostra o caminho completo de uma venda por PIX ou boleto. Os números batem com os passos abaixo.

Antes de começar

Separe o código da oferta

A cobrança precisa de uma oferta. Envie o código da oferta no campo offer_identifier. É o identifier que voltou quando você criou a oferta.

Na hora da cobrança, a API confere a oferta:

RegraSe não for cumprida
A oferta existe na sua conta e não é oculta.404 com Oferta não encontrada
A oferta está ativa.409 com Oferta inativa
A oferta não passou da data de expiração.409 com Oferta expirada
O meio de pagamento está ligado na oferta.409 com Método de pagamento PIX não habilitado para esta oferta (ou BOLETO)

Também dá para informar a oferta na hora, com o campo offer no lugar de offer_identifier. Nunca envie os dois. Veja Ofertas, planos e ofertas ocultas.

Crie a cobrança

Envie uma Idempotency-Key única para esta cobrança e grave no seu pedido antes de enviar. Veja Idempotência.

O exemplo cria um PIX:

curl -X POST "https://api.pagpolar.com/v1/payments/pix" \
  -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>" \
  -H "Idempotency-Key: 3c8e1f7a-2b4d-4e6f-9a1c-5d7e9f0a1b2c" \
  -H "Content-Type: application/json" \
  -d '{
    "offer_identifier": "<CODIGO_DA_OFERTA>",
    "external_reference": "PEDIDO-0002",
    "customer": {
      "name": "Maria Silva",
      "email": "cliente@exemplo.com",
      "document": "<CPF_DO_CLIENTE>",
      "phone": "<TELEFONE_DO_CLIENTE>"
    }
  }'
import { randomUUID } from 'node:crypto';

const idempotencyKey = randomUUID();

const response = await fetch('https://api.pagpolar.com/v1/payments/pix', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'Idempotency-Key': idempotencyKey,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    offer_identifier: '<CODIGO_DA_OFERTA>',
    external_reference: 'PEDIDO-0002',
    customer: {
      name: 'Maria Silva',
      email: 'cliente@exemplo.com',
      document: '<CPF_DO_CLIENTE>',
      phone: '<TELEFONE_DO_CLIENTE>',
    },
  }),
});

console.log(response.status, await response.json());

Para o boleto, o corpo é o mesmo. Só a rota muda: POST /payments/boleto.

Campos do corpo:

CampoObrigatórioO que é
offer_identifierSim, ou offerCódigo da oferta.
quantityNãoQuantidade de unidades. Padrão 1. Mais de 1 só se a oferta permitir.
external_referenceNãoCódigo do seu pedido, até 255 caracteres, como PEDIDO-0002. Serve para achar a venda depois. Não use o formato do código da venda. Veja Como a venda é encontrada.

Dados do cliente:

CampoObrigatórioO que é
customer.nameSimNome do cliente, até 255 caracteres.
customer.emailSimE-mail válido do cliente.
customer.documentSimCPF ou CNPJ do cliente, com ou sem pontuação. Veja o formato em Documento e telefone.
customer.phoneSimTelefone do cliente com DDD, com ou sem pontuação. Veja o formato em Documento e telefone.

Campos opcionais:

CampoObrigatórioO que é
addressNãoEndereço do cliente. Se enviar, street, number, neighborhood, city, state e postal_code são obrigatórios. complement é opcional.
affiliate_identifierNãoCódigo do afiliado que indicou a venda. Veja Vender com afiliado.
buyer_ipNãoIP do cliente. Se não enviar, a API usa o IP de quem chamou, ou seja, o do seu servidor.
buyer_user_agentNãoNavegador do cliente, até 512 caracteres. Se não enviar, a API usa o header User-Agent da sua requisição.

Não envie installments. No PIX e no boleto, o único valor aceito é 1.

Resposta 201 do PIX:

{
  "data": {
    "offer_identifier": "PPP1234567890",
    "transactions": ["a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"],
    "pix": {
      "qr_code": "00020126580014br.gov.bcb.pix0136a1b2c3d4-e5f6-4a7b-8c9d"
    }
  }
}

Resposta 201 do boleto:

{
  "data": {
    "offer_identifier": "PPP1234567890",
    "transactions": ["b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e"],
    "boleto": {
      "barcode": "34191.79001 01043.510047 91020.150008 1 96610000015000",
      "pdf_link": "https://boletos.pagpolar.com/a1b2c3d4.pdf"
    }
  }
}

As duas respostas estão resumidas. Contrato completo: POST /payments/pix e POST /payments/boleto.

Guarde transactions[0] junto do seu pedido. Ele é o id da venda. Você vai usar esse valor para ligar o webhook ao pedido e para consultar a venda.

Mostre o PIX ou o boleto ao cliente

PIX. Mostre pix.qr_code como código "copia e cola". Se quiser mostrar a imagem do QR Code, gere a imagem a partir desse texto.

  • O PIX é criado com validade de 5 horas.
  • A data e a hora exatas do vencimento aparecem em payment_details.qr_code_expires_at quando você consulta a venda (passo 5).

Boleto. Mostre o link boleto.pdf_link para o cliente abrir e pagar.

  • O boleto é criado com vencimento em 5 dias.
  • boleto.barcode traz o código do boleto como o gateway devolveu.

O código do boleto na consulta pode ser outro campo

Na consulta da venda, payment_details.billet_barcode vem de outro campo do gateway. O formato pode ser diferente do boleto.barcode da resposta de criação. Guarde os dois se for mostrar o código ao cliente mais tarde.

Espere o webhook

A PagPolar envia um POST para a URL do webhook da sua credencial a cada mudança importante. Autentique a requisição e descarte repetidos: veja Autenticar requisições e Processar sem duplicar.

EventoQuando chegaO que fazer
TRANSACTION_CREATEDLogo depois da resposta 201.Registre a venda. Não libere o produto.
TRANSACTION_PAIDO gateway confirmou o pagamento.Libere o que foi vendido.
TRANSACTION_EXPIREDO PIX ou o boleto venceu sem pagamento.Não libere. Se o cliente ainda quiser comprar, crie outra cobrança com outra Idempotency-Key.

Exemplo de TRANSACTION_PAID de um PIX (resumido):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "TRANSACTION_PAID",
  "creation_date": "2026-09-15T14:35:10.000Z",
  "version": "1.0.0",
  "data": {
    "transaction": {
      "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
      "identifier": "PPO9876543210",
      "status": "PAID",
      "payment_method": "PIX",
      "total_amount": "10.0000",
      "net_amount": 10,
      "paid_at": "2026-09-15T14:35:00.000Z"
    },
    "source": {
      "channel": "API",
      "api_credential_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
    }
  }
}

Use data.transaction.id, o mesmo valor de transactions[0], para achar o seu pedido: o webhook não traz a external_reference. Decida pelo data.transaction.status, que é o estado da venda no momento do envio. Veja todos os campos em Formato do evento.

Consulte a venda

Use a consulta quando precisar do status atual: o webhook atrasou, o seu servidor ficou fora do ar ou você quer conferir antes de liberar.

Envie o id que veio em transactions[0]:

curl "https://api.pagpolar.com/v1/sales/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
  -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>"
const response = await fetch(
  'https://api.pagpolar.com/v1/sales/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
  { headers: { Authorization: `Bearer ${accessToken}` } },
);

console.log(response.status, await response.json());

Resposta 200 (resumida):

{
  "data": {
    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "identifier": "PPO9876543210",
    "external_reference": "PEDIDO-0002",
    "status": "PAID",
    "payment_method": "PIX",
    "total_amount": 10,
    "paid_at": "2026-09-15T14:35:00.000Z",
    "payment_details": {
      "qr_code": "00020126580014br.gov.bcb.pix0136a1b2c3d4-e5f6-4a7b-8c9d",
      "qr_code_expires_at": "2026-09-15T19:30:00.000Z",
      "billet_barcode": null,
      "billet_link": null,
      "last_credit_card_digits": null
    }
  }
}

total_amount vem em reais: 10 na API e "10.0000", como texto, no webhook. Veja Valores nas respostas.

Você também pode consultar pelo código da venda (GET /sales/PPO9876543210) ou pela sua referência (GET /sales/PEDIDO-0002). GET /payments/{identifier} faz a mesma consulta. Veja Como a venda é encontrada.

Contrato completo: GET /sales/{identifier}.

Ciclo de vida

O diagrama mostra os status que uma venda por PIX ou boleto percorre neste fluxo.

StatusO que significaO que você faz
PROCESSINGO PIX ou o boleto foi gerado e espera o pagamento. É o status que você vê depois da resposta 201.Mostre o código ao cliente e espere.
PAIDO pagamento foi confirmado. paid_at fica preenchido.Libere o que foi vendido.
EXPIREDO prazo passou sem pagamento.Não libere. Crie outra cobrança se o cliente pedir.

O vencimento não é avisado na hora. A PagPolar confere os vencimentos a cada 3 horas. O PIX vence quando passa do qr_code_expires_at. O boleto vence 5 dias depois de criado. Por isso EXPIRED e o evento TRANSACTION_EXPIRED podem chegar algumas horas depois do prazo.

EXPIRED não é definitivo. Se o gateway confirmar um pagamento depois do vencimento, a venda passa para PAID. Se chegar TRANSACTION_PAID depois de TRANSACTION_EXPIRED, libere o produto.

Reembolso, cancelamento e chargeback estão em Ciclo de vida da venda.

Quando algo dá errado

Além dos erros comuns a todas as rotas, este fluxo pode responder:

PassoSituaçãoRespostaComo resolver
2offer_identifier e offer juntos, ou nenhum dos dois.400 com Envie offer_identifier ou offer, nunca os dois ou Envie offer_identifier ou offerEnvie só um.
2Campo obrigatório do cliente faltando.400 com O campo customer.email é obrigatório (muda conforme o campo)Complete o customer. A mensagem mostra um campo por vez.
2A oferta não passa numa das regras conferidas na cobrança: não encontrada, inativa, expirada, ou PIX ou boleto desligado.404 ou 409, conforme a tabela do passo 1Veja Regras conferidas em toda cobrança. Abaixo do valor mínimo, o meio fica desligado mesmo com true.
2quantity maior que o limite da oferta.400 com Quantidade acima do limite permitido para esta oferta (máximo N)Reduza a quantidade.
2quantity maior que 1 numa oferta que não aceita.400 com Esta oferta não permite compra de múltiplas unidadesEnvie quantity: 1 ou não envie o campo.
2installments diferente de 1.400 com Para o campo installments os valores permitidos são [1]Não envie o campo.
2O gateway não conseguiu gerar o PIX ou o boleto.400 com a mensagem do gateway, ou Erro ao criar pedido no gatewayVeja o aviso abaixo antes de repetir.
4O webhook não chegou.—Confira a URL e os eventos da credencial. Veja Entregas e retentativas. Enquanto isso, consulte a venda.
5Nenhuma venda com o valor enviado.404 com Venda não encontradaConfira o id, o código ou a external_reference.
5A external_reference tem o formato do código da venda e bate com o código de outra venda.200 com a venda erradaConsulte pelo id, ou por GET /sales?external_reference=, que só procura pela referência. Nas próximas cobranças, não use o formato do código na referência. Veja Como a venda é encontrada.

Erro na geração não garante que nada foi criado

Quando o gateway não gera o PIX ou o boleto, a resposta é um erro, mas a venda pode ficar registrada sem código de pagamento. Nesse caso, TRANSACTION_CREATED não é enviado. Mais tarde a venda vence e chega TRANSACTION_EXPIRED.

Antes de repetir, procure pela sua referência: GET /sales/PEDIDO-0002. Se a venda existir sem código de pagamento, crie uma nova cobrança com outra external_reference e outra Idempotency-Key. Veja Idempotência.

Confira no painel

A venda aparece em Vendas → Minhas vendas, com código, cliente, produto, valor recebido e status:

Tela Minhas vendas do painel, com a lista de vendas, o código, o cliente, o produto, o valor recebido e o status de cada venda

Ao abrir a venda, a tela Detalhes da venda mostra o status, os valores, o cliente e a forma de pagamento:

Tela Detalhes da venda com uma venda PIX paga, mostrando o resumo, o cliente, o endereço de entrega e a forma de pagamento Pix

Próximos passos