Dynamic QR Code Guide
This guide explains how to generate PIX charges using dynamic QR Codes.
Overview
The Dynamic QR Code allows you to create unique charges with a defined amount, expiration date, and payer information. It is ideal for:
- E-commerce - Order payments
- Billing - Invoices and bills
- Services - Payment for rendered services
For a reusable code that accepts multiple payments and never expires — a sign on the counter, a donation, a monthly fee — see the Static QR Code Guide.
Integration Flow
Step 1: Create a Charge (Dynamic QR Code)
Request
Body Parameters
Important Headers
Success Response (201 Created)
No data envelope
The response is a flat object (top-level fields). There is no data
envelope and no statusCode/title/message fields. The copy-and-paste
code is in emv (not data.payload) and the key is in pixKey (not
data.chave).
Step 2: Display the QR Code
Using PIX Copy and Paste
Display the emv field for the customer to copy:
You can generate a QR code image from the emv string using any QR code library (e.g., qrcode.js, python-qrcode).
Step 3: Check Charge Status
Poll the status of a charge by its identifier:
The qrcode.manage scope covers creating, cancelling and reading the QR: a
credential dedicated to charges can see whether the QR was paid without the
general query scope (read), which also grants balance and statement. See the
Authentication Guide.
Request
Possible Statuses
The status is returned in UPPERCASE (canonical). A PIX refund does
not change the QR status to “refunded” — the QR stays PAID and the
refund is tracked via the transaction/statement.
Response Examples by Status
Active (awaiting payment)
Paid (payment confirmed)
After a refund
A PIX refund (POST /v1/accounts/{accountId}/pix/out/refund) does not
change the QR status to “refunded” — the QR stays PAID. The refund is a
separate transaction; track it via the statement (GET .../statement) or the
payment lookup (GET .../pix/payments/lookup). The QR lookup does not
return refund fields.
Expired (charge expired)
Field Reference
Lookup Endpoint (advanced search)
The lookup is done by identifier (backward-compat alias: txid):
The lookup is resolved in real time at the partner and returns the flat QR
object (status, value, emv and — when paid — payer/payee/endToEndId).
This endpoint does not accept qrcodeId/endToEndId and does not
return transaction/fees/refund data.
Step 4: Receive Payment Webhook
When the customer pays, you receive a qrcode.paid webhook in the canonical
envelope (id, type, occurredAt, schemaVersion, data):
Configure webhooks via POST /v1/webhooks with event type qrcode.paid. See the Webhooks Guide.
Step 5: Cancel a Charge (Optional)
Cancel a pending charge before it’s paid:
Response (200 OK):
Step 6: QR Code Metrics (optional)
There is no list endpoint for QR codes — lookups are always by
identifier. For per-day aggregated metrics (generated/paid/refunded/value),
use:
Full Example: E-commerce Integration
Best Practices
- Use Idempotency Key - Always send a unique identifier per charge to prevent duplicates
- Set appropriate expiration - 30 minutes for checkout, 24h for invoices
- Configure webhooks - Don’t rely solely on polling; use
qrcode.paidevents - All amounts in BRL - Use max 2 decimal places (e.g.,
150.75for R$150,75) - Handle expiration - Notify the customer when the charge expires
- Store the identifier - Use it to check status and reconcile payments
Common Errors
Errors come in the { "errorCode": "...", "message": "..." } shape:
Example:
Next Steps
- Cash Out Guide - Make PIX transfers
- Refund Guide - Reverse received payments
- Webhooks - Configure notifications