Integrar boletos com a Calebe Pay
Esta é a API implementada pela Calebe Pay, com exemplos prontos para backend e agentes de programação. Valores são inteiros em centavos BRL. 1250 significa R$ 12,50. Não envie o JSON do provedor de pagamento diretamente: a Calebe Pay adapta o seu contrato ao do provedor.
Escolha o ambiente
| Modo | Como reconhecer na resposta | Resultado |
|---|---|---|
Teste (chave cp_test_) |
livemode: false, simulated: true, environment: sandbox |
Boleto de teste na API de produção, com a mesma validação; boleto_url, boleto_digitable_line e boleto_barcode são nulos e o Pix do boleto é um marcador não pagável; nada chega ao provedor de pagamento |
| Simulador | simulated: true, environment: sandbox |
Registro local; boleto_url, boleto_digitable_line e boleto_barcode são nulos e o Pix do boleto é um marcador não pagável; nenhum título pagável |
| Sandbox de boleto | simulated: false, environment: sandbox |
Boleto de teste emitido no sandbox do provedor de pagamento, sem Pix pagável (o sandbox não tem Pix) e com PDF marcado como documento de teste; não representa dinheiro real |
| Produção | simulated: false, environment: production |
Emissão financeira real, com o Pix do mesmo valor, liberada pela Calebe Pay para a conta |
No provedor de pagamento, boleto suporta sandbox; Pix não. Um teste no simulador ou no sandbox não comprova que a conta está liberada para produção.
A Calebe Pay define o ambiente de cada conta e libera a emissão em produção caso a caso. Enquanto a produção não estiver liberada, a API responde 403 live_payments_disabled ou 403 live_payment_out_of_scope. Nunca tente contornar essa recusa trocando a chave de idempotência ou o payload.
Antes de começar
- A Calebe Pay habilita o boleto para a sua conta. Contas novas começam apenas com Pix.
- No painel, um administrador da conta emite uma chave com
scopes: ["boleto:write", "transactions:read"].boleto:writenão é adicionado a chaves antigas nem ao padrão de novas chaves. O segredo só aparece na criação. - Configure
CALEBE_API_URLeCALEBE_API_KEYno backend integrador. Não exponha a chave em React, Expo, Electron renderer, prompts ou logs.
Primeiro boleto no simulador
Com o boleto habilitado no ambiente de simulação da sua conta, prepare uma vez o payload fictício com vencimento em sete dias, considerando a data de São Paulo:
node docs/examples/prepare-boleto.mjs .local/boleto-request.json
export CALEBE_API_URL=http://localhost:18080
export CALEBE_REQUEST_FILE=.local/boleto-request.json
# CALEBE_API_KEY vem do ambiente seguro do seu servidor.
# Grave esta chave no pedido antes da primeira chamada e não a troque em retries.
export CALEBE_IDEMPOTENCY_KEY=pedido-boleto-exemplo-42-tentativa-1
curl --fail-with-body "$CALEBE_API_URL/v1/boleto" \
-H "X-API-Key: $CALEBE_API_KEY" \
-H "Idempotency-Key: $CALEBE_IDEMPOTENCY_KEY" \
-H 'Content-Type: application/json' \
--data-binary "@$CALEBE_REQUEST_FILE"
O preparador não substitui um arquivo existente. Preserve esse arquivo nos retries, inclusive depois do vencimento; não recalcule a data a cada tentativa. Para um pedido novo, grave outro payload e outra chave comercial deliberadamente. Dados fictícios servem ao simulador local; para integração remota use dados e configuração aceitos pelo provider.
Alternativas à chamada cURL, com o mesmo arquivo e chave:
node docs/examples/create-boleto.mjs
python3 docs/examples/create_boleto.py
go run docs/examples/create_boleto.go
Os exemplos não repetem chamadas automaticamente e não seguem redirects com credenciais. Uma resposta incerta exige consultar a tentativa existente e preservar a chave.
Contrato de criação
POST /v1/boleto usa o tenant da API key: não envie tenant_id ou provider_id. A chamada exige Idempotency-Key com 1–128 caracteres de [A-Za-z0-9._:-].
{
"amount": 1250,
"reference": "pedido-boleto-42",
"description": "Pedido por boleto",
"customer": {
"name": "Cliente de demonstração",
"document": "00000000000",
"email": "cliente@example.com",
"phone": "11999999999",
"address": {
"zip_code": "01001000",
"street": "Rua Exemplo",
"number": "100",
"complement": "Sala 1",
"district": "Centro",
"city": "São Paulo",
"state": "SP"
}
},
"boleto": {
"due_date": "2026-10-01",
"instruction": "Não receber após a baixa",
"penalty_rate": 2,
"interest_rate": 1,
"cancel_after_due": true,
"days_before_cancel": 5
}
}
A data acima é ilustrativa: para uma nova emissão, escolha hoje ou até 365 dias à frente em America/Sao_Paulo. O preparador evita exemplos com data vencida. A Calebe Pay converte a data ISO para o formato do provedor internamente. Não envie expires_in no boleto.
| Campo | Regra |
|---|---|
amount |
Inteiro de 1 a 100000000 centavos; também sujeito ao limite por cobrança da conta |
reference / description |
Obrigatórios; 1–100 / 1–200 bytes UTF-8 |
customer.name |
2–120 bytes |
customer.document |
String alfanumérica de 11 ou 14 caracteres, sem pontuação; a API local não comprova identidade |
customer.email / phone |
Ambos obrigatórios; e-mail até 254 bytes, telefone com 10 ou 11 dígitos incluindo DDD, sem código do país, pela validação customer_phone_length ativa por padrão; pontuação usual não entra na contagem, limite bruto de 20 bytes |
address.zip_code |
8 dígitos como string |
address.street / number |
2–120 / 1–20 bytes; número é string, por exemplo "S/N" |
address.complement |
Opcional, até 120 bytes |
address.district / city / state |
Bairro/cidade 2–80 bytes; UF brasileira de duas letras |
boleto.due_date |
Obrigatório, YYYY-MM-DD; hoje até +365 dias em São Paulo na primeira emissão |
instruction |
Opcional, até 200 bytes |
penalty_rate / interest_rate |
Percentuais de 0 a 100, no máximo duas casas; padrão 0 |
cancel_after_due / days_before_cancel |
Booleano padrão false / inteiro de 0 a 120, padrão 0 |
Multa, juros e prazo de baixa dependem das condições contratadas para a sua conta. Altere o vencimento de um boleto em aberto com PATCH /v1/transactions/{id}/boleto e solicite estorno integral de um boleto pago com POST /v1/transactions/{id}/refund, ambos com Idempotency-Key. Boleto pago pelo boleto exige conta bancária do próprio pagador; boleto quitado pelo Pix acoplado é estornado pelo Pix. Veja Estornos e vencimento. Não há endpoint público de cancelamento de boleto.
Resposta e idempotência
Nova emissão conhecida retorna 201 {"data": ...}; replay retorna 200 e Idempotency-Replayed: true, ou 202 quando o registro ainda está processing. 202 indica processamento/resultado incerto, não pagamento. Guarde pelo menos id, method, status, environment, simulated e a referência comercial no pedido.
O objeto Transaction contém method: "boleto", boleto_due_date, boleto_url, boleto_digitable_line e boleto_barcode. Os últimos três são strings ou nulos, sem garantia de disponibilidade numa resposta parcial. Não transforme linha/código de barras em número; zeros fazem parte do dado. No simulador e no modo de teste esses três campos permanecem nulos. boleto_url é o PDF do boleto gerado pela Calebe Pay, no nosso domínio (document_url + /boleto.pdf): envie esse link, ou document_url, a quem vai pagar; o seu sistema não precisa reconstruir o boleto. A resposta também traz os campos do Pix no boleto: normalmente o 201 já vem com boleto_pix_copy_paste; se a emissão do Pix demorar, ele vem null e aparece na consulta da transação (GET /v1/transactions/{id}) em seguida. O Pix não é reenviado, e repetir a criação com a mesma chave não emite outro.
amount informa o valor total e retained_amount a soma das tarifas próprias e herdadas, em centavos, preservada na emissão do boleto. O servidor deriva o split automaticamente; não envie recebedores no corpo. split contém {total_fee_amount, merchant_amount, on} ou null no histórico anterior. tenant_fee_id e fee_starts_on identificam apenas a versão própria e podem ser nulos com herança positiva. Replay e refresh preservam o snapshot. Num boleto real pago pelo Pix que o acompanha (paid_with: "pix"), só split passa a trazer o resumo do Pix, calculado com as tarifas de Pix na emissão; retained_amount, tenant_fee_id e fee_starts_on continuam os da emissão do boleto. Valores anteriores a eventuais custos adicionais do provedor, sem comprovar liquidação; veja vigência e histórico.
O namespace idempotente é compartilhado por Pix e boleto. (tenant, Idempotency-Key) identifica uma tentativa. Usar uma chave previamente empregada em Pix no endpoint de boleto retorna 409 idempotency_conflict. O corpo normalizado inclui o método: mantenha corpo, método e chave idênticos no retry. O vencimento original continua válido para recuperar uma tentativa idempotente antiga, sem nova emissão.
reference não é única. A referência enviada ao provedor de pagamento é o ID local txn_..., usado na reconciliação, enquanto a referência comercial permanece na Calebe Pay.
Pix no boleto
Todo boleto real é emitido com um Pix do mesmo valor, sempre que o Pix pode ser emitido para a sua conta e para aquele pagador. Quem recebe o boleto escolhe como pagar: pela linha digitável ou pelo QR Code do Pix, que aparece no PDF do boleto, na página da cobrança (document_url), no portal e no app. Os dois caminhos quitam a mesma cobrança.
| Campo | O que traz |
|---|---|
boleto_pix_copy_paste |
Pix copia e cola. Presente somente enquanto as duas formas podem ser pagas: boleto pending e Pix dentro do prazo. Pago por qualquer uma, vencido o Pix ou em qualquer outro status, volta null. Também vem null enquanto a emissão do Pix não terminou: se ele faltar na resposta da criação, consulte a transação em seguida |
boleto_pix_expires_at |
Prazo do Pix: o fim do dia do vencimento no horário de Brasília (23:59:59, devolvido em UTC). Continua preenchido depois do pagamento ou do prazo; null quando o boleto saiu sem Pix, em boletos emitidos antes do Pix no boleto e enquanto a emissão do Pix não terminou |
paid_with |
null enquanto a cobrança não foi paga; boleto ou pix quando paga, dizendo por qual forma. Um boleto emitido antes do Pix no boleto e pago depois recebe boleto; só os boletos pagos antes dessa mudança (28/09/2026) ficam com null. Num pagamento em dobro, passa a boleto (o Pix é estornado). Para saber se um boleto saiu sem Pix, use boleto_pix_expires_at |
duplicate_payment_at |
Preenchido quando o boleto e o Pix foram pagos; o Pix é estornado automaticamente (veja abaixo). null quando não houve |
{
"data": {
"id": "txn_...",
"method": "boleto",
"status": "pending",
"environment": "production",
"simulated": false,
"livemode": true,
"boleto_due_date": "2026-10-01",
"boleto_digitable_line": "00190000090312855700000000042176215860000001250",
"boleto_barcode": "00192158600000012500000003128557000000004217",
"boleto_url": "https://api.calebepay.com.br/cobranca/txn_.../.../boleto.pdf",
"document_url": "https://api.calebepay.com.br/cobranca/txn_.../...",
"boleto_pix_copy_paste": "00020101021226...6304ABCD",
"boleto_pix_expires_at": "2026-10-02T02:59:59+00:00",
"paid_with": null,
"duplicate_payment_at": null
}
}
- O Pix vale até o fim do dia do vencimento. Depois disso o boleto passa a cobrar multa e juros, que o Pix não carrega: a partir daí só a linha digitável vale. Por isso o boleto que vence hoje só sai com Pix se ainda faltarem pelo menos 5 minutos para a meia-noite.
- Uma cobrança só. O Pix não é outra transação: não aparece em listas, não tem
idpróprio e não gera eventos próprios. Pago o Pix, a cobrança passa apaidcompaid_with: "pix", num únicotransaction.updatedque também trazdata.paid_with. Gere o QR a partir do texto exato deboleto_pix_copy_paste, sem trim, e só enquanto ele vier preenchido. - Quando um é pago, o outro sai de cena. Pago o Pix, a Calebe Pay pede a baixa do boleto automaticamente. Pago o boleto, o Pix deixa de ser mostrado em toda parte, mas um Pix emitido não pode ser cancelado: ele continua aceito pelo banco até o fim do prazo.
- Pagamento em dobro. Se alguém pagar o boleto e o Pix, em qualquer ordem, a Calebe Pay pede o estorno do Pix automaticamente: o valor do Pix volta a quem pagou e a cobrança continua
paid, agora paga pelo boleto (paid_with: "boleto").duplicate_payment_atregistra quando isso foi identificado. Não há segundo evento nem mudança de status. O estorno é processado pelo provedor de pagamento de forma assíncrona e a tarifa do Pix cobrada por ele não é devolvida; se o estorno não puder ser feito na hora, a Calebe Pay tenta de novo e a equipe é avisada. Para reduzir o risco, não reenvie um QR antigo a quem já pagou e mostre a quem paga o estado atual da cobrança. - O PDF é da Calebe Pay.
boleto_urlédocument_url+/boleto.pdf: um PDF gerado pela Calebe Pay a cada abertura, no nosso domínio, com a ficha de compensação (linha digitável e código de barras) e o QR do Pix enquanto ele puder ser pago. Paga, vencida ou em outra situação que não aceita pagamento, a cobrança sai com um carimbo com o status e sem QR. O PDF de um boleto de teste (o do sandbox do provedor de pagamento; no modo de teste e no simuladorboleto_urlé nulo) sai com a marca d'água "DOCUMENTO DE TESTE / NÃO PAGUE" e, enquanto pendente, com o QR do marcador não pagávelCALEBEPAY_SIMULACAO_NAO_PAGAVEL:pix:<id>, que não é um Pix e nenhum banco aceita; pago ou vencido, com o carimbo e sem QR. Como o PDF é montado na hora, o mesmo link sempre mostra o estado atual. - Sem Pix. Quando o Pix não pode ser emitido (por exemplo, Pix não habilitado para a conta, dados do pagador que o Pix não aceita ou vencimento sem prazo útil), o boleto sai normalmente, com
boleto_pix_expires_at: null. Um problema no Pix nunca recusa nem altera o boleto. - Teste, simulador e sandbox. O boleto de teste (chave
cp_test_), o do simulador e o do sandbox do provedor de pagamento, que não tem Pix, trazem emboleto_pix_copy_pasteo marcadorCALEBEPAY_SIMULACAO_NAO_PAGAVEL:pix:<id>enquanto pendentes. Ele não é um Pix: nunca gere QR a partir dele (o PDF de teste da Calebe Pay o desenha só sob a marca d'água de documento de teste). No modo de teste,POST /v1/transactions/{id}/simulatecom{"status": "paid", "paid_with": "pix"}simula o pagamento pelo Pix, e o evento sai comdata.paid_with: "pix"; sempaid_with, o pagamento simulado é pelo boleto.paid_withsó vale comstatus: "paid"num boleto e só aceitaboletooupix(senão,422 validation_error).paid_with: "pix"exige o Pix de teste pendente e no prazo, até 23:59:59 do vencimento: depois disso, ou se o boleto saiu sem Pix, a resposta é409 simulation_not_allowedmesmo com a cobrança pendente — simule o pagamento pelo boleto.
Consultar e confirmar
GET /v1/transactions?method=boleto&reference=pedido-boleto-42&limit=50&offset=0
GET /v1/transactions/{id}
POST /v1/transactions/{id}/refresh
Os dois GET leem o estado local e exigem transactions:read. O refresh de boleto exige transactions:read e boleto:write, consulta o provedor e nunca cria outra cobrança. Um pai pode ler sua subárvore com include_descendants=true; criar no filho exige a chave daquele filho.
No provedor de pagamento, a intenção de pagamento do boleto pode produzir processing antes da confirmação bancária. Somente paid em produção confirma pagamento real, pelo boleto ou pelo Pix que o acompanha: paid_with diz qual, e as duas formas liquidam o mesmo valor. O refresh de um boleto confere as duas. pending e processing não liberam o produto; unknown exige reconciliação. Não deduza baixa/expiração apenas da data local: banco e regras do boleto determinam o estado. A expiração automática pelo prazo vale só para Pix; um boleto real só passa a expired quando o banco informa a baixa.
As mudanças de status chegam pelo webhook transaction.updated, descrito no guia de integração. Mantenha mesmo assim um polling limitado no seu backend, retome pendências após reinícios e respeite o rate limit. ID do provedor, valor e referência retornados no refresh devem coincidir com a transação local.
Diagnóstico sem nova emissão
Na primeira recusa confirmada, 502 provider_rejected inclui error.transaction_id e os campos diretos nullable provider_error_code, provider_error_message e provider_http_status. Consulte o ID por GET local para ler o diagnóstico persistido. O HTTP remoto pode ser 200 em uma rejeição de negócio; ele não substitui o status da transação.
Uma resposta incerta continua sendo 202 com data.status: "unknown" e os diagnósticos disponíveis. Repetir a mesma chave e o mesmo corpo de uma tentativa failed retorna 200 com o registro anterior, sem novo boleto no provedor. Preserve inclusive o vencimento original. Se o histórico não capturou detalhes, eles permanecem nulos: não emita outra cobrança para tentar reconstruir o erro antigo. Veja o contrato completo de diagnóstico.
Uma falha ao consultar o provedor em /refresh pode trazer diagnóstico atual em error, mas não altera o estado nem o diagnóstico da criação persistidos. Use o request_id do erro para rastrear essa consulta separadamente. O refresh de boleto consulta o boleto e o Pix que o acompanha: se uma das consultas aplica uma mudança (por exemplo, o Pix pago) e a outra falha, a resposta é 200 com o estado novo e a consulta que falhou é repetida em segundo plano; 502 provider_refresh_failed só quando nada pôde ser aplicado.
| Código | Ação |
|---|---|
403 insufficient_scope |
Emitir chave autorizada com boleto:write; a chave atual não ganha permissão automaticamente |
422 provider_not_configured |
Boleto ainda não está habilitado para a conta; fale com a Calebe Pay |
422 provider_method_disabled |
Boleto foi desabilitado para a conta; fale com a Calebe Pay |
422 validation_error |
Corrigir endereço, vencimento, valor ou opções antes de nova solicitação válida |
422 split_* |
Configuração de recebedores ou taxas incompatível; emissão recusada antes da reserva. Solicite revisão à Calebe Pay |
422 fee_exceeds_amount |
Soma das tarifas de boleto maior que o valor da nova cobrança; emissão recusada. Fale com a Calebe Pay para revisar a tarifa |
409 idempotency_conflict |
Recuperar payload/método/chave originais; não trocar chave para contornar |
403 live_payments_disabled / live_payment_out_of_scope |
Produção ainda não liberada ou cobrança fora da autorização; fale com a Calebe Pay |
502 provider_rejected |
Recusa confirmada; GET pelo error.transaction_id recupera diagnóstico local sem reenvio |
202, timeout, 503 reconciliation_required |
Pode haver cobrança; preservar os dados e reconciliar antes de qualquer nova tentativa |
502 provider_refresh_failed |
Consulta falhou/divergiu e nada foi aplicado; estado local preservado; investigar sem criar outro boleto |
Para agentes: implemente esse fluxo no backend, persista payload/chave antes da rede, reconheça todos os estados e ambientes, e use o OpenAPI como contrato. Para estornar boleto pago ou alterar vencimento, use os endpoints documentados em Estornos e vencimento. Não invente /cancel ou endpoint público de cadastro de webhook. Não gere um PDF de boleto próprio: use boleto_url, que já é o PDF da Calebe Pay com o QR do Pix. Mostre o Pix do boleto só a partir de boleto_pix_copy_paste preenchido, em produção, e nunca a partir do marcador de simulação.