Documentação da API

Receba Pix pela Cifra no seu sistema.

API REST para criar cobranças Pix, consultar o pagamento e receber o aviso de venda paga num webhook assinado.

Basehttps://api.cifra-pay.com

Atalho

Integre com IA em minutos.

Copie o prompt e cole no seu assistente de código (ChatGPT, Claude, Cursor, Copilot) junto com o seu projeto. Ele leva toda a especificação desta página (rotas, exemplos, assinatura do webhook e regras de segurança) e pede a integração completa, com testes. A chave de API nunca vai no prompt: ele manda ler de variável de ambiente.

01

Para plataformas e bots

Bot de Telegram, loja ou plataforma que oferece a Cifra como opção de pagamento: cada vendedor conecta a conta dele com a própria chave de API. A plataforma não precisa de chave própria.

  1. 01Cada vendedor cria a conta na Cifra, tem a verificação de identidade aprovada e gera uma chave de PRODUÇÃO em Painel › API, com os escopos Criar cobranças, Consultar pagamentos e Gerenciar webhooks.
  2. 02O vendedor cola a chave no seu painel/bot. Guarde-a cifrada; ela é do vendedor e só vale para a conta dele.
  3. 03Na conexão, chame GET /api/v1/capacidades: habilitacao.pagamentos precisa ser true. Se for false, a resposta diz a pendência.
  4. 04Ainda na conexão, cadastre o seu endereço com POST /api/v1/webhooks (evento cobranca.paga) e guarde o id e o segredo junto da chave. Antes, confira com GET /api/v1/webhooks se já não existe.
  5. 05A cada compra, crie a cobrança com POST /api/v1/cobrancas (Idempotency-Key nova por pedido, referenciaExterna = o id do pedido no seu sistema) e mostre ao comprador o pix.copiaECola (dá para gerar o QR Code a partir dele).
  6. 06Quando o comprador pagar, o seu endereço recebe cobranca.paga. Confira a assinatura com o segredo, ache o pedido por data.referenciaExterna (ou data.id) e libere a entrega. Responda 2xx.
  7. 07Se o aviso atrasar, consulte GET /api/v1/cobrancas/{id}: estado "paga" é a confirmação. Nunca libere pelo que o comprador diz ou manda (comprovante).
  • •O dinheiro de cada venda entra no saldo do vendedor dono da chave, já descontada a taxa. O saque é feito pelo vendedor no painel da Cifra, para a chave Pix dele.
  • •A plataforma não movimenta o saldo do vendedor pela API. Para ficar com uma parte de cada venda, use o split (abaixo): a parte cai no saldo da conta Cifra da plataforma.

02

Autenticação

Envie a chave no cabeçalho x-cifra-api-key. Não use Authorization nem a query string: a chamada é recusada. A chave é criada pelo vendedor em Painel › API, e o segredo aparece uma vez só.

Formato cifra_<ambiente>_<identificador>_<segredo>

  • <ambiente>: dev, sbx, prd
  • <identificador>: 16 caracteres, público (aparece na lista de chaves)
  • <segredo>: 43 caracteres, mostrado uma vez, quando a chave é criada
Chamada
curl https://api.cifra-pay.com/api/v1/ping \
  -H "x-cifra-api-key: $CIFRA_API_KEY"
  • GET/api/v1/ping

    Confirma que a chave vale e que o serviço responde.

  • GET/api/v1/organizacao

    A organização e a chave que fizeram a chamada.

  • GET/api/v1/capacidades

    O que a organização pode fazer hoje, com cada pendência.

03

Cobranças Pix

  • POST/api/v1/cobrancaspayments:write

    Cria uma cobrança Pix. Exige o cabeçalho idempotency-key.

  • GET/api/v1/cobrancaspayments:read

    As cobranças mais recentes da organização (limite de 1 a 100, padrão 20).

  • GET/api/v1/cobrancas/{id}payments:read

    Uma cobrança, com o estado atual e o Pix copia e cola enquanto vale.

Criar uma cobrança
curl -X POST https://api.cifra-pay.com/api/v1/cobrancas \
  -H "x-cifra-api-key: $CIFRA_API_KEY" \
  -H "idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"valorCentavos":4990,"descricao":"Curso de exemplo","referenciaExterna":"pedido-1001","pagador":{"nome":"Comprador Exemplo","email":"comprador@example.com","documento":"52998224725","telefone":"11999990000"},"origem":{"url":"https://sualoja.example.com/oferta","utms":{"utm_source":"facebook","utm_medium":"cpc","utm_campaign":"lancamento","utm_content":"video-1"},"produto":{"id":"curso-1","nome":"Curso de exemplo"}}}'
Corpo
{
  "valorCentavos": 4990,
  "descricao": "Curso de exemplo",
  "referenciaExterna": "pedido-1001",
  "pagador": {
    "nome": "Comprador Exemplo",
    "email": "comprador@example.com",
    "documento": "52998224725",
    "telefone": "11999990000"
  },
  "origem": {
    "url": "https://sualoja.example.com/oferta",
    "utms": {
      "utm_source": "facebook",
      "utm_medium": "cpc",
      "utm_campaign": "lancamento",
      "utm_content": "video-1"
    },
    "produto": {
      "id": "curso-1",
      "nome": "Curso de exemplo"
    }
  }
}
  • •Repetir o mesmo pedido com a mesma idempotency-key devolve a mesma cobrança; a mesma chave com outro corpo é recusada (409). Use 16 a 128 caracteres; um UUID serve.
  • •valorCentavos é um inteiro em centavos.
  • •pagador (opcional): nome, e-mail, CPF ou CNPJ só com números e telefone com DDD. Vai para o provedor e fica cifrado na venda; no painel, só quem tem permissão financeira vê.
  • •origem (opcional): página de venda em HTTPS sem parâmetros, as UTMs (utm_source, utm_medium, utm_campaign, utm_content, utm_term, src, sck) e o produto. Aparece no detalhe da venda.
  • •A cobrança vai para a adquirente ativa da loja no momento da criação, e o saldo dela fica na carteira dessa adquirente.

Resposta (a mesma de GET /api/v1/cobrancas/{id}). O estado passa de pendente para paga.

Resposta
{
  "id": "3b6f0c1e-8d2a-4f5b-9c7e-1a2b3c4d5e6f",
  "estado": "pendente",
  "valorCentavos": 4990,
  "moeda": "BRL",
  "descricao": "Curso de exemplo",
  "referenciaExterna": "pedido-1001",
  "provedor": "velani",
  "criadaEm": "2026-11-06T12:00:00.000Z",
  "atualizadaEm": "2026-11-06T12:00:01.000Z",
  "pagaEm": null,
  "tentativa": {
    "numero": 1,
    "estado": "aceita",
    "provedor": "velani",
    "iniciadaEm": "2026-11-06T12:00:00.000Z",
    "concluidaEm": "2026-11-06T12:00:01.000Z",
    "incertaDesde": null
  },
  "pix": {
    "copiaECola": "00020101021226...6304ABCD",
    "expiraEm": "2026-11-06T12:30:00.000Z"
  }
}

04

Split

Parte de cada venda vai para outra conta Cifra, como o dono do bot que a loja usa. A loja paga as taxas da Cifra e o bot recebe a parte dele no saldo.

  1. 01Quem vai receber (o dono do bot, da plataforma ou do checkout) tem conta na Cifra com a verificação aprovada e copia o ID de recebedor em Painel › Split.
  2. 02Na criação da cobrança, mande o campo split com o recebedor e a parte dele: percentual da venda ou valor fixo em centavos. Pode mudar a cada venda.
  3. 03Quando a venda é paga, a parte de cada recebedor cai no saldo dele na Cifra. Ele saca como qualquer conta.
Corpo · 3% para o bot
{
  "valorCentavos": 4990,
  "referenciaExterna": "pedido-1001",
  "split": [
    {
      "recebedorId": "2d8f7a10-5c3e-4b9a-8e21-7f6c5d4b3a29",
      "percentual": 3
    }
  ]
}
Corpo · R$ 1,50 fixo
{
  "valorCentavos": 4990,
  "split": [
    {
      "recebedorId": "2d8f7a10-5c3e-4b9a-8e21-7f6c5d4b3a29",
      "valorCentavos": 150
    }
  ]
}
  • •Até 5 recebedores por venda, cada um uma vez, e no máximo 50% da venda para cada um.
  • •percentual aceita até 2 casas (2.5 = 2,5%) e arredonda para baixo em centavos.
  • •As taxas da Cifra saem da parte da loja: o recebedor ganha a parte cheia. A soma do split não pode passar do que sobra para a loja.
  • •O split fica gravado na criação e não muda depois. A resposta da cobrança mostra cada parte em split.
  • •O webhook cobranca.paga da loja traz liquidoCentavos já sem o split.
  • 422split_recebedor_invalidoo ID não é de uma conta Cifra com a verificação aprovada
  • 422split_propria_contao recebedor é a própria loja da chave
  • 422split_acima_do_limiteuma parte passa de 50% da venda
  • 422split_maior_que_liquidoo split passa do que sobra para a loja depois das taxas
  • 422split_valor_invalidouma parte ficou abaixo de R$ 0,01
  • 422split_indisponivela loja não pode dividir agora (saldo bloqueado, conta de gateway parceiro ou adquirente sem split)

05

Webhooks

Cadastre pelo painel (tela Webhooks) ou pela própria chave, com as rotas abaixo. Até 10 endereços ativos por conta. Eventos enviados: webhook.test, cobranca.criada, cobranca.paga, saque.concluido, saque.recusado.

  • POST/api/v1/webhookswebhooks:manage

    Cadastra um endereço que recebe eventos de cobrança (cobranca.criada, cobranca.paga). A resposta traz o segredo de assinatura uma única vez: guarde.

  • GET/api/v1/webhookswebhooks:manage

    Os endereços cadastrados pela API nesta conta (sem a URL inteira e sem segredo). Use para não cadastrar o mesmo duas vezes. Os do painel não aparecem.

  • DELETE/api/v1/webhooks/{id}webhooks:manage

    Desativa (pausa) um endereço cadastrado pela API. As entregas pendentes dele são encerradas.

Cadastrar o endereço
curl -X POST https://api.cifra-pay.com/api/v1/webhooks \
  -H "x-cifra-api-key: $CIFRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"nome":"Bot de vendas","url":"https://bot.example.com/cifra/webhook","eventos":["cobranca.paga"]}'
Corpo · URL HTTPS pública
{
  "nome": "Bot de vendas",
  "url": "https://bot.example.com/cifra/webhook",
  "eventos": [
    "cobranca.paga"
  ]
}
Evento de venda paga
{
  "id": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
  "type": "cobranca.paga",
  "apiVersion": "2026-09-20",
  "createdAt": "2026-11-06T12:03:10.000Z",
  "organizationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
  "data": {
    "id": "3b6f0c1e-8d2a-4f5b-9c7e-1a2b3c4d5e6f",
    "valorCentavos": 4990,
    "liquidoCentavos": 4890,
    "referenciaExterna": "pedido-1001",
    "ocorridoEm": "2026-11-06T12:03:09.000Z"
  }
}
Cifra-Webhook-Id
Id da entrega. Igual nas repetições.
Cifra-Webhook-Event
Tipo do evento.
Cifra-Webhook-Timestamp
Segundos desde 1970. Recuse diferença maior que 300 s.
Cifra-Webhook-Signature
v1= e o HMAC-SHA256, em hexadecimal, de timestamp, id e corpo, separados por ponto.

Entrega pelo menos uma vez: responda 2xx e descarte ids repetidos. Confira a assinatura com o corpo exatamente como chegou:

Conferir a assinatura · Node.js
const crypto = require('node:crypto');

function assinaturaValida(segredo, cabecalhos, corpoCru, agoraSegundos = Math.floor(Date.now() / 1000)) {
  const id = cabecalhos['cifra-webhook-id'];
  const timestamp = cabecalhos['cifra-webhook-timestamp'];
  const recebidas = String(cabecalhos['cifra-webhook-signature'] || '').split(',');
  if (Math.abs(agoraSegundos - Number(timestamp)) > 300) return false;
  const esperada = 'v1=' + crypto.createHmac('sha256', segredo).update(`${timestamp}.${id}.${corpoCru}`).digest('hex');
  return recebidas.some((a) => a.length === esperada.length && crypto.timingSafeEqual(Buffer.from(a), Buffer.from(esperada)));
}

06

Erros

Todo erro vem como JSON com code, message e requestId.

  • 401api_key_invalidchave ausente, com formato errado, revogada ou expirada
  • 401credencial_ambiguaa chamada trouxe a chave e também um cabeçalho Authorization
  • 403api_key_scope_requireda chave não tem o escopo que a rota exige
  • 429api_key_quota_exceededa cota por minuto da chave acabou
  • 429rate_limitedfalhas de autenticação demais do mesmo endereço
  • 503service_unavailableo controle de limites está fora; a chamada é recusada, não liberada
Documentação da API Cifra Pay