Skip to main content
POST
https://api.sandbox.wepayout.com.br
/
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>",
  "app": "<string>",
  "city_code": "<string>"
}
'
{
  "end_to_end_id": "string",
  "credit_party": {
    "name": "string",
    "key_type": "string",
    "key": "string"
  },
  "amount": 0,
  "is_amount_changeable": true
}

Decode QR Code

Decode third-parties PIX QR codes to make them payable at the create payment endpoint.

Request Body

emv
string
required
EMV from the QR Code.Example: 00020126580014BR.GOV.BCB.PIX...
app
string
Data of payment - optional parameter, should be used with QR Codes that have discount or fines.Format: <date>
city_code
string
City code.

Response

end_to_end_id
string
End to end ID - can be used for 30d after generation.
credit_party
object
Beneficiary data.
amount
number
Amount of the QR code.
is_amount_changeable
boolean
If true, the amount can be changed at payment endpoint.

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",
    "app": "2023-08-24",
    "city_code": "string"
  }'
{
  "end_to_end_id": "string",
  "credit_party": {
    "name": "string",
    "key_type": "string",
    "key": "string"
  },
  "amount": 0,
  "is_amount_changeable": true
}

Use Cases

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 using decoded data
  const payment = await createPayment({
    amount: qrData.amount * 100, // Convert to cents
    currency: 'BRL',
    country: 'BR',
    description: `Payment to ${qrData.credit_party.name}`,
    recipient: {
      name: qrData.credit_party.name,
      pix_key: qrData.credit_party.key,
      pix_key_type: qrData.credit_party.key_type
    },
    end_to_end_id: qrData.end_to_end_id
  });
  
  return 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 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({
    amount: finalAmount * 100,
    currency: 'BRL',
    country: 'BR',
    description: `Payment to ${qrData.credit_party.name}`,
    recipient: {
      name: qrData.credit_party.name,
      pix_key: qrData.credit_party.key,
      pix_key_type: qrData.credit_party.key_type
    },
    end_to_end_id: qrData.end_to_end_id
  });
  
  return payment;
}
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 can be used for 30 days after generation. Store it if you need to make the payment later.
Amount Validation: Always check is_amount_changeable before allowing users to modify the payment amount.
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 TypeDescriptionExample
CPFIndividual tax ID12345678900
CNPJCompany tax ID12345678000190
EMAILEmail address[email protected]
PHONEPhone number+5511999999999
EVPRandom key123e4567-e89b-12d3-a456-426614174000

Integration Flow