Skip to main content

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

Integration Flow

┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│ Create │ │ Customer │ │ Webhook │
│ Charge │ ───► │ Pays QR │ ───► │ Received │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
Returns EMV Confirms
and payload Payment

Step 1: Create a Charge (Dynamic QR Code)

Request

curl -X POST "https://api.corpxapi.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"
}'

Body Parameters

FieldTypeRequiredDescription
pixKeystringYesPIX key of the receiving account (must be registered)
valuenumberYesCharge amount in BRL. Max 2 decimal places (e.g., 150.75)
expirationDatedatetimeYesExpiration date/time (RFC3339, e.g., 2026-02-10T15:30:00Z)
identifierstringYesUnique charge identifier (max 35 characters)
messagestringNoMessage displayed to the payer (max 140 characters)
allowChangeValuebooleanNoAllows changing the amount at payment time (default: false)
allowedPayerTaxNumberstringNoSpecific CPF/CNPJ authorized to pay

Important Headers

HeaderDescription
Idempotency-KeyUnique identifier to prevent duplicate charges

Success Response (201 Created)

{
"statusCode": 201,
"title": "created",
"type": "dynamic_immediate",
"message": "QR code created successfully",
"data": {
"chave": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"identifier": "order-12345",
"location": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a908a92441a98dac228ee1d95075204000053039865802BR5912iDez Digital6004Lins62070503***63040BFF",
"payload": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a908a92441a98dac228ee1d95075204000053039865802BR5912iDez Digital6004Lins62070503***63040BFF",
"status": "ATIVA",
"txid": "88a38a908a92441a98dac228ee1d9507"
}
}
FieldDescription
data.chavePIX key used for the charge
data.identifierUnique charge ID (use for lookups)
data.payloadPIX Copy and Paste code (EMV string)
data.locationSame as payload - the EMV string for the QR code
data.statusCharge status (ATIVA = active)
data.txidInternal transaction ID

Step 2: Display the QR Code

Using PIX Copy and Paste

Display the payload field for the customer to copy:

<input type="text" 
value="00020101021226790014br.gov.bcb.pix..."
readonly />
<button onclick="navigator.clipboard.writeText(this.previousElementSibling.value)">
Copy
</button>
tip

You can generate a QR code image from the payload 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:

Request

curl -X GET "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-code?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

Possible Statuses

StatusDescription
activeAwaiting payment
paidPayment confirmed
refundedPayment was refunded (you returned the money)
expiredCharge expired without payment
cancelledCharge cancelled manually

Response Examples by Status

Active (awaiting payment)

{
"txid": "88a38a908a92441a98dac228ee1d9507",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"value": 150.75,
"status": "active",
"type": "dynamic",
"createdAt": "2026-02-09T01:50:36Z",
"expiresAt": "2026-02-09T02:50:34Z",
"description": "Payment for order #12345",
"emv": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a90...",
"location": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a90...",
"reconciled": false
}
{
"txid": "b091da7bba6a45d1a9f709daaba04e30",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"value": 150.75,
"status": "paid",
"type": "dynamic",
"createdAt": "2026-02-05T22:08:02Z",
"expiresAt": "2026-02-05T23:08:00Z",
"description": "Payment for order #12345",
"emv": "00020101021226790014br.gov.bcb.pix...",
"location": "00020101021226790014br.gov.bcb.pix...",
"paidAt": "2026-02-05T22:10:25.055",
"paidAmount": 150.75,
"endToEndId": "E303062942026020522100000005EXVX",
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankCode": "30306294",
"branch": "0020",
"account": "004912314"
},
"reconciled": true,
"reconciledAt": "2026-02-05T22:10:25Z",
"transactionId": "e094058f-de94-40a8-99a0-cdd5cb4cc832"
}

Refunded (you returned the payment)

When you refund a received payment using POST /v1/accounts/{accountId}/pix/out/refund, the QR code status changes to refunded:

{
"txid": "b091da7bba6a45d1a9f709daaba04e30",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"value": 150.75,
"status": "refunded",
"type": "dynamic",
"createdAt": "2026-02-05T22:08:02Z",
"paidAt": "2026-02-05T22:10:25.055",
"paidAmount": 150.75,
"endToEndId": "E303062942026020522100000005EXVX",
"payer": {
"name": "John Smith",
"document": "12345678901"
},
"reconciled": true,
"reconciledAt": "2026-02-05T22:10:25Z",
"transactionId": "e094058f-de94-40a8-99a0-cdd5cb4cc832",
"refundEndToEndId": "D303062942026020613020000005Ft76",
"refundedAt": "2026-02-06T13:02:16Z",
"refundAmount": 150.75,
"refunds": [
{
"id": "refund-001",
"amount": 150.75,
"status": "DEVOLVIDO",
"endToEndId": "D303062942026020613020000005Ft76",
"requestedAt": "2026-02-06T13:02:00Z",
"processedAt": "2026-02-06T13:02:16Z"
}
],
"totalRefundAmount": 150.75
}

Expired (charge expired)

{
"txid": "c1234567890abcdef1234567890abcde",
"identifier": "order-99999",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"value": 50.00,
"status": "expired",
"type": "dynamic",
"createdAt": "2026-02-01T10:00:00Z",
"expiresAt": "2026-02-01T10:30:00Z",
"emv": "00020101021226790014br.gov.bcb.pix...",
"reconciled": false
}

Field Reference

FieldPresentDescription
txidAlwaysInternal QR code transaction ID
identifierAlwaysYour unique charge identifier
valueAlwaysCharge amount in BRL
statusAlwaysCurrent status (active, paid, refunded, expired, cancelled)
typeAlwaysQR code type (dynamic or static)
emvAlwaysPIX Copy and Paste code
expiresAtAlwaysCharge expiration date
reconciledAlwaysWhether linked to a statement transaction
paidAtWhen paidPayment timestamp
paidAmountWhen paidAmount actually paid in BRL
endToEndIdWhen paidPIX E2E identifier (unique in PIX system)
payerWhen paidPayer info (name, document, bankCode, branch, account)
transactionIdWhen reconciledTransaction ID for statement lookup
refundEndToEndIdWhen refundedRefund E2E identifier
refundedAtWhen refundedRefund timestamp
refundAmountWhen refundedAmount refunded in BRL
refundsWhen refundedArray of refund details (supports partial refunds)
totalRefundAmountWhen refundedTotal of all refunds in BRL

In addition to searching by identifier, you can use the dedicated lookup endpoint that supports qrcodeId (txid) or endToEndId:

# Search by identifier
curl -X GET "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-code/lookup?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

# Search by txid (qrcodeId)
curl -X GET "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-code/lookup?qrcodeId=5774a2eb0e2f40ac" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

# Search by E2E (when paid)
curl -X GET "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-code/lookup?endToEndId=E22896431..." \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"
info

Only one parameter can be sent at a time. The lookup returns enriched details including transaction data, payer, fees and related refunds.

Step 4: Receive Payment Webhook

When the customer pays, you receive a pix.in.completed webhook with method: QR_CODE_DYNAMIC:

{
"event": "qrcode.paid",
"timestamp": "2026-02-05T22:10:25Z",
"tenantId": "tenant-yourcompany",
"data": {
"identifier": "order-12345",
"txid": "b091da7bba6a45d1a9f709daaba04e30",
"status": "PAID",
"value": 150.75,
"paidAmount": 150.75,
"endToEndId": "E303062942026020522100000005EXVX",
"payer": {
"name": "John Smith",
"document": "12345678901"
}
}
}
tip

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:

curl -X DELETE "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-code?identifier=order-12345" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

Step 6: List All QR Codes

List QR codes for an account, optionally filtered by status:

curl -X GET "https://api.corpxapi.com/v1/accounts/{accountId}/pix/qr-codes?status=PAID" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

Response

{
"items": [
{
"txid": "8ab8a37b2e274c8dae51128a379c909a",
"identifier": "order-67890",
"status": "paid",
"value": 50.00,
"paidAmount": 50.00,
"endToEndId": "E303062942026020522130000005EYaT",
"reconciled": true,
"createdAt": "2026-02-05T22:09:32Z"
}
],
"count": 1
}

Full Example: E-commerce Integration

#!/bin/bash

# Configuration
API_URL="https://api.corpxapi.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 '.data.identifier')
PAYLOAD=$(echo $response | jq -r '.data.payload')

echo "Charge created!"
echo "ID: $IDENTIFIER"
echo "PIX Copy and Paste: $PAYLOAD"

# 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?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

Best Practices

  1. Use Idempotency Key - Always send a unique identifier per charge to prevent duplicates
  2. Set appropriate expiration - 30 minutes for checkout, 24h for invoices
  3. Configure webhooks - Don't rely solely on polling; use qrcode.paid events
  4. All amounts in BRL - Use max 2 decimal places (e.g., 150.75 for R$150,75)
  5. Handle expiration - Notify the customer when the charge expires
  6. Store the identifier - Use it to check status and reconcile payments

Common Errors

ErrorCauseSolution
400 - pixKey is requiredMissing PIX keyInclude a valid PIX key registered for the account
400 - value must be greater than zeroInvalid amountSend a positive amount in BRL
400 - value has too many decimal placesMore than 2 decimalsUse max 2 decimal places (e.g., 150.75)
400 - identifier is requiredMissing identifierProvide a unique charge identifier
400 - expirationDate must be a valid RFC3339 timestampInvalid dateUse RFC3339 format (e.g., 2026-02-10T15:30:00Z)
404 - QR code not foundCharge not foundCheck the identifier and accountId

Next Steps