O QR Code do PIX nada mais é que um payload de texto estruturado segundo o padrão EMV BR Code (BR Code = subset brasileiro do EMV QR Code Specification), codificado num QR. Você pode gerar o payload via API do gateway, e renderizar o QR no front-end, no back-end ou usar a imagem que a gente já devolve.

Dinâmico vs estático

  • Estático: um único QR fixo, sem valor pré-definido, reutilizável. Bom pra "PIX pra doação" ou "PIX da padaria do João".
  • Dinâmico: gerado pra um pagamento específico, com valor e identificador único (TXID). É o que faz sentido no checkout. Expira após o tempo configurado.

Na Vanilla Pag, o endpoint POST /v1/payment-transaction/create sempre devolve um QR dinâmico. Detalhes na documentação.

O que você recebe da API

{
  "id": "tx_2sQfgT...",
  "qr_code": "00020126410014BR.GOV.BCB.PIX...6304F248",
  "qr_code_image": "https://vanillapag.com/qr/tx_2sQfgT.png"
}

Dois caminhos: usar a qr_code_image direto numa <img> (mais simples, 1 request a menos) ou pegar a string qr_code e gerar o QR localmente em JS / PHP / Python pra controle total do estilo (cor, logo no centro, etc.).

Renderizar em JavaScript

// usando qrcode (npm install qrcode)
import QRCode from 'qrcode';

const dataUrl = await QRCode.toDataURL(payload, {
  width: 320,
  margin: 1,
  color: { dark: '#000000', light: '#ffffff' }
});
document.getElementById('pix-qr').src = dataUrl;

Renderizar em PHP

// composer require endroid/qr-code
$qr = (new \Endroid\QrCode\QrCode($payload))
  ->setSize(320)
  ->setMargin(8);
$writer = new \Endroid\QrCode\Writer\PngWriter();
header('Content-Type: image/png');
echo $writer->write($qr)->getString();

Renderizar em Python

# pip install qrcode[pil]
import qrcode
img = qrcode.make(payload, box_size=8, border=2)
img.save('pix.png')

UX no checkout

Mostre o QR e o botão "Copiar código" lado a lado. Cliente em mobile prefere colar; cliente em desktop prefere escanear com o celular. Mostrar os dois aumenta conversão.