Pular para o conteúdo principal

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

CampoTipoObrigatórioDescrição
pixKeystringSimChave PIX da conta recebedora (deve estar cadastrada)
valuenumberSimValor da cobrança em BRL, maior que zero. Máximo de 2 casas decimais (ex.: 150.75)
expirationDatedatetimeRecomendadoData/hora de expiração (RFC3339, ex.: 2026-02-10T15:30:00Z). Sem ela vale o default do liquidante (MT: 1 dia)
identifierstringRecomendadoIdentificador único da cobrança (máximo 38 caracteres, charset [A-Za-z0-9._-]). Se omitido, a API gera um UUID sem hifens
messagestringNãoMensagem exibida ao pagador (máximo 140 caracteres)
allowedPayerTaxNumberstringNãoCPF/CNPJ específico autorizado a pagar

Headers Importantes

HeaderDescrição
Idempotency-KeyIdentificador ú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"
}
Sem envelope data

A 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).

CampoDescrição
emvCódigo PIX Copia e Cola (string EMV). Renderize como QR.
txidID interno da transação
identifierID único da cobrança (use para consultas)
statusStatus da cobrança (ACTIVE = ativa)
pixKeyChave PIX utilizada na cobrança
valueValor da cobrança em BRL
expiresAtData/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>
dica

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:

Credencial só de QR code

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

StatusDescrição
ACTIVECriado / aguardando
AWAITING-PAYMENTAguardando pagamento
PAIDPagamento confirmado
CANCELLEDCancelado / rejeitado
EXPIREDExpirou sem pagamento
UNKNOWNStatus do parceiro fora do mapeamento conhecido
Valores em MAIÚSCULAS

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

CampoPresenteDescrição
txidSempreID interno da transação do QR code
emvSempreCódigo PIX Copia e Cola (BR Code)
typeSempreTipo do QR code (dynamic ou static)
statusSempreStatus atual (ACTIVE, AWAITING-PAYMENT, PAID, CANCELLED, EXPIRED, UNKNOWN)
valueSempreValor da cobrança em BRL
identifierSempreSeu identificador único da cobrança
accountIdSempreConta dona da cobrança
pixKeyQuando disponívelChave PIX da cobrança
createdAtQuando disponívelData/hora de criação
expiresAtQuando disponívelData de expiração (QR dinâmico)
paidAtQuando pagoData/hora do pagamento
paidAmountQuando pagoValor efetivamente pago em BRL
endToEndIdQuando pagoIdentificador E2E do PIX
payerQuando pagoDados do pagador (name, document, bankIspb, bankName, branch, account, pixKey)
payeeQuando disponívelDados 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}"
informação

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"
}
}
dica

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

  1. Use Idempotency Key - Sempre envie um identificador único por cobrança para evitar duplicatas
  2. Defina uma expiração adequada - 30 minutos para checkout, 24h para faturas
  3. Configure webhooks - Não dependa apenas de polling; use eventos qrcode.paid
  4. Todos os valores em BRL - Use no máximo 2 casas decimais (ex.: 150.75 para R$150,75)
  5. Trate a expiração - Notifique o cliente quando a cobrança expirar
  6. Armazene o identifier - Use-o para consultar status e conciliar pagamentos

Erros Comuns

Os erros vêm no formato { "errorCode": "...", "message": "..." }:

errorCodeHTTPCausaSolução
missing_field400pixKey ausente ou value menor ou igual a zeroEnvie uma chave cadastrada e um valor positivo em BRL
invalid_identifier400identifier fora do charset [A-Za-z0-9._-] ou acima de 38 caracteresAjuste o identificador
invalid_field400message acima de 140 caracteres ou com caracteres não aceitosEncurte a mensagem
invalid_payload400JSON malformado, expirationDate fora do RFC3339 ou no passadoCorrija o corpo da requisição
missing_param400Lookup/cancelamento sem identifier na queryInforme ?identifier= (alias: txid)
not_found404Cobrança não encontradaVerifique o identifier e o accountId
policy_denied422Uma regra de política recusou a criação da cobrançaVeja violations no corpo — Políticas e Regras

Exemplo:

{
"errorCode": "missing_field",
"message": "pixKey and positive value are required"
}

Próximos Passos