Pagar Pix copia e cola
Pague um Pix copia e cola, estático ou dinâmico, com o saldo da conta.
Pagar um Pix copia e cola funciona como um saque: mesma resposta, mesmo acompanhamento e os mesmos limites, com tarifa própria. O destino vem do código, e o valor também, quando o código fixa um.
Ler o Pix copia e cola
Opcional. POST /transactions/pix/decode, escopo PIX_DICT_READ, lê o código sem pagar e sem consultar o banco: não conta no limite de consultas e não diz quem é o titular.
curl -X POST https://api.hub.payzu.com.br/api/v1/transactions/pix/decode \
-H "Authorization: Bearer $PAYZU_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "brCode": "00020126400014br.gov.bcb.pix0118fulano@exemplo.com520400005303986540525.005802BR5913FULANO DE TAL6009SAO PAULO62140510PEDIDO482163048572" }'const res = await fetch('https://api.hub.payzu.com.br/api/v1/transactions/pix/decode', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
brCode: '00020126400014br.gov.bcb.pix0118fulano@exemplo.com520400005303986540525.005802BR5913FULANO DE TAL6009SAO PAULO62140510PEDIDO482163048572',
}),
});
const codigo = await res.json();{
"pixKey": "fulano@exemplo.com",
"url": null,
"amount": 2500,
"merchantName": "FULANO DE TAL",
"merchantCity": "SAO PAULO",
"txid": "PEDIDO4821",
"isDynamic": false,
"isAmountFixed": true
}isAmountFixed diz se o código já traz o valor. merchantName e merchantCity são o que quem gerou o código escreveu, sem verificação; para saber o titular, use Consultar destinatário. No código dinâmico, pixKey vem null e só url é preenchida; o titular e o valor saem da consulta de destinatário.
Pagar o Pix copia e cola
POST /transactions/pix/qr-payments, escopo WITHDRAW. Mande o código completo em brCode, como foi lido: a chave decodificada pelo seu sistema não é aceita no lugar dele. Mande amount, em centavos, só quando o código não fixa valor.
Gere uma Idempotency-Key para cada pagamento e, se repetir a chamada, mande a mesma.
IDEMPOTENCY_KEY=$(uuidgen)
curl -X POST https://api.hub.payzu.com.br/api/v1/transactions/pix/qr-payments \
-H "Authorization: Bearer $PAYZU_TOKEN" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{
"brCode": "00020126400014br.gov.bcb.pix0118fulano@exemplo.com520400005303986540525.005802BR5913FULANO DE TAL6009SAO PAULO62140510PEDIDO482163048572",
"comment": "Pedido 4821"
}'import crypto from 'node:crypto';
const idempotencyKey = crypto.randomUUID();
const res = await fetch('https://api.hub.payzu.com.br/api/v1/transactions/pix/qr-payments', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
'Idempotency-Key': idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
brCode: '00020126400014br.gov.bcb.pix0118fulano@exemplo.com520400005303986540525.005802BR5913FULANO DE TAL6009SAO PAULO62140510PEDIDO482163048572',
comment: 'Pedido 4821',
}),
});
const pagamento = await res.json();comment vai ao destinatário; sem ele, vai o nome do destinatário que está no código. callbackUrl recebe os webhooks deste pagamento e exige o segredo de callback. Todos os campos estão em Pagar Pix copia e cola.
Guardar o pagamento
A resposta (201) tem o formato do saque. Guarde o id.
{
"id": "hubp-20261005H2P6XC8VNM127431",
"status": "APPROVED",
"amount": 2500,
"serviceFee": 100,
"totalDebited": 2600,
"pixKey": "f***@exemplo.com",
"comment": "Pedido 4821",
"e2e": null,
"providerRejectedReason": null,
"callbackUrl": null,
"createdAt": "2026-10-05T14:40:11.002Z",
"sentAt": "2026-10-05T14:40:11.380Z",
"approvedAt": "2026-10-05T14:40:11.702Z",
"confirmedAt": null
}pixKey vem mascarada. APPROVED é pagamento a caminho, não dinheiro entregue.
Confirmar a entrega
O pagamento está entregue quando chega o webhook WITHDRAW_COMPLETED, com status: "CONFIRMED" e operation: "EXTERNAL_PAYMENT". Se falhar, chega WITHDRAW_FAILED, e o valor e a tarifa voltam ao saldo.
A consulta é a do saque: GET /transactions/withdraw/{withdrawId}.
Valor
| O código | amount enviado | Resultado |
|---|---|---|
| Fixa valor | Nenhum | Paga o valor do código. |
| Fixa valor | O mesmo | Paga. |
| Fixa valor | Diferente | 422 QR_AMOUNT_MISMATCH, com details.expected e details.requested. |
| Não fixa | Um valor | Paga o valor enviado. |
| Não fixa | Nenhum | 422 QR_AMOUNT_REQUIRED. |
Código dinâmico
O código dinâmico traz só um link, que a PayZu resolve no banco antes de pagar; nada sai do saldo antes disso. O corpo e a resposta são os mesmos.
- Se a resolução falha, a recusa usa os códigos da consulta de destinatário:
404PIX_DEST_PIX_KEY,503PIX_DEST_UNAVAILABLEouPIX_DEST_THROTTLED,502PIX_DEST_NOT_AUTHORIZED_AT_PROVIDER. - Se o valor impresso no código difere do valor que o banco devolve para ele, o pagamento é recusado com
422QR_AMOUNT_DISAGREES.
Pedido repetido
A Idempotency-Key segue as regras do saque, e a comparação também considera o código pago. No código dinâmico, o código é resolvido antes de conferir a repetição, então repetir pode trazer as recusas da resolução em vez do pagamento original.
Num 502, o pagamento pode ter saído. Repita com a mesma Idempotency-Key ou procure o pagamento em GET /transactions/withdraw antes de pagar de novo.
Tarifa e limites
- A tarifa é a de pagamento de Pix copia e cola,
externalPaymentnos limites. - O mínimo e o máximo são os do saque. O teto diário e o limite de requisições também, somados com ele.
- Código já pago ou vencido é recusado pelo banco.
- Código corrompido (
QR_CRC), fora do formato (QR_MALFORMED) ou que não é de Pix (QR_NOT_PIX) é recusado com400, na leitura e no pagamento.
As recusas, com o code, estão em Pagar Pix copia e cola.