Guia de QR Code Dinâmico
Este guia explica como gerar cobranças PIX utilizando QR Codes dinâmicos.
Visão Geral
O QR Code Dinâmico permite criar cobranças únicas com valor definido, data de expiração e informações do pagador. É ideal para:
- E-commerce - Pagamentos de pedidos
- Faturamento - Faturas e boletos
- Serviços - Pagamento por serviços prestados
Para um código reutilizável, que aceita vários pagamentos e não expira — placa no balcão, doação, mensalidade —, veja o Guia de QR Code Estático.
Fluxo de Integração
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Criar │ │ Cliente │ │ Webhook │
│ Cobrança │ ───► │ Paga QR │ ───► │ Recebido │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
Retorna EMV Confirma
e payload Pagamento
Passo 1: Criar uma Cobrança (QR Code Dinâmico)
Request
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/dynamic" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-12345" \
-d '{
"pixKey": "your-pix-key-here",
"value": 150.75,
"expirationDate": "2026-02-10T15:30:00Z",
"identifier": "order-12345",
"message": "Payment for order #12345"
}'
Parâmetros do Body
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
pixKey | string | Sim | Chave PIX da conta recebedora (deve estar cadastrada) |
value | number | Sim | Valor da cobrança em BRL, maior que zero. Máximo de 2 casas decimais (ex.: 150.75) |
expirationDate | datetime | Recomendado | Data/hora de expiração (RFC3339, ex.: 2026-02-10T15:30:00Z). Sem ela vale o default do liquidante (MT: 1 dia) |
identifier | string | Recomendado | Identificador único da cobrança (máximo 38 caracteres, charset [A-Za-z0-9._-]). Se omitido, a API gera um UUID sem hifens |
message | string | Não | Mensagem exibida ao pagador (máximo 140 caracteres) |
allowedPayerTaxNumber | string | Não | CPF/CNPJ específico autorizado a pagar |
Headers Importantes
| Header | Descrição |
|---|---|
Idempotency-Key | Identificador único para evitar cobranças duplicadas |
Resposta de Sucesso (201 Created)
{
"txid": "88a38a908a92441a98dac228ee1d9507",
"emv": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a908a92441a98dac228ee1d95075204000053039865802BR5912iDez Digital6004Lins62070503***63040BFF",
"type": "dynamic",
"status": "ACTIVE",
"value": 150.75,
"message": "Payment for order #12345",
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "{accountId}",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"allowChange": false,
"createdAt": "2026-02-10T12:00:00Z",
"expiresAt": "2026-02-10T15:30:00Z"
}
dataA resposta é um objeto plano (top-level). Não há envelope data nem
os campos statusCode/title/message. O código copia-e-cola está em
emv (não data.payload) e a chave em pixKey (não data.chave).
| Campo | Descrição |
|---|---|
emv | Código PIX Copia e Cola (string EMV). Renderize como QR. |
txid | ID interno da transação |
identifier | ID único da cobrança (use para consultas) |
status | Status da cobrança (ACTIVE = ativa) |
pixKey | Chave PIX utilizada na cobrança |
value | Valor da cobrança em BRL |
expiresAt | Data/hora de expiração (RFC3339) |
Passo 2: Exibir o QR Code
Usando PIX Copia e Cola
Exiba o campo emv para o cliente copiar:
<input type="text"
value="00020101021226790014br.gov.bcb.pix..."
readonly />
<button onclick="navigator.clipboard.writeText(this.previousElementSibling.value)">
Copy
</button>
Você pode gerar uma imagem de QR code a partir da string emv usando qualquer biblioteca de QR code (ex.: qrcode.js, python-qrcode).
Passo 3: Consultar Status da Cobrança
Consulte o status de uma cobrança pelo seu identifier:
O escopo qrcode.manage cobre criar, cancelar e consultar o QR: uma
credencial dedicada a cobranças enxerga se o QR foi pago sem precisar do escopo
de consulta geral (read), que dá acesso a saldo e extrato. Ver o
Guia de Autenticação.
Request
curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/lookup?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"
Status Possíveis
| Status | Descrição |
|---|---|
ACTIVE | Criado / aguardando |
AWAITING-PAYMENT | Aguardando pagamento |
PAID | Pagamento confirmado |
CANCELLED | Cancelado / rejeitado |
EXPIRED | Expirou sem pagamento |
UNKNOWN | Status do parceiro fora do mapeamento conhecido |
O status é retornado em MAIÚSCULAS (canônico). Uma devolução de PIX
não muda o status do QR para "refunded" — o QR permanece PAID e a
devolução é acompanhada pela transação/extrato.
Exemplos de Resposta por Status
Ativa (aguardando pagamento)
{
"txid": "88a38a908a92441a98dac228ee1d9507",
"emv": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a90...",
"type": "dynamic",
"status": "ACTIVE",
"value": 150.75,
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"createdAt": "2026-02-09T01:50:36Z",
"expiresAt": "2026-02-09T02:50:34Z"
}
Paga (pagamento confirmado)
{
"txid": "b091da7bba6a45d1a9f709daaba04e30",
"emv": "00020101021226790014br.gov.bcb.pix...",
"type": "dynamic",
"status": "PAID",
"value": 150.75,
"message": "Payment for order #12345",
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"allowChange": false,
"createdAt": "2026-02-05T22:08:02Z",
"expiresAt": "2026-02-05T23:08:00Z",
"paidAt": "2026-02-05T22:10:25Z",
"paidAmount": 150.75,
"endToEndId": "E303062942026020522100000005EXVX",
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankIspb": "30306294",
"bankName": "BANCO EXEMPLO",
"branch": "0020",
"account": "004912314"
},
"payee": {
"name": "iDez Digital",
"document": "12345678000190",
"bankIspb": "50871921",
"bankCode": "681"
}
}
Após uma devolução
Uma devolução de PIX (POST /v1/accounts/{accountId}/pix/out/refund) não
muda o status do QR para "refunded" — o QR permanece PAID. A devolução é uma
transação separada; acompanhe-a pelo extrato (GET .../statement) ou pelo
lookup de pagamento (GET .../pix/payments/lookup). O lookup de QR não
retorna campos de devolução.
Expirada (cobrança expirou)
{
"txid": "c1234567890abcdef1234567890abcde",
"emv": "00020101021226790014br.gov.bcb.pix...",
"type": "dynamic",
"status": "EXPIRED",
"value": 50.00,
"identifier": "order-99999",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"createdAt": "2026-02-01T10:00:00Z",
"expiresAt": "2026-02-01T10:30:00Z"
}
Referência de Campos
| Campo | Presente | Descrição |
|---|---|---|
txid | Sempre | ID interno da transação do QR code |
emv | Sempre | Código PIX Copia e Cola (BR Code) |
type | Sempre | Tipo do QR code (dynamic ou static) |
status | Sempre | Status atual (ACTIVE, AWAITING-PAYMENT, PAID, CANCELLED, EXPIRED, UNKNOWN) |
value | Sempre | Valor da cobrança em BRL |
identifier | Sempre | Seu identificador único da cobrança |
accountId | Sempre | Conta dona da cobrança |
pixKey | Quando disponível | Chave PIX da cobrança |
createdAt | Quando disponível | Data/hora de criação |
expiresAt | Quando disponível | Data de expiração (QR dinâmico) |
paidAt | Quando pago | Data/hora do pagamento |
paidAmount | Quando pago | Valor efetivamente pago em BRL |
endToEndId | Quando pago | Identificador E2E do PIX |
payer | Quando pago | Dados do pagador (name, document, bankIspb, bankName, branch, account, pixKey) |
payee | Quando disponível | Dados do recebedor (sua conta) |
Endpoint de Lookup
A busca é feita por identifier (alias retrocompat: txid):
curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/lookup?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"
O lookup é resolvido em tempo real no parceiro e retorna o objeto plano do
QR (status, valor, emv e — quando pago — payer/payee/endToEndId). Este
endpoint não aceita busca por qrcodeId/endToEndId e não retorna
dados de transação/fees/refunds.
Passo 4: Receber Webhook de Pagamento
Quando o cliente pagar, você receberá um webhook qrcode.paid no envelope
canônico (id, type, occurredAt, schemaVersion, data):
{
"id": "evt_987654321",
"type": "qrcode.paid",
"occurredAt": "2026-02-05T22:10:25.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"data": {
"endToEnd": "E303062942026020522100000005EXVX",
"type": "dynamic",
"identifier": "order-12345",
"qrcodeId": "b091da7bba6a45d1a9f709daaba04e30",
"amount": 150.75,
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankCode": "033",
"branch": "0001",
"accountNumber": "54321-0"
},
"payee": {
"name": "iDez Digital",
"document": "12345678000190"
},
"receivedAt": "2026-02-05T22:10:25.000Z"
}
}
Configure webhooks via POST /v1/webhooks com o tipo de evento qrcode.paid. Veja o Guia de Webhooks.
Passo 5: Cancelar uma Cobrança (Opcional)
Cancele uma cobrança pendente antes de ser paga:
curl -X DELETE "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"
Resposta (200 OK):
{
"identifier": "order-12345",
"status": "CANCELLED"
}
Passo 6: Métricas de QR Codes (opcional)
Não há endpoint de listagem de QR codes — a consulta é sempre por
identifier (lookup). Para métricas agregadas por dia (gerados/pagos/
devolvidos/valor), use:
curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-codes/stats?days=30" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"
Exemplo Completo: Integração E-commerce
#!/bin/bash
# Configuration
API_URL="https://tenant.api.corpx.com"
TOKEN="your_token_here"
TENANT_ID="tenant-yourcompany"
ACCOUNT_ID="your-account-id"
PIX_KEY="your-pix-key"
# 1. Create charge for order
ORDER_ID="order-$(date +%s)"
AMOUNT=299.90
EXPIRATION=$(date -u -v+30M +"%Y-%m-%dT%H:%M:%SZ") # 30 minutes
echo "Creating charge: $ORDER_ID for R\$$AMOUNT..."
response=$(curl -s -X POST "$API_URL/v1/accounts/$ACCOUNT_ID/pix/qr-code/dynamic" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $ORDER_ID" \
-d "{
\"pixKey\": \"$PIX_KEY\",
\"value\": $AMOUNT,
\"expirationDate\": \"$EXPIRATION\",
\"identifier\": \"$ORDER_ID\",
\"message\": \"Store Purchase - $ORDER_ID\"
}")
# 2. Extract information
IDENTIFIER=$(echo $response | jq -r '.identifier')
EMV=$(echo $response | jq -r '.emv')
echo "Charge created!"
echo "ID: $IDENTIFIER"
echo "PIX Copy and Paste: $EMV"
# 3. Poll for payment (alternative to webhook)
while true; do
sleep 10
status_response=$(curl -s "$API_URL/v1/accounts/$ACCOUNT_ID/pix/qr-code/lookup?identifier=$IDENTIFIER" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID")
current_status=$(echo $status_response | jq -r '.status')
if [ "$current_status" = "PAID" ]; then
paid_amount=$(echo $status_response | jq -r '.paidAmount')
e2e=$(echo $status_response | jq -r '.endToEndId')
echo "Payment confirmed! Amount: R\$$paid_amount, E2E: $e2e"
break
elif [ "$current_status" = "EXPIRED" ]; then
echo "Charge expired"
break
fi
echo "Awaiting payment... Status: $current_status"
done
Boas Práticas
- Use Idempotency Key - Sempre envie um identificador único por cobrança para evitar duplicatas
- Defina uma expiração adequada - 30 minutos para checkout, 24h para faturas
- Configure webhooks - Não dependa apenas de polling; use eventos
qrcode.paid - Todos os valores em BRL - Use no máximo 2 casas decimais (ex.:
150.75para R$150,75) - Trate a expiração - Notifique o cliente quando a cobrança expirar
- Armazene o identifier - Use-o para consultar status e conciliar pagamentos
Erros Comuns
Os erros vêm no formato { "errorCode": "...", "message": "..." }:
errorCode | HTTP | Causa | Solução |
|---|---|---|---|
missing_field | 400 | pixKey ausente ou value menor ou igual a zero | Envie uma chave cadastrada e um valor positivo em BRL |
invalid_identifier | 400 | identifier fora do charset [A-Za-z0-9._-] ou acima de 38 caracteres | Ajuste o identificador |
invalid_field | 400 | message acima de 140 caracteres ou com caracteres não aceitos | Encurte a mensagem |
invalid_payload | 400 | JSON malformado, expirationDate fora do RFC3339 ou no passado | Corrija o corpo da requisição |
missing_param | 400 | Lookup/cancelamento sem identifier na query | Informe ?identifier= (alias: txid) |
not_found | 404 | Cobrança não encontrada | Verifique o identifier e o accountId |
policy_denied | 422 | Uma regra de política recusou a criação da cobrança | Veja violations no corpo — Políticas e Regras |
Exemplo:
{
"errorCode": "missing_field",
"message": "pixKey and positive value are required"
}
Próximos Passos
- Guia de Cash Out - Fazer transferências PIX
- Guia de Devolução - Devolver pagamentos recebidos
- Webhooks - Configurar notificações