Para receber Pix num aplicativo, o app não fala com a API de pagamento: ele fala com o seu servidor, e o servidor fala com a xFlow. A API Pix da xFlow devolve a cobrança com o copia e cola e o QR Code prontos e avisa o seu servidor por webhook assinado quando o pagamento é confirmado. O app só mostra o código e muda de tela.
A arquitetura certa: app, servidor, API
| Passo | Quem faz | O quê |
|---|---|---|
| 1 | App | Pede o pagamento do pedido ao seu servidor |
| 2 | Seu servidor | Chama POST /api/v1/charges com o segredo da chave |
| 3 | Seu servidor | Devolve ao app só pix.copyPaste, pix.qrCodeBase64 e o id do pedido |
| 4 | xFlow | Confere o pagamento na adquirente e envia transaction.paid ao servidor |
| 5 | Seu servidor | Valida a assinatura, atualiza o pedido e avisa o app |
Dois motivos tornam o servidor obrigatório. O primeiro é o segredo: um pacote de aplicativo pode ser inspecionado, e o sk_live_ dentro dele vira credencial de qualquer um. O segundo é a allowlist de IP: ela limita as chamadas aos IPs dos seus servidores e recusa com 401 o que vem de fora, inclusive de celulares. Os controles estão na página de segurança.
No celular, o copia e cola vem primeiro
Quem paga pelo celular não consegue ler um QR Code que está na tela do próprio celular. No app, o botão "Copiar código Pix" é o caminho principal. O QR Code serve para quem abre o pagamento num computador ou noutro aparelho. O guia de Pix copia e cola por API explica o formato do código e como exibi-lo sem alterar nada.
Conexão instável sem cobrança em dobro
A conexão do celular cai no meio da requisição. Se o app repetir o pedido e o servidor repetir a chamada, sem proteção você gera dois Pix. Crie a Idempotency-Key quando o pedido nasce e use a mesma em toda repetição:
// No seu servidor: a chave nasce com o pedido e é reaproveitada em qualquer retry
const res = await fetch("https://app.xflowpayments.com/api/v1/charges", {
method: "POST",
headers: {
Authorization: "Basic " + Buffer.from(`${process.env.XFLOW_PUBLIC_KEY}:${process.env.XFLOW_SECRET_KEY}`).toString("base64"),
"Content-Type": "application/json",
"Idempotency-Key": `app-pedido-${pedido.id}`,
},
body: JSON.stringify({
amountCents: pedido.totalCentavos,
customer: { name: pedido.nome, email: pedido.email, document: pedido.cpf },
external_reference: `pedido-${pedido.id}`,
}),
});Na repetição com a mesma chave e o mesmo corpo, a API devolve a mesma cobrança. Com a mesma chave e outro corpo, responde 409 idempotency_conflict.
Confirmação e atualização da tela
O webhook transaction.paid chega ao seu servidor, nunca ao app. Depois de validar a assinatura e conferir livemode, o servidor marca o pedido como pago e avisa o aplicativo por notificação ou pela consulta que o app faz ao seu back-end. Se o webhook atrasar, o servidor confere com GET /api/v1/charges/{id}. O handler completo está em webhook Pix.
Se o usuário demorar, a cobrança pode passar a expired. Não há webhook de expiração: confira o status quando o usuário voltar à tela e gere uma cobrança nova se for o caso.
Repasses para quem usa a plataforma
Plataformas que pagam usuários, como prestadores, parceiros ou criadores, usam o saque Pix da API. POST /api/v1/transfers envia o valor para uma chave Pix (CPF, CNPJ, e-mail, telefone ou chave aleatória) ou para um QR Code, com Idempotency-Key por repasse. Os eventos withdrawal.completed e withdrawal.failed informam o resultado. Os detalhes estão em API de saque Pix. Se a divisão acontece na própria venda e o recebedor tem conta na xFlow, o split da cobrança faz a separação na confirmação do pagamento.
Teste antes de publicar o app
Crie uma chave de teste no painel, mesmo com o cadastro em análise. O servidor usa os mesmos endpoints, a cobrança não chama adquirente e o copia e cola de teste não é pagável. Simule o pagamento com POST /api/v1/test/charges/{id}/pay e confira se o app muda de tela. Saque e split não funcionam com chave de teste.
A API trabalha com Pix. Cartão e checkout hospedado ainda não estão disponíveis na API.
Perguntas frequentes
Posso chamar a API Pix direto do aplicativo?
Não. A chamada usa o segredo da chave (sk_live_), que não pode ir para dentro do app. O aplicativo pede o pagamento ao seu servidor, e o servidor chama a API da xFlow.
Como o app fica sabendo que o Pix foi pago?
O webhook transaction.paid chega no seu servidor, assinado com HMAC-SHA256. O servidor valida a assinatura, atualiza o pedido e avisa o app, por notificação ou pela consulta que o app faz ao seu back-end.
Dá para pagar usuários da plataforma por Pix?
Sim, com o saque Pix da API: POST /api/v1/transfers envia o valor do saldo da sua conta para uma chave Pix ou um QR Code. Use uma Idempotency-Key por repasse para não pagar duas vezes.
Tem ambiente de teste para o app?
Sim. Com chaves pk_test_ e sk_test_, o seu servidor usa os mesmos endpoints, simula o pagamento e recebe o webhook com livemode: false. Saque e split não estão disponíveis no teste.