a plataformaDesenvolvedores API v1

Documentação

API de a plataforma

Consulte saldo, leia o extrato e faça transferências direto do seu sistema. Autenticação por chave, respostas em JSON, valores em decimal.

URL base

https://bank.credmaispay.com/api

Todo endereço desta página é relativo a ela. Chamadas em HTTPS, sempre.

Como começar

  1. 1

    Gere sua chave

    No app, em Mais → Credenciais de API. A chave aparece uma única vez: guarde na hora.

  2. 2

    Teste com valores pequenos

    Não há sandbox: sk_test_ e sk_live_ movem dinheiro real na sua conta. O prefixo é só um rótulo para organizar as chaves. Para experimentar, use valores baixos.

  3. 3

    Confira com GET /v1/me

    Antes de qualquer integração, veja se a chave responde e quais escopos ela carrega.

Integrar usando IA

Esta documentação existe também em um arquivo de texto feito para assistentes de programação. Mande o endereço para a sua IA, ou abra e cole o conteúdo — ela terá os endpoints, os formatos e os erros exatos, sem precisar adivinhar.

Abrir o arquivo

Peça algo como: “integre esta API de pagamento no meu sistema seguindo esta documentação”, com o arquivo junto.

Autenticação

Envie a chave no header Authorization. Ela identifica a conta: não há parâmetro de conta em nenhuma rota, e uma chave nunca alcança dados de outra.

curl https://bank.credmaispay.com/api/v1/me \
  -H "Authorization: Bearer sk_test_sua_chave_aqui"

A chave é uma senha

Guarde no servidor, nunca no código do navegador nem no app. Quem tem a chave move o dinheiro da conta. Se vazar, revogue no painel — a revogação vale na hora.

Endpoints

GET/v1/me

Verificar a chave

Devolve o ambiente, os escopos e a conta associada. Use para conferir a integração antes de qualquer outra chamada.

Resposta

{
  "environment": "test",
  "scopes": ["balance:read", "transactions:read"],
  "account": { "id": "8d1e6211-..." },
  "tenant": { "slug": "sua-marca" },
  "permissions": {
    "balance": true,
    "transactions": true,
    "transfers": false
  }
}
GET/v1/balancebalance:read

Consultar saldo

O saldo disponível, o retido e o que pode ser gasto agora. Valores em decimal com duas casas.

Resposta

{
  "available": "8589.10",
  "held": "0.00",
  "spendable": "8589.10"
}
GET/v1/transactions?limit=25&offset=0transactions:read

Listar movimentações

Extrato paginado. Aceita limit (até 100) e offset. Ordenado da mais recente para a mais antiga.

Resposta

{
  "items": [
    {
      "id": "6b346bc2-...",
      "type": "INTERNAL_TRANSFER",
      "direction": "OUT",
      "amount": "150.00",
      "description": "Pagamento de fornecedor",
      "createdAt": "2026-09-06T04:12:00.000Z"
    }
  ],
  "total": 42
}
GET/v1/transactions/{id}transactions:read

Detalhe de uma movimentação

O comprovante completo, com contraparte e taxas. É o que você mostra ao seu usuário como recibo.

Resposta

{
  "id": "6b346bc2-...",
  "status": "SETTLED",
  "amount": "150.00",
  "fee": "0.50",
  "counterparty": { "name": "Padaria Central" },
  "settledAt": "2026-09-06T04:12:00.000Z"
}
POST/v1/payment-linkspix:write

Criar link de pagamento

Uma página hospedada que fica aberta e recebe de várias pessoas, até ser cancelada ou expirar. Diferente da cobrança avulsa, que é um QR para um pagamento só. Use link quando o valor for divulgado: uma vaquinha, uma mensalidade, um catálogo.

Corpo

{
  "description": "Mensalidade de setembro",
  "amount": "99.90",
  "singleUse": false,
  "expiresInHours": 720,
  "requirePayerName": true
}

Resposta

{
  "id": "4f21c8de-...",
  "slug": "k3n8vq2p",
  "url": "https://seu-banco.com/pagar/k3n8vq2p",
  "description": "Mensalidade de setembro",
  "amount": "99.90",
  "amountOpen": false,
  "singleUse": false,
  "status": "open"
}
GET/v1/payment-linkspix:read

Listar links

Os links da conta, com quanto cada um já recebeu e quantos pagamentos teve.

Resposta

{
  "items": [
    {
      "id": "4f21c8de-...",
      "slug": "k3n8vq2p",
      "url": "https://seu-banco.com/pagar/k3n8vq2p",
      "description": "Mensalidade de setembro",
      "amount": "99.90",
      "singleUse": false,
      "uses": 12,
      "status": "open",
      "received": "1198.80",
      "payments": 12
    }
  ]
}
POST/v1/payment-links/{id}/cancelpix:write

Cancelar link

Fecha o link. Quem abrir depois vê que não está mais disponível; os pagamentos já recebidos continuam na conta.

Resposta

{
  "id": "4f21c8de-...",
  "status": "cancelled"
}
POST/v1/transferstransfers:writeidempotente

Transferir

Move dinheiro da sua conta para outra da mesma plataforma. O destino pode ser o apelido (@loja ou loja) ou o id da conta.

Corpo

{
  "to": "padaria",
  "amount": "150.00",
  "description": "Pagamento do pedido 8842"
}

Resposta

{
  "id": "6b346bc2-...",
  "status": "SETTLED",
  "amount": "150.00",
  "fee": "0.50",
  "to": { "id": "c24b7e31-...", "name": "Padaria Central" },
  "replayed": false
}
POST/v1/pix/chargespix:writeidempotente

Cobrar por Pix

Cobrança avulsa: um QR para um pagamento. Devolve o código copia-e-cola, que também serve para gerar o QR. Não cria link nem página pública — use quando o pedido já existe no seu sistema e só falta receber. O pagamento cai direto na sua conta e você é avisado pelo webhook charge.paid.

Corpo

{
  "amount": "49.90",
  "description": "Pedido #1234",
  "expiresIn": 3600,
  "payer": {
    "name": "Maria Silva",
    "email": "maria@exemplo.com",
    "document": "12345678901"
  },
  "externalReference": "pedido-1234"
}

Resposta

{
  "id": "e636775c-...",
  "status": "open",
  "amount": "49.90",
  "description": "Pedido #1234",
  "qrCode": "00020101021226830014br.gov.bcb.pix...",
  "copyPaste": "00020101021226830014br.gov.bcb.pix...",
  "expiresAt": "2026-09-10T00:35:19.836Z",
  "externalReference": "pedido-1234"
}
GET/v1/pix/charges/{id}pix:read

Consultar cobrança

Estado atual da cobrança. Use para conferir um pagamento pontual — para acompanhar em tempo real, prefira o webhook: consultar em laço gasta requisição e chega depois.

Resposta

{
  "id": "e636775c-...",
  "status": "paid",
  "amount": "49.90",
  "description": "Pedido #1234",
  "paidAt": "2026-09-09T21:14:02.000Z",
  "expiresAt": "2026-09-10T00:35:19.836Z"
}
POST/v1/pix/payoutspix:sendidempotente

Enviar Pix

Envia Pix da sua conta para uma chave externa de qualquer banco (Pix de saída). Diferente de Transferir, que move entre contas desta plataforma. Sai dinheiro da conta — por isso pede o escopo próprio pix:send e Idempotency-Key obrigatória.

Corpo

{
  "amount": "150.00",
  "pixKey": "maria@exemplo.com",
  "pixKeyType": "EMAIL",
  "description": "Pagamento fornecedor"
}

Resposta

{
  "id": "8f1a...",
  "status": "processing",
  "amount": "150.00",
  "fee": "1.20",
  "total": "151.20",
  "pixKey": "ma****@exemplo.com",
  "providerReference": "E1890...",
  "endToEndId": "E1890..."
}

Idempotência

Toda transferência exige o header Idempotency-Key. Reenviar a mesma requisição com a mesma chave devolve a operação original com replayed: true, em vez de transferir de novo.

Isso existe porque um timeout de rede não diz se a operação aconteceu. Gere um identificador por intenção de pagamento — não por tentativa — e reenvie o mesmo em cada retry.

curl -X POST https://bank.credmaispay.com/api/v1/transfers \
  -H "Authorization: Bearer sk_test_sua_chave" \
  -H "Idempotency-Key: pedido-8842" \
  -H "Content-Type: application/json" \
  -d '{"to":"padaria","amount":"150.00"}'

Erros

Todo erro traz error (código estável) e message (texto para humano). Trate pelo código, não pelo texto.

HTTPCódigoQuando acontece
401missing_credentialsFaltou o header Authorization.
401invalid_credentialsChave inexistente, revogada ou de outro ambiente.
403insufficient_scopeA chave não tem o escopo exigido pela rota.
400missing_idempotency_keyPOST /v1/transfers exige Idempotency-Key.
400provider_failedO provedor de Pix recusou a cobrança. Nenhuma cobrança foi criada — pode tentar de novo.
404charge_not_foundCobrança inexistente ou de outra conta.
400invalid_requestCorpo malformado. `details` diz qual campo.
404not_foundO recurso não existe ou não é desta conta.

Estados de uma cobrança Pix

paid significa dinheiro na conta. Libere o pedido nesse estado, nunca antes.

openCriada, aguardando pagamento.
paidPaga e creditada na sua conta. É o único estado que move saldo.
expiredPassou da validade sem pagamento. Crie outra cobrança.
cancelledCancelada antes do pagamento.
refundedDevolvida ao pagador depois de paga.

Webhooks

Em vez de perguntar de tempos em tempos se a cobrança foi paga, cadastre uma URL no painel e receba o aviso no momento em que acontece. Cada envio é assinado — confira a assinatura antes de confiar no conteúdo.

Eventos

charge.paidA cobrança foi paga e o valor entrou na sua conta. É este que autoriza liberar o pedido.
charge.expiredA cobrança venceu sem pagamento. Serve para cancelar o pedido em aberto.
transfer.completedUma transferência que você enviou chegou ao destino.
credit.drawnAlguém usou o limite de crédito da conta.
loan.approvedUm empréstimo pedido pela conta foi aprovado.
investment.appliedUm aporte em investimento foi aplicado.
consortium.quota.approvedUma cota de consórcio foi aprovada.
consortium.contemplatedUma cota de consórcio foi contemplada.

O que chega

POST https://seu-sistema.com/webhooks
content-type: application/json
x-webhook-id: 9f2c1a44-...
x-webhook-event: charge.paid
x-webhook-timestamp: 1789002842
x-webhook-signature: 7b52009b64fd0a2a49e6d8a939753077792b0554...

{
  "id": "9f2c1a44-...",
  "type": "charge.paid",
  "createdAt": "2026-09-09T21:14:02.000Z",
  "data": {
    "chargeId": "e636775c-...",
    "sellerId": "c34b87db-...",
    "amount": "4990"
  }
}

O valor em data.amount vem em centavos. O identificador da cobrança é data.chargeId — o mesmo id devolvido ao criar.

Conferindo a assinatura

A assinatura é o HMAC-SHA256 de {timestamp}.{corpo}, em hexadecimal, com o segredo do destino, mostrado ao cadastrar a URL e recuperável depois em Credenciais, no botão Ver segredo ao lado do destino. O timestamp entra no cálculo para que uma entrega capturada não possa ser reenviada depois — recuse o que chegar com mais de 5 minutos.

import { createHmac, timingSafeEqual } from "node:crypto";

// corpo CRU, exatamente como chegou — reserializar muda os bytes
// e a assinatura deixa de bater.
function confere(corpoBruto, headers, segredo) {
  const assinatura = headers["x-webhook-signature"];
  const timestamp = Number(headers["x-webhook-timestamp"]);

  // Entrega velha é entrega repetida: recuse.
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;

  const esperado = createHmac("sha256", segredo)
    .update(`${timestamp}.${corpoBruto}`)
    .digest("hex");

  const a = Buffer.from(assinatura);
  const b = Buffer.from(esperado);
  // Comparação em tempo constante: "===" vaza, pelo tempo, quantos
  // caracteres iniciais estavam certos.
  return a.length === b.length && timingSafeEqual(a, b);
}

Boas práticas

  • Responda 200 rápido. Processe depois, em fila. Demorar faz o envio ser considerado falho e reenviado.
  • Espere repetição. O mesmo evento pode chegar duas vezes — uma reentrega após falha de rede, por exemplo. Guarde o x-webhook-id já processado e ignore repetidos, ou o pedido é liberado duas vezes.
  • Não confie no valor recebido para creditar. Antes de liberar o pedido, confirme com GET /v1/pix/charges/{id}. O webhook diz o que olhar; a consulta diz o que é verdade.
  • Use HTTPS. URLs em HTTP não são aceitas.

Valores e datas

  • Dinheiro vai e volta como string decimal com duas casas: "150.00". Nunca como número — ponto flutuante perde centavo, e centavo perdido em dinheiro é erro contábil.
  • Datas em ISO 8601, UTC: 2026-09-06T04:12:00.000Z.
  • Identificadores são UUID. Não presuma ordem nem sequência entre eles.