Migrar a API Pix do banco para um gateway é trocar uma integração por outra sem deixar de receber nenhum dia. O caminho seguro tem três etapas: mapear cada operação da API antiga para a nova, rodar as duas em paralelo com uma camada sua na frente e mudar o tráfego aos poucos, por configuração, até desligar o banco. Se você ainda está decidindo entre os dois modelos, a comparação está em API Pix do Bacen x API de gateway. Aqui o foco é a mudança em si.
O que você deixa para trás
A API Pix do banco segue a especificação do Banco Central, descrita no Manual de Padrões para Iniciação do Pix. Pelo manual, a autenticação usa OAuth 2.0 com TLS mútuo e certificado digital do cliente, e o webhook do PSP também trafega num canal com TLS mútuo. Na API Pix da xFlow, a autenticação é HTTP Basic com pk_live_ e sk_live_, e o webhook é um POST HTTPS assinado com HMAC-SHA256. Some o certificado, e mudam os nomes, os identificadores e algumas regras.
O que não migra
Antes do mapa, separe o que fica no banco. Estes recursos estão na especificação do Banco Central, mas não aparecem na documentação atual da xFlow:
- cobrança com vencimento (
/cobv), com juros, multa e desconto; - Pix Automático e cobranças recorrentes;
- devolução parcial ou várias devoluções do mesmo Pix;
- alteração de uma cobrança já criada;
- txid definido por você;
- location reutilizável (
/loc), usada em QR dinâmico impresso.
Se a sua operação depende de algum deles, esse fluxo continua no banco, e a migração vale para o resto. Ter as duas integrações por um tempo longo é normal.
O mapa de operações
| Operação | API Pix do banco (padrão do Banco Central) | API da xFlow |
|---|---|---|
| Autenticar | OAuth 2.0 com TLS mútuo e certificado | HTTP Basic com pk_live_:sk_live_ |
| Criar cobrança imediata | PUT /cob/{txid} ou POST /cob |
POST /api/v1/charges com Idempotency-Key |
| Identificar a cobrança | txid |
id da xFlow e o seu external_reference |
| Exibir o código | Dados da cobrança; a API não devolve a imagem do QR | pix.copyPaste e pix.qrCodeBase64, prontos |
| Consultar | GET /cob/{txid} |
GET /api/v1/charges/{id} |
| Configurar webhook | PUT /webhook/{chave}, um por chave Pix |
POST /api/v1/webhooks, com a lista de eventos |
| Ser avisado do pagamento | Lista de Pix recebidos com txid | Evento transaction.paid com os dados da cobrança |
| Devolver | PUT /pix/{e2eid}/devolucao/{id}, total ou parcial |
POST /api/v1/charges/{id}/refund, total |
| Conciliar | GET /pix com início e fim |
GET /api/v1/charges?status=paid&from=...&to=... |
As mudanças que pedem atenção
Identificador. No banco, o txid era seu e servia de chave em tudo. Agora você guarda o id devolvido pela xFlow junto do pedido e envia o id do pedido em external_reference. Esse campo não precisa ser único: duas tentativas do mesmo pedido aparecem juntas na busca por external_reference.
Idempotência. O manual do Banco Central explica que PUT /cob/{txid} é idempotente pelo txid, e POST /cob não. Na xFlow, a proteção vem do header Idempotency-Key: na repetição com o mesmo corpo, a API devolve a mesma cobrança; com outro corpo, 409 idempotency_conflict. Veja idempotência em API de pagamento.
Webhook. No banco, o webhook fica ligado a uma chave Pix e avisa só sobre Pix com txid. Na xFlow, o endpoint é da conta, você escolhe os eventos e valida a assinatura do corpo cru. É um handler novo, com outro formato: no evento, o valor vem em amount; na resposta da API, em amountCents.
Devolução. No banco, você devolvia pelo End-to-end ID, em partes, se quisesse. Na xFlow, o estorno é pelo id da cobrança, total, uma vez, até 90 dias após o pagamento. A resposta 202 significa "em processamento", e o resultado chega por transaction.refunded ou transaction.refund_failed. O fluxo está em estorno Pix por API.
Estados. Os nomes e os significados mudam. O manual do Banco Central lembra que CONCLUIDA indica que a cobrança não aceita outro pagamento. Na xFlow, paid indica pagamento confirmado, com o líquido no seu saldo. A lista completa: pending, paid, expired, canceled, refunded, under_review e blocked.
Dinheiro. No banco, o Pix cai na sua conta. Na xFlow, o valor líquido entra no saldo da conta, e a retirada é feita por saque, no painel ou com POST /api/v1/transfers. A conciliação passa a ter taxa (fee), líquido (net) e saldo. As taxas e a reserva da sua conta aparecem em GET /api/v1/company.
O que o pagador vê. Faça uma cobrança real de valor baixo e confira qual nome de recebedor aparece no app do banco. Se mudou em relação ao que os seus clientes conheciam, avise o atendimento antes da virada.
Uma camada sua na frente das duas APIs
O resto do seu sistema não deve saber qual provedor gerou a cobrança. Crie uma função única de criação e grave o provedor em cada cobrança. A escolha usa um percentual configurável e um hash do id do pedido, para que o mesmo pedido caia sempre no mesmo provedor:
import { createHash } from "node:crypto";
// percentual de pedidos novos que vão para a xFlow (0 a 100)
function provedorDoPedido(pedidoId, percentual) {
const hash = createHash("sha256").update(String(pedidoId)).digest();
return hash.readUInt32BE(0) % 100 < percentual ? "xflow" : "banco";
}
async function criarCobrancaNaXflow(pedido) {
const auth = 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 ${auth}`,
"Content-Type": "application/json",
"Idempotency-Key": `pedido-${pedido.id}-${pedido.tentativa}`,
},
body: JSON.stringify({
amountCents: pedido.valorCentavos,
customer: pedido.cliente, // { name, email, document }
external_reference: String(pedido.id),
}),
});
if (!res.ok) throw new Error(`xFlow ${res.status} ${res.headers.get("x-request-id")}`);
const c = await res.json();
return { provedor: "xflow", idExterno: c.id, copiaECola: c.pix.copyPaste, qrCode: c.pix.qrCodeBase64 };
}Três regras para essa camada:
- Grave o provedor na cobrança. Consulta, webhook e devolução de uma cobrança vão sempre para o provedor que a criou.
- Não troque de provedor no meio de uma repetição. Se a chamada à xFlow falhou por rede, repita na xFlow com a mesma
Idempotency-Key. Mandar o mesmo pedido para o banco pode gerar duas cobranças pagáveis. - Normalize os eventos. Os dois handlers de webhook, o antigo e o novo, chamam a mesma função interna de "pedido pago". A regra de negócio não se duplica.
Rodar em paralelo e virar aos poucos
- Sandbox. Com
pk_test_esk_test_, valide criação, webhook, consulta e estorno. O pagamento é simulado comPOST /api/v1/test/charges/{id}/pay. O guia está em API Pix sandbox. - Produção com 0%. Publique a camada com o percentual zerado e cadastre o webhook de produção. Nada muda para o cliente.
- Pedidos internos. Force o provedor
xflowpara pedidos da equipe, pague, estorne e concilie. - Percentual pequeno. Suba o percentual e acompanhe erros na criação (como
502 charge_failed), tempo até a confirmação, eventos recebidos contra eventos recuperados pela varredura, divergências na conciliação e chamados no atendimento. - Aumente em degraus. A cada degrau, compare os indicadores dos dois provedores antes de seguir.
- 100% e desligamento. Com todo o tráfego novo na xFlow, mantenha a integração do banco viva enquanto houver cobranças dela em aberto ou que possam precisar de devolução. Só então desligue o webhook antigo e revogue o certificado e as credenciais do banco.
Se algo der errado, volte o percentual para zero. Pedidos novos voltam para o banco, e as cobranças já criadas na xFlow seguem o fluxo delas. Antes do primeiro degrau, passe pelo checklist de integração Pix para produção.
Onde o roteamento da xFlow entra
A virada entre o banco e a xFlow é decidida no seu código. Depois dela, outra camada trabalha do lado da xFlow. Cada cobrança segue as regras de roteamento de pagamentos da sua conta, que escolhem a adquirente por valor, horário e dia da semana entre as 11 integradas. Se a escolhida não responde ao pedido de geração da cobrança, a retentativa automática gera a cobrança na próxima adquirente da cadeia.
Para a sua integração, isso tem três efeitos práticos. A resposta e os webhooks têm o mesmo formato, seja qual for a adquirente. Mudar ou acrescentar adquirentes é uma mudança de regra na configuração da conta, feita com a equipe da xFlow, sem deploy no seu sistema. E o trabalho desta migração não precisa se repetir para usar outra das adquirentes integradas. A conciliação com várias adquirentes está em conciliação de pagamentos, e a referência da API na documentação.
Conteúdo informativo, atualizado em 25/10/2026. Não substitui orientação jurídica.
Perguntas frequentes
Preciso de certificado digital para usar a API da xFlow?
Não. A API da xFlow autentica com HTTP Basic, usando a chave pública pk_live_ e o segredo sk_live_. O certificado do banco continua necessário só enquanto a integração antiga estiver ligada.
O txid continua existindo depois da migração?
Na API da xFlow você não envia txid. A cobrança é identificada pelo id que a xFlow devolve e pelo external_reference, que você define. Para conciliar com o extrato, use o pix.endToEnd, o End-to-end ID do pagamento.
Dá para fazer devolução parcial na xFlow?
Não pela documentação atual. O estorno é total, uma vez por cobrança, para cobrança paga e até 90 dias após o pagamento. Se o seu fluxo depende de devolução parcial, deixe esse caso fora da migração.
Cobrança com vencimento e Pix Automático migram?
Não. Esses recursos existem na especificação da API Pix do Banco Central, mas não fazem parte da documentação atual da xFlow. Mantenha-os na integração com o banco.