Decode QR Code
curl --request POST \
--url https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"emv": "<string>",
"city_code": "<string>",
"dpp": "<string>"
}
'import requests
url = "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode"
payload = {
"emv": "<string>",
"city_code": "<string>",
"dpp": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({emv: '<string>', city_code: '<string>', dpp: '<string>'})
};
fetch('https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'emv' => '<string>',
'city_code' => '<string>',
'dpp' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode"
payload := strings.NewReader("{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"end_to_end_id": "string",
"credit_party": {
"name": "string",
"key_type": "string",
"key": "string"
},
"amount": 0,
"is_amount_changeable": true
}
{
"message": "QR Code is invalid or expired"
}
{
"message": "QR Code doesn't have a valid status"
}
{
"message": "The given data was invalid.",
"errors": {
"emv": ["The emv field is required."]
}
}
{
"message": "Internal error"
}
Payout
Decode QR Code
Decode third-parties PIX QR codes to make them payable at the create payment endpoint
POST
/
v2
/
payout
/
qrcode-decode
Decode QR Code
curl --request POST \
--url https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"emv": "<string>",
"city_code": "<string>",
"dpp": "<string>"
}
'import requests
url = "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode"
payload = {
"emv": "<string>",
"city_code": "<string>",
"dpp": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({emv: '<string>', city_code: '<string>', dpp: '<string>'})
};
fetch('https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'emv' => '<string>',
'city_code' => '<string>',
'dpp' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode"
payload := strings.NewReader("{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"emv\": \"<string>\",\n \"city_code\": \"<string>\",\n \"dpp\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"end_to_end_id": "string",
"credit_party": {
"name": "string",
"key_type": "string",
"key": "string"
},
"amount": 0,
"is_amount_changeable": true
}
{
"message": "QR Code is invalid or expired"
}
{
"message": "QR Code doesn't have a valid status"
}
{
"message": "The given data was invalid.",
"errors": {
"emv": ["The emv field is required."]
}
}
{
"message": "Internal error"
}
Decode QR Code
Decode third-parties PIX QR codes to make them payable at the create payment endpoint.Request Body
string
required
EMV from the QR Code.Example:
00020126580014BR.GOV.BCB.PIX...string
City code.
string
Expected payment date - optional parameter, should be used with QR Codes that have discount or fines.Format:
YYYY-MM-DDResponse
string
End to end ID - send it in
qrcode.end_to_end_id at the create payment endpoint. It expires 5 minutes after the decode and can be used for a single payment.object
number
Amount of the QR code.
boolean
If true, the amount can be changed at payment endpoint. If false, the payment
amount must be equal to the QR code amount.Request Example
curl --request POST \
--url https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode \
--header 'Accept: application/json' \
--header 'Authorization: Bearer 123' \
--header 'Content-Type: application/json' \
--data '{
"emv": "00020126580014BR.GOV.BCB.PIX0136123e4567-e12b-12d1-a456-426655440000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***63041D3D",
"dpp": "2023-08-24",
"city_code": "string"
}'
async function decodeQRCode(emv, dpp = null, cityCode = null) {
const body = { emv };
if (dpp) body.dpp = dpp;
if (cityCode) body.city_code = cityCode;
const response = await fetch(
'https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer 123',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
return await response.json();
}
// Usage
const qrData = await decodeQRCode(
'00020126580014BR.GOV.BCB.PIX0136123e4567-e12b-12d1-a456-426655440000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***63041D3D'
);
console.log('QR Code decoded:', qrData);
console.log('Beneficiary:', qrData.credit_party.name);
console.log('Amount:', qrData.amount);
console.log('Can change amount:', qrData.is_amount_changeable);
import requests
def decode_qr_code(emv, dpp=None, city_code=None):
url = 'https://api.sandbox.wepayout.com.br/v2/payout/qrcode-decode'
headers = {
'Accept': 'application/json',
'Authorization': 'Bearer 123',
'Content-Type': 'application/json'
}
data = {'emv': emv}
if dpp:
data['dpp'] = dpp
if city_code:
data['city_code'] = city_code
response = requests.post(url, headers=headers, json=data)
return response.json()
# Usage
qr_data = decode_qr_code(
'00020126580014BR.GOV.BCB.PIX0136123e4567-e12b-12d1-a456-426655440000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***63041D3D'
)
print(f"QR Code decoded: {qr_data}")
print(f"Beneficiary: {qr_data['credit_party']['name']}")
print(f"Amount: {qr_data['amount']}")
print(f"Can change amount: {qr_data['is_amount_changeable']}")
{
"end_to_end_id": "string",
"credit_party": {
"name": "string",
"key_type": "string",
"key": "string"
},
"amount": 0,
"is_amount_changeable": true
}
{
"message": "QR Code is invalid or expired"
}
{
"message": "QR Code doesn't have a valid status"
}
{
"message": "The given data was invalid.",
"errors": {
"emv": ["The emv field is required."]
}
}
{
"message": "Internal error"
}
Use Cases
Pay Third-Party PIX QR Code
Pay Third-Party PIX QR Code
Decode and pay a PIX QR Code from another institution:
async function payThirdPartyQRCode(qrCodeEmv) {
// Step 1: Decode the QR Code
const qrData = await decodeQRCode(qrCodeEmv);
console.log(`Paying to: ${qrData.credit_party.name}`);
console.log(`Amount: R$ ${qrData.amount}`);
// Step 2: Create payment within 5 minutes using the decoded end_to_end_id
const payment = await createPayment({
payment_method: 'QRCODE',
amount: qrData.amount, // Decimal format, must match when is_amount_changeable is false
currency: 'BRL',
country: 'BR',
invoice: crypto.randomUUID(),
description: `Payment to ${qrData.credit_party.name}`,
qrcode: {
end_to_end_id: qrData.end_to_end_id
}
});
return payment;
}
Validate QR Code Before Payment
Validate QR Code Before Payment
Validate QR Code and show details to user before confirming:
async function validateAndShowQRCode(qrCodeEmv) {
try {
const qrData = await decodeQRCode(qrCodeEmv);
// Show details to user for confirmation
const confirmation = {
beneficiary: qrData.credit_party.name,
pixKey: qrData.credit_party.key,
keyType: qrData.credit_party.key_type,
amount: qrData.amount,
canChangeAmount: qrData.is_amount_changeable,
valid: true
};
return confirmation;
} catch (error) {
return {
valid: false,
error: 'Invalid QR Code'
};
}
}
// Usage
const validation = await validateAndShowQRCode(qrCodeEmv);
if (validation.valid) {
console.log('QR Code is valid');
console.log(`Pay R$ ${validation.amount} to ${validation.beneficiary}`);
// Show confirmation dialog to user
const confirmed = await showConfirmationDialog(validation);
if (confirmed) {
await payThirdPartyQRCode(qrCodeEmv);
}
} else {
console.error('Invalid QR Code');
}
Handle Dynamic Amount QR Codes
Handle Dynamic Amount QR Codes
Handle QR Codes where amount can be changed:
async function payDynamicAmountQRCode(qrCodeEmv, customAmount = null) {
const qrData = await decodeQRCode(qrCodeEmv);
let finalAmount = qrData.amount;
if (qrData.is_amount_changeable && customAmount) {
finalAmount = customAmount;
console.log(`Amount changed from R$ ${qrData.amount} to R$ ${customAmount}`);
} else if (!qrData.is_amount_changeable && customAmount) {
console.warn('Cannot change amount for this QR Code');
}
const payment = await createPayment({
payment_method: 'QRCODE',
amount: finalAmount,
currency: 'BRL',
country: 'BR',
invoice: crypto.randomUUID(),
description: `Payment to ${qrData.credit_party.name}`,
qrcode: {
end_to_end_id: qrData.end_to_end_id
}
});
return payment;
}
Bulk QR Code Processing
Bulk QR Code Processing
Process multiple QR Codes in batch:
async function processBulkQRCodes(qrCodes) {
const results = [];
for (const qr of qrCodes) {
try {
const qrData = await decodeQRCode(qr.emv);
results.push({
id: qr.id,
success: true,
beneficiary: qrData.credit_party.name,
amount: qrData.amount,
data: qrData
});
} catch (error) {
results.push({
id: qr.id,
success: false,
error: error.message
});
}
}
return results;
}
// Usage
const qrCodes = [
{ id: 'QR1', emv: 'emv-string-1' },
{ id: 'QR2', emv: 'emv-string-2' }
];
const results = await processBulkQRCodes(qrCodes);
console.log('Processed QR Codes:', results);
Best Practices
End-to-End ID Validity: The
end_to_end_id expires 5 minutes after the decode and can be used for a single payment. Do not store it to pay later: decode the QR Code again right before each payment. An expired or already used end_to_end_id returns 404 with the message End to End ID not found at the create payment endpoint.Amount Validation: Always check
is_amount_changeable before allowing users to modify the payment amount. When it is false, a payment with a different amount is rejected with 400.QR Code Status: Dynamic QR Codes are accepted only while the charge is active. Any other status returns
400 with the message QR Code doesn't have a valid status.Error Handling: Implement proper error handling for invalid QR Codes. Not all QR Codes are valid PIX codes.
QR Code Format: The EMV string should be the complete PIX QR Code string starting with “00020126…”.
PIX Key Types
Common PIX key types you might encounter:| Key Type | Description | Example |
|---|---|---|
| CPF | Individual tax ID | 12345678900 |
| CNPJ | Company tax ID | 12345678000190 |
| Email address | user@example.com | |
| PHONE | Phone number | +5511999999999 |
| EVP | Random key | 123e4567-e89b-12d3-a456-426614174000 |
Integration Flow
Related Resources
Create Payment
Create payment after decoding QR Code
Callback Payment
Receive payment notifications
Was this page helpful?

