Skip to main content
Existem dois jeitos de gerar um PIX, e a diferença não é estilo: eles aceitam recursos diferentes. Os dois aceitam valor solto. Não é que um seja “com produto” e o outro “sem”. Em /v1/payments o productId é opcional: sem ele, você manda valueCents e funciona igual. O que separa de verdade é o que cada um faz além disso.
Regra prática: quer só um valor, usa charges. É o caminho mais curto, e é o único que faz split. Vá pra payments quando precisar de catálogo, cripto ou assinatura.
Uma coisa que os dois aceitam: o campo supplier, que amarra a cobrança a um produto da sua loja pra entrega automática. Isso é independente de qual endpoint você escolheu.

Criando

Resposta
Em /v1/payments, se você mandar productId e valueCents ao mesmo tempo, o preço do produto vence. Produto em moeda diferente de BRL é convertido para real na hora da cobrança.Sem productId, o valueCents manda e a description vira o nome do pagamento (padrão "Pagamento" quando você não mandar nenhuma).
Cuidado pra não confundir dois campos com nome parecido:productId é produto de cobrança, criado por POST /v1/products. Ele define o preço.supplier.productId é produto da loja, no formato prod_xxx. Ele não define preço nenhum: serve pra entrega automática. Passar um no lugar do outro devolve 404.

Prazo de validade

expiresIn, em segundos. De 60 (um minuto) a 604800 (sete dias). Sem o campo, a cobrança vale 30 minutos, que é o que sempre valeu.
Valor fora da faixa devolve 400 em vez de cair no padrão. É de propósito: o erro mais provável é mandar minutos achando que o campo é em minutos, e expiresIn: 15 virar uma cobrança de quinze segundos seria bem pior que uma mensagem de erro. A resposta traz expiresAt com o instante exato do vencimento. Use esse valor no seu contador, em vez de somar o prazo no seu relógio: o que vale é a hora do servidor.
O prazo vale para PIX. Cobrança no cartão e assinatura têm ciclo próprio e ignoram o campo.

Valor mínimo

O piso da plataforma é R$ 0,80 (valueCents: 80), mas cada loja pode configurar um mínimo maior no painel. Quando o valor não passa, o erro 400 já diz qual é o mínimo daquela conta:
Vale ler esse número em vez de fixar 80 no seu código.

Ciclo de vida

1

pending

A cobrança existe e o brCode funciona. Dura o expiresIn que você escolheu, ou 30 minutos quando você não escolheu nenhum.
2

paid

O PIX caiu. O webhook sai nesse momento e o valor entra no seu saldo.
3

expired

Passou do prazo sem pagamento. Para tentar de novo, crie outra cobrança.
4

refunded / cancelled

Estorno ou cancelamento posterior. Vale conferir esses status antes de entregar algo de valor alto.
expired é o estado da cobrança, e não uma garantia de que o dinheiro não entra mais. Dependendo de qual instituição processa o PIX da sua loja, um pagamento feito depois do prazo ainda pode ser aceito pelo banco. Quando isso acontece a gente credita o valor e dispara o charge.paid normalmente, porque o cliente pagou de verdade e não receber o produto seria pior.Ou seja: expired não dispensa você de tratar o webhook. Se o seu fluxo não pode entregar depois do prazo, decida isso no seu handler comparando paidAt com expiresAt, e estorne se for o caso.

Reconciliando

Faça as duas coisas. Elas cobrem falhas diferentes.

Webhook: rápido, mas não confiável sozinho

A entrega é feita assim que o pagamento confirma, com reentrega automática em caso de falha. Ainda assim, a sua URL é pública e qualquer um pode chamá-la.Sempre valide a assinatura e deduplique pelo header X-Webhook-Id.
GET /v1/charges/{paymentId} e GET /v1/payments/{paymentId} devolvem o estado atual. Use antes de entregar algo caro, e como rede de segurança quando o webhook não chegou.
Se precisar mesmo, use intervalo de 5 segundos ou mais e pare no primeiro status final. O limite de 120 requisições por minuto vale para tudo somado.
Antes de liberar o produto, confira amountCents além do status. Um pagamento pago com valor menor que o esperado não deveria virar entrega.

Dados do pagador

No webhook charge.paid chegam campos que não existem na criação, porque vêm do banco: Servem para conciliação bancária e para responder disputa. CPF, telefone e endereço não são enviados em webhook.

Dividir o valor

Marketplace, comissão ou sociedade, resolvido no momento do pagamento.

Entregar sozinho

Chave ou conta liberada assim que o PIX confirma.