BitFlow Pay API PIX — Documentação pública

Referência oficial para integração via API pública: autenticação, consulta de saldo, Pix In, Pix Out e webhooks.

Pesquisar na documentacao

👋 Introdução

Esta documentação cobre somente os endpoints de integração da API PIX da BitFlow Pay.

A autenticação da API pública utiliza JWT OAuth2 (client credentials) e API Key. O token deve ser enviado no header Authorization e a chave pública no header X-API-Key.

🔐 Autenticação

1. Gerar credenciais da API

  1. Acesse o painel BitFlow Pay.
  2. Vá em Integrações > API PIX > Cadastrar API Key.
  3. Guarde os valores de client_id (public key), client_secret (secret key).

O header X-API-Key deve receber o valor do client_id (public key).

2. Obter Token JWT

POST
/auth/oauth2/token
Body da Requisição
POST /auth/oauth2/token
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "bf_abc123...",
  "client_secret": "bf_xyz789..."
}
CampoTipoObrigatórioDescrição
grant_typestringSimValor fixo: client_credentials
client_idstringSimPublic key da API
client_secretstringSimSecret key da API
Resposta
{
  "access_token": "jwt_aqui",
  "token_type": "Bearer",
  "expires_in": 3600
}

Utilize os headers abaixo nos endpoints da API:

Headers de Autenticação
Authorization: Bearer {access_token}
X-API-Key: {public_key}

💼 Get Balance

Consultar saldo da carteira

GET
/wallet/me

Retorna os saldos da carteira em centavos.

Exemplo de Requisição
GET /wallet/me
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Resposta
{
  "available": 50000,
  "blocked": 10000,
  "reserved": 5000,
  "internalReserve": 0,
  "totalReceived": 100000
}

📥 Pix In (CashIn)

Criar cobrança PIX (API pública)

POST
/cashin/api

Para API pública, o objeto customer é obrigatório.

Campos do corpo

CampoTipoObrigatórioDescrição
amountCentsnumberSimValor em centavos
descriptionstringNãoDescrição da cobrança
customerobjectSim (na API)Dados do pagador (nome, email, cpf, phone; externaRef opcional)
customer.externaRefstringNãoReferência no seu sistema; se omitido, usamos o ID do usuário BitFlow
customer.addressobjectCondicionalObrigatório se algum item tiver tangible=true
itemsarraySimLista com pelo menos 1 item
trace / trackingobjectNãoParâmetros de rastreamento (UTM, src, sck). Aceita tracking (preferencial), trace ou campos soltos no body. Usado em integrações como Utmify.
pix.expiresInDaysnumberNãoPrazo da cobrança em dias (default: 2)
urlCallBackstring (URL)NãoURL do cliente para notificação de status
splitarrayNãoDivisão de receita entre parceiros (até 3). Ver Split CashIn
Exemplo mínimo
POST /cashin/api
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Content-Type: application/json

{
  "amountCents": 10000,
  "customer": {
    "name": "Cliente Teste",
    "email": "[email protected]",
    "cpf": "12345678901",
    "phone": "11999999999"
  },
  "items": [
    {
      "title": "Pagamento",
      "quantity": 1,
      "unitPriceCents": 10000,
      "tangible": false
    }
  ]
}
Exemplo completo
POST /cashin/api
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Content-Type: application/json

{
  "amountCents": 25990,
  "description": "Pedido #9876",
  "customer": {
    "name": "Joao da Silva",
    "email": "[email protected]",
    "cpf": "12345678901",
    "phone": "11988887777",
    "externaRef": "user-ext-42",
    "address": {
      "street": "Rua A",
      "streetNumber": "100",
      "complement": "Apto 101",
      "zipCode": "01001000",
      "neighborhood": "Centro",
      "city": "Sao Paulo",
      "state": "SP",
      "country": "br"
    }
  },
  "trace": {
    "utm_source": "google",
    "utm_medium": "cpc",
    "utm_campaign": "black_friday"
  },
  "tracking": {
    "utm_source": "facebook",
    "utm_medium": "cpc",
    "utm_campaign": "campanha01",
    "utm_content": "criativo03",
    "utm_term": "publico01",
    "src": "fb",
    "sck": "abc123"
  },
  "pix": {
    "expiresInDays": 3
  },
  "items": [
    {
      "title": "Produto A",
      "quantity": 1,
      "unitPriceCents": 19990,
      "tangible": true
    },
    {
      "title": "Servico B",
      "quantity": 1,
      "unitPriceCents": 6000,
      "tangible": false
    }
  ],
  "urlCallBack": "https://cliente.com/webhooks/bitflow/pix-in"
}
Resposta de sucesso (201)
{
  "id": 1,
  "amountCents": 10000,
  "fee": 0,
  "netAmount": 10000,
  "description": "Pedido #9876",
  "paymentCode": "000201010212...",
  "status": "PENDING",
  "providerTransactionId": "388544133",
  "expiresAt": "2026-03-22T18:30:00.000Z",
  "createdAt": "2026-03-19T18:30:00.000Z"
}

Parâmetros de rastreamento

Todos os campos abaixo são opcionais. Payloads antigos sem tracking continuam funcionando. Os dados são salvos na transação e repassados a integrações externas (ex.: Utmify), quando configuradas na conta.

CampoDescrição
tracking.utm_source / trace.utm_sourceOrigem (ex.: facebook, google)
tracking.utm_mediumMeio (ex.: cpc, email)
tracking.utm_campaignNome da campanha
tracking.utm_contentCriativo / variação
tracking.utm_termPalavra-chave ou público
tracking.srcFonte customizada
tracking.sckChave de rastreamento (tracker / checkout)

No link de pagamento, adicione os parâmetros na URL (o slug do produto não é tracking): /l/seu-slug?utm_source=facebook&utm_campaign=campanha01&src=fb&sck=abc123. O checkout captura automaticamente; o comprador não preenche UTMs.

Split de receita (CashIn)

O split reparte o valor bruto de uma cobrança PIX entre você (dono da cobrança — conta que autenticou na API) e até 3 parceiros cadastrados na BitFlow. A divisão é definida por percentuais no momento da criação; os créditos na carteira de cada beneficiário ocorrem quando o pagamento é confirmado (PAID).

Como definir o split

FormaQuando usar
split no body do POST /cashin/apiRegra por cobrança (marketplace, afiliado, coprodutor). Tem prioridade sobre qualquer preset do painel.
Preset global (painel)Em Integrações → Split CashIn, configure destinatários fixos. Se você não enviar split na API, o preset ativo é aplicado automaticamente em cada nova cobrança.
Conflito preset × payload: se existir preset ativo e você enviar split na mesma requisição, a API responde 409 Conflict. Desative o preset no painel ou remova o array split do body.

Campos de cada item em split

CampoTipoDescrição
userIdnumber (inteiro)ID do usuário BitFlow do parceiro. Não pode ser o dono da cobrança nem repetir outro item do array.
percentagenumberPercentual da cobrança (máx. 2 casas decimais, ex.: 12.5 = 12,5%). A soma de todos os itens deve ser menor que 100%; o restante fica com o dono.

Regras de validação

  • De 1 a 3 destinatários no array (além do dono, que não entra no array).
  • Cada parceiro precisa estar ACTIVE, com KYC APPROVED e e-mail verificado na BitFlow.
  • A taxa CashIn é cobrada apenas do dono da cobrança, com a taxa configurada na conta dele, sobre o valor integral da transação. Os parceiros do split recebem a fatia bruta sem desconto de taxa.
  • Os campos fee e netAmount na resposta de criação e no webhook de PAID referem-se ao dono da cobrança, não ao valor total repartido.
  • Centavos de arredondamento: cada fatia usa floor quando o percentual não fecha em centavo exato. A diferença (poucos centavos no total) é registrada em houseRemainderCents na resposta — não é creditada a parceiros nem ao dono.
  • Em MED/estorno após PAID, os débitos de reversão consideram todos os beneficiários que receberam crédito no split.
Exemplo com split (R$ 100,00 — 20% parceiro A, 10% parceiro B)
POST /cashin/api
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Content-Type: application/json

{
  "amountCents": 10000,
  "customer": {
    "name": "Cliente Teste",
    "email": "[email protected]",
    "cpf": "12345678901",
    "phone": "11999999999"
  },
  "items": [
    {
      "title": "Produto com parceiros",
      "quantity": 1,
      "unitPriceCents": 10000,
      "tangible": false
    }
  ],
  "split": [
    { "userId": 42, "percentage": 20 },
    { "userId": 57, "percentage": 10 }
  ]
}
Resposta 201 com split (trecho)
{
  "id": 99,
  "amountCents": 10000,
  "fee": 300,
  "netAmount": 6700,
  "status": "PENDING",
  "hasSplit": true,
  "houseRemainderCents": 0,
  "split": [
    {
      "userId": 42,
      "role": "RECIPIENT",
      "percentageBps": 2000,
      "grossAmountCents": 2000,
      "feeCents": 0,
      "netAmountCents": 2000
    },
    {
      "userId": 57,
      "role": "RECIPIENT",
      "percentageBps": 1000,
      "grossAmountCents": 1000,
      "feeCents": 0,
      "netAmountCents": 1000
    },
    {
      "userId": 1,
      "role": "OWNER",
      "percentageBps": 7000,
      "grossAmountCents": 7000,
      "feeCents": 300,
      "netAmountCents": 6700
    }
  ]
}

percentageBps usa base 10.000 (= 100,00%). Ex.: 2000 = 20%. O item com role: "OWNER" é o dono da cobrança. Valores em grossAmountCents, feeCents e netAmountCents são o plano calculado na criação; na liquidação (PAID), as carteiras são creditadas conforme esse snapshot.

Para consultar o split após a criação (incluindo data de liquidação), use GET /cashin/:id com o mesmo token JWT — o objeto split traz source (PAYLOAD ou PRESET), appliedAt e allocations com percentuais legíveis.

Erros frequentes

HTTPMensagem (resumo)Causa usual
400Soma dos percentuais deve ser menor que 100%Percentuais somam 100% ou mais; o dono precisa de fatia > 0.
400Destinatário inexistente ou com cadastro incompletoParceiro sem KYC, inativo ou e-mail não verificado.
400Dono da cobrança não pode aparecer no array splituserId igual ao dono incluído em split.
409Split no payload conflita com preset global ativoPreset ligado no painel e split enviado na mesma requisição.

📤 Pix Out (CashOut)

Criar envio PIX (API pública)

POST
/cashout/api

Campos do corpo

CampoTipoObrigatórioDescrição
amountCentsnumberSimValor em centavos
pixKeyTypeenumSimCPF, CNPJ, EMAIL, PHONE ou RANDOM
pixKeystringSimChave Pix de destino
beneficiaryNamestringSimNome do beneficiário
beneficiaryDocumentstringCondicionalObrigatório para EMAIL, PHONE e RANDOM. Em CPF/CNPJ, o backend usa a própria chave.
descriptionstringNãoDescrição do pagamento
externalReferencestringNãoIdentificador de idempotência por usuário
urlCallbackstring (URL)NãoURL do cliente para receber mudança de status
Exemplo mínimo
POST /cashout/api
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Content-Type: application/json

{
  "amountCents": 10000,
  "pixKeyType": "CPF",
  "pixKey": "12345678901",
  "beneficiaryName": "Cliente Exemplo"
}
Exemplo completo
POST /cashout/api
Authorization: Bearer {access_token}
X-API-Key: {public_key}
Content-Type: application/json

{
  "amountCents": 15350,
  "pixKeyType": "EMAIL",
  "pixKey": "[email protected]",
  "beneficiaryName": "Empresa Favorecida LTDA",
  "beneficiaryDocument": "12345678000190",
  "description": "Repasse pedido #9001",
  "externalReference": "cashout-9001",
  "urlCallback": "https://cliente.com/webhooks/bitflow/pix-out"
}
Resposta de sucesso (201)
{
  "id": 10,
  "amountCents": 10000,
  "fee": 0,
  "netAmount": 10000,
  "pixKey": "12345678901",
  "pixKeyType": "CPF",
  "beneficiaryName": "Cliente Exemplo",
  "beneficiaryDocument": "12345678901",
  "description": "Repasse pedido #9001",
  "status": "PENDING",
  "provider": "hiconex",
  "providerTransactionId": null,
  "externalReference": "cashout-9001",
  "createdAt": "2026-03-19T18:40:00.000Z",
  "updatedAt": "2026-03-19T18:40:00.000Z"
}

🔔 Webhooks (exemplos de payload)

A BitFlow Pay envia notificações para as URLs configuradas em urlCallback dos CashIns e CashOuts. Abaixo estão exemplos de payloads para facilitar sua implementação.

Regra de prioridade (API pública):
  1. 1) Se enviar urlCallBack/urlCallback no body, ela será usada.
  2. 2) Se não enviar no body, a BitFlow Pay usa a URL fixa cadastrada para o evento.
  3. 3) Se não houver nenhuma URL, a API retorna erro de callback obrigatório.

Webhook de Pix In (Pagamento Recebido)

StatusQuando ocorre
PAIDPagamento confirmado e crédito aplicado na carteira (com split, cada beneficiário recebe sua fatia líquida).
EXPIREDCobrança venceu sem pagamento.
CANCELLEDCobrança cancelada.
MEDTransação marcada em análise/devolução (MED).
REFUNDEDValor estornado/devolvido após crédito anterior.
Exemplo
POST https://seusistema.com/webhook/pix-in
Content-Type: application/json

{
  "event": "cashin.status_changed",
  "data": {
    "cashInId": 14,
    "status": "PAID",
    "amountCents": 500,
    "fee": 67,
    "netAmount": 433,
    "providerTransactionId": "5eb1ed6df54d0786f47d9ea8213d18",
    "externalReference": "pedido-1234",
    "paymentCode": "000201010212...",
    "e2e": "E339303682026031912161117192f1",
    "urlCallback": "https://cliente.com/webhooks/bitflow/pix-in",
    "paidAt": "2026-03-19T12:16:11.000Z"
  }
}

Em cobranças com split, fee e netAmount no webhook são do dono da cobrança. O detalhamento por parceiro está na resposta do POST /cashin/api (quando hasSplit: true) e em GET /cashin/:id.

Webhook de Pix Out (Pagamento Enviado)

StatusQuando ocorre
COMPLETEDPagamento enviado com sucesso.
FAILEDFalha no envio (inclui cancelamento/falha no provider).
Exemplo
POST https://seusistema.com/webhook/pix-out
Content-Type: application/json

{
  "event": "cashout.status_changed",
  "data": {
    "cashOutId": 7,
    "status": "COMPLETED",
    "amountCents": 200,
    "fee": 0,
    "netAmount": 200,
    "providerTransactionId": "f6e84056-1bbf-4b59-add1-313bfdf70fd3",
    "pixKey": "03439207196",
    "beneficiaryName": "Lucas Melo",
    "beneficiaryDocument": "03439207196",
    "e2e": "E33930368202603192154341017192f1",
    "processedAt": "2026-03-19T15:54:39.000Z"
  }
}

🤖 Integre com IA

Para acelerar integrações com agentes de IA (Cursor, Claude, etc.), disponibilizamos um contexto técnico único com regras, payloads e comportamento esperado da API.

Baixe o arquivo, copie todo o conteúdo e cole no seu agente de IA junto com o contexto do seu projeto.

DOWNLOAD