Para gerar o Pix copia e cola por API, você cria uma cobrança e a API devolve o código pronto. Na API Pix da xFlow, um POST /api/v1/charges com o valor em centavos e os dados do cliente retorna 201 com o campo pix.copyPaste, que é o copia e cola, e pix.qrCodeBase64, que é o QR Code da mesma cobrança em imagem PNG. Você não monta o código, não calcula nada e não precisa de biblioteca de QR Code.
O que é o Pix copia e cola
O copia e cola existe porque nem sempre dá para escanear um QR Code. Quem compra pelo celular não consegue ler, com a câmera, uma imagem que está na própria tela. O Manual de Padrões para Iniciação do Pix, do Banco Central, descreve a funcionalidade como uma alternativa para esses casos: o recebedor oferece ao pagador uma forma de copiar a sequência de caracteres inteira do código, e o pagador cola no app do banco.
A regra central do manual é simples: o texto copiado tem que ser exatamente a mesma sequência que o leitor de QR Code leria na imagem. Por isso, copia e cola e QR Code são duas formas de apresentar o mesmo dado.
O que é o BR Code
O BR Code é o padrão usado para gerar QR Codes de pagamento no Brasil. Ele segue o padrão EMV para QR Codes no modo em que o recebedor apresenta o código ao pagador. Na prática, o código é uma sequência de campos, e cada campo tem três partes: um identificador de 2 dígitos, o tamanho do valor em 2 dígitos e o valor.
Os campos principais, conforme o manual do Banco Central:
| ID | Campo | O que guarda |
|---|---|---|
| 00 | Payload Format Indicator | A versão do formato, sempre 01 |
| 01 | Point of Initiation Method | 12 indica que o código não deve ser pago mais de uma vez |
| 26 | Merchant Account Information | O identificador br.gov.bcb.pix e os dados da conta Pix do recebedor: a chave, no QR estático, ou uma URL, no dinâmico |
| 52 | Merchant Category Code | Categoria do recebedor (0000 quando não informada) |
| 53 | Transaction Currency | Moeda: 986 é o real |
| 54 | Transaction Amount | O valor, quando o QR é de valor fixo |
| 58 | Country Code | País: BR |
| 59 | Merchant Name | Nome do recebedor |
| 60 | Merchant City | Cidade do recebedor |
| 62 | Additional Data Field | Dados adicionais, como o identificador da transação |
| 63 | CRC16 | Código de verificação calculado sobre todo o conteúdo |
O último campo explica por que você nunca deve editar o código. O CRC16 é calculado sobre todos os caracteres anteriores. Mudar um espaço, cortar o fim ou trocar a caixa de uma letra invalida o código, e o app do pagador recusa a leitura. A documentação da xFlow diz o mesmo: trate o pix.copyPaste como opaco e repasse sem alterar.
Como gerar o copia e cola na xFlow
O fluxo tem três passos:
- Gere a chave de API no painel, em Desenvolvedores > Chaves de API.
- Crie a cobrança com
POST /api/v1/charges. - Leia
pix.copyPastena resposta e mostre ao pagador.
Com cURL:
curl -X POST https://app.xflowpayments.com/api/v1/charges \
-u "pk_live_...:sk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-1234" \
-d '{
"amountCents": 1990,
"customer": {
"name": "Cliente Exemplo",
"email": "cliente@exemplo.com",
"document": "00000000000"
},
"description": "Pedido #1234",
"external_reference": "pedido-1234"
}'Com Node.js, no seu servidor:
const cred = Buffer.from(
process.env.XFLOW_PUBLIC_KEY + ":" + process.env.XFLOW_SECRET_KEY,
).toString("base64");
const res = await fetch("https://app.xflowpayments.com/api/v1/charges", {
method: "POST",
headers: {
Authorization: "Basic " + cred,
"Content-Type": "application/json",
"Idempotency-Key": "pedido-1234",
},
body: JSON.stringify({
amountCents: 1990,
customer: { name: "Cliente Exemplo", email: "cliente@exemplo.com", document: "00000000000" },
description: "Pedido #1234",
external_reference: "pedido-1234",
}),
});
const charge = await res.json();
console.log(charge.pix.copyPaste);Com PHP:
<?php
$ch = curl_init("https://app.xflowpayments.com/api/v1/charges");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_USERPWD => getenv("XFLOW_PUBLIC_KEY") . ":" . getenv("XFLOW_SECRET_KEY"),
CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Idempotency-Key: pedido-1234"],
CURLOPT_POSTFIELDS => json_encode([
"amountCents" => 1990,
"customer" => ["name" => "Cliente Exemplo", "email" => "cliente@exemplo.com", "document" => "00000000000"],
"description" => "Pedido #1234",
"external_reference" => "pedido-1234",
]),
CURLOPT_RETURNTRANSFER => true,
]);
$cobranca = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $cobranca["pix"]["copyPaste"];Mais detalhes por linguagem estão em API Pix com Node.js e API Pix com PHP.
O header Idempotency-Key protege contra duplicidade. Se a conexão cair e o seu sistema repetir a chamada com a mesma chave, a API devolve a mesma cobrança, com o mesmo copia e cola, em vez de gerar outro Pix.
Como mostrar o código ao cliente
Mostre o QR Code e, logo abaixo, um botão de copiar. No celular, o botão é o que o cliente vai usar.
<img id="qr" alt="QR Code Pix" width="240" height="240">
<button id="copiar" type="button">Copiar código Pix</button>
<script>
// charge = cobrança criada no seu servidor e enviada para a página
document.getElementById("qr").src = charge.pix.qrCodeBase64;
document.getElementById("copiar").addEventListener("click", async () => {
await navigator.clipboard.writeText(charge.pix.copyPaste);
});
</script>O pix.qrCodeBase64 já vem como data-URL (data:image/png;base64,...), então entra direto no src da imagem. Algumas dicas de experiência:
- Mostre o valor da cobrança perto do código, para o cliente conferir antes de pagar.
- Dê um retorno visual depois do clique, como "Código copiado".
- Se o código aparecer em texto, deixe a caixa só de leitura. Edição manual quebra o CRC.
Cuidados que evitam suporte
- Para mostrar de novo, busque pelo id. Se o cliente voltar à página, consulte
GET /api/v1/charges/{id}, que traz opix.copyPastee opix.qrCodeBase64. A listagem não traz esses campos. - Confirme o pagamento pelo servidor. O copia e cola não avisa nada. A confirmação vem pelo webhook
transaction.paidou pelo status da cobrança. Veja como montar o handler em webhook Pix. - No sandbox, o código não paga. Com chave
pk_test_, opix.copyPasteé um marcador não pagável. Simule comPOST /api/v1/test/charges/{id}/pay. - Use a sua referência. O
external_referencevolta em toda resposta e webhook e liga o código ao pedido no seu sistema.
O caminho inverso: pagar um copia e cola pela API
A mesma API aceita um copia e cola como destino de saque. Em POST /api/v1/transfers, envie qr_code com o código no lugar de pix_key e pix_key_type. Se o QR tiver valor fixo, amount é opcional e, se informado, precisa bater com o valor do QR. Se o valor for variável, amount é obrigatório. Nem todo provedor aceita saque por QR: quando não aceita, a resposta é 422 transfer_failed e nada é debitado. O fluxo completo está na API de saque Pix.
Para entender a diferença entre QR estático e dinâmico, leia QR Code Pix dinâmico por API. E para ver chaves, sandbox e logs num só lugar, acesse a página Desenvolvedores.
Perguntas frequentes
O Pix copia e cola e o QR Code são o mesmo código?
Sim. O copia e cola é a sequência de caracteres que o leitor de QR Code leria na imagem. Na xFlow, pix.copyPaste e pix.qrCodeBase64 representam a mesma cobrança.
Posso montar o copia e cola no meu sistema?
Na xFlow não é preciso. A API devolve o código pronto e a documentação pede que você o trate como opaco, repassando ao pagador sem alterar nenhum caractere.
Por que a listagem de cobranças não traz o copia e cola?
A listagem GET /api/v1/charges omite pix.copyPaste e pix.qrCodeBase64. Para mostrar o código de novo, consulte a cobrança pelo id com GET /api/v1/charges/{id}.
O copia e cola do ambiente de teste pode ser pago?
Não. Com chave pk_test_, o pix.copyPaste é um marcador não pagável. Para testar o fluxo de pagamento, use POST /api/v1/test/charges/{id}/pay.