1. Separe o título financeiro da tentativa de emissão
O título do ERP representa a obrigação comercial. A transação Calebe Pay representa uma tentativa de cobrança daquele título. Salve a relação entre o ID do título, a referência comercial, o payload original, a chave de idempotência e o transaction.id retornado pela API.
Crie a chave e grave o payload antes da chamada. Use uma tentativa por decisão de emissão e recupere essa tentativa nos retries. Uma fila de trabalho pode continuar o envio após um reinício, desde que preserve o corpo e a chave já salvos e não crie outra cobrança para resolver uma resposta incerta.
Para emitir em produção, a conta deve estar habilitada para boleto e a chave precisa de boleto:write e transactions:read. Boleto não é uma permissão implícita de toda chave. Comece com cp_test_ no seu backend; o frontend não deve receber o segredo.
2. Mapeie os dados do ERP para o contrato da API
Envie POST /v1/boleto com X-API-Key, Idempotency-Key e Content-Type: application/json. A API key determina a conta que emitirá. Use os dados legítimos do pagador e preserve números de documento, CEP e telefone como strings.
O vencimento da primeira emissão deve estar entre hoje e 365 dias à frente, considerando America/Sao_Paulo. A API recebe a data em YYYY-MM-DD. Não envie expires_in, pois esse campo pertence ao Pix.
| No ERP | Na API Calebe Pay |
|---|---|
| Valor do título | amount: inteiro em centavos; 1250 significa R$ 12,50. |
| Identificação comercial | reference e description, com até 100 e 200 bytes, respectivamente. |
| Cadastro do pagador | customer: nome, documento, e-mail e telefone obrigatórios. |
| Endereço de cobrança | customer.address: zip_code, street, number, district, city e state; complement é opcional. |
| Vencimento | boleto.due_date: data ISO YYYY-MM-DD. |
| Condições do boleto | boleto.instruction, penalty_rate, interest_rate, cancel_after_due e days_before_cancel. |
3. Defina multa, juros e prazo de baixa na emissão
penalty_rate e interest_rate recebem percentuais de 0 a 100 com até duas casas decimais, não valores em centavos. O padrão é zero. instruction é opcional e comporta até 200 bytes; days_before_cancel aceita de 0 a 120 e acompanha a opção cancel_after_due.
Essas condições dependem do contrato da conta e devem ser definidas no payload original. A API atual não oferece endpoint para alterar, cancelar ou estornar um boleto depois da emissão. A opção de baixa enviada na criação não deve ser confundida com uma ordem de cancelamento posterior.
Para títulos mensais, o calendário e a criação de cada obrigação continuam sob responsabilidade do ERP. Quando chegar a data de uma nova emissão, o ERP prepara deliberadamente outro título ou tentativa, com seu payload e sua chave. Este fluxo não pressupõe um endpoint de recorrência.
4. Persista a resposta sem perder o histórico
A primeira criação conhecida retorna 201. Um replay retorna o mesmo registro com 200, ou 202 se ainda estiver em processamento. Salve o ID da transação, método, status, ambiente, vencimento e os campos de documento disponibilizados. O contrato completo é definido pelo OpenAPI.
boleto_url, boleto_digitable_line e boleto_barcode são strings ou nulos. Não converta linha digitável ou código de barras em números: zeros fazem parte da informação. Uma resposta parcial pode não ter o documento pronto. No simulador, esses três campos permanecem nulos.
Use o documento devolvido pela integração quando estiver disponível. Não reconstrua um boleto bancário a partir de campos incompletos e não apresente uma cobrança simulada como documento pagável.
5. Trate timeout e repetição sem duplicar a cobrança
Em uma falha de rede, a emissão pode ter chegado à API. Preserve inclusive o vencimento original ao repetir uma tentativa: recalcular a data muda o pedido. O servidor compara a chave e o corpo; uma mudança retorna 409 idempotency_conflict.
O namespace de idempotência de Pix e boleto é compartilhado dentro da conta e do modo de operação. Não reutilize no boleto uma chave já utilizada para Pix. A referência comercial não substitui a chave e pode corresponder a mais de uma transação.
Uma recusa confirmada pode retornar 502 provider_rejected com error.transaction_id. Consulte esse ID para recuperar o diagnóstico persistido. Em uma resposta unknown, investigue a tentativa existente; não emita outro boleto automaticamente. GET consulta o estado local, enquanto refresh consulta o provedor sem criar uma cobrança.
GET /v1/transactions?method=boleto&reference=pedido-42
GET /v1/transactions/{id}
POST /v1/transactions/{id}/refresh6. Dê baixa no ERP somente após confirmação
Receba transaction.updated em um endpoint controlado pela sua empresa e valide Calebe-Signature antes de processar o corpo. A assinatura usa HMAC-SHA256 com o segredo de webhook da conta e os bytes crus da requisição. Persista o evento antes de responder 2xx e deduplique pelo id do evento.
O evento registra o estado no momento em que ocorreu. Se chegar atrasado ou repetido, sua aplicação não deve contabilizar a baixa outra vez nem inferir uma ordem apenas pelo recebimento. Correlacione o transaction.id ao título e consulte o estado atual quando necessário.
processing pode representar intenção de pagamento ainda sem confirmação bancária. Somente paid em produção, com livemode: true e simulated: false, confirma dinheiro real. Vencimento ultrapassado também não prova baixa: um boleto real só fica expired quando o banco informa esse estado.
Mantenha uma rotina limitada de conciliação para títulos pendentes, inclusive após reinícios ou indisponibilidade do webhook. Respeite o rate limit; o refresh exige transactions:read e boleto:write. Tarifas e split retornados descrevem a previsão capturada na emissão e não são um comprovante de liquidação.
7. Valide o ciclo completo antes de operar
Com uma chave cp_test_, valide a criação, a consulta, a repetição idempotente e a mudança de uma transação pendente usando /simulate. O evento de teste deve chegar a um webhook configurado no modo de teste. O sandbox remoto de boleto é outro ambiente possível, sujeito à configuração da conta; simulated: false com environment: sandbox ainda não representa dinheiro real.
Antes de emitir títulos reais, confirme a habilitação de boleto e produção, revise as condições de cobrança e configure a chave e os webhooks de produção no servidor. Seu ERP deve distinguir testes de recebimentos reais mesmo quando o status de ambos for paid.