Como integrar
Visão geral
O Boleto OnLine registra o boleto direto na API do banco — suporta todos os bancos credenciados (lista logo abaixo) pelo mesmo motor (hoje validado em produção com Santander e Itaú) — não existe arquivo de remessa/CNAB nem processamento em lote. Toda operação é síncrona: a chamada à API já volta com o resultado (código de barras, linha digitável, ou o erro real que o banco recusou). O ciclo de vida de um boleto tem quatro fases (a última é opcional):
1. Configurar
Uma vez por conta bancária: credenciais, certificado e dados do cedente.
2. Emitir
A cada cobrança: o boleto é registrado no banco e o cliente recebe a linha digitável.
3. Verificar pagamento
Periodicamente: quem integrou consulta o banco para saber o que foi pago.
4. Cancelar (se precisar)
Opcional: dar baixa num boleto ainda não pago — .
Bancos credenciados
O Boleto OnLine não trabalha só com um banco — o motor de registro suporta todos os
bancos abaixo, pelo mesmo mecanismo (só muda o valor de banco.TipoCobranca
na configuração da conta). O número não é o código FEBRABAN do banco.
Validado = a EXATA já rodou o fluxo inteiro (emitir → registrar → pagar → webhook) em produção com esse banco. Os demais são suportados pelo mesmo motor de registro, mas ainda não foram validados aqui — dependem de credencial/homologação junto ao banco.
Como um boleto é criado
POST /api/accounts/{account}/bankslips
(aba )
envia os dados do título (valor, vencimento, sacado) direto para a API do banco — o
Nosso Número é gerado pelo Boleto OnLine, não é informado por
quem chama. Cada conta tem a sua sequência: a emissão usa o
Nosso número atual da conta + 1. Esse valor fica na configuração da conta
(aba Cedente) e pode ser ajustado, por exemplo para continuar a numeração de um sistema
anterior ou para separar faixas quando outro sistema ainda emite na mesma conta. Ele não
pode ficar abaixo do maior nosso número já emitido na conta. Emissão recusada não consome
número: o próximo boleto reaproveita o número que falhou. O banco valida, registra e
devolve na hora o código de barras e a linha digitável — não há espera nem processamento
assíncrono. Se o banco recusar (dado inválido, limite, etc.), o erro real dele volta na
resposta, com o campo recusado quando o banco informa.
Verificação automática de pagamento (o Boleto OnLine faz por você)
O banco não avisa quando um boleto é pago — não existe webhook/callback do lado do banco. Mas você não precisa ficar consultando: o próprio Boleto OnLine roda um verificador periódico interno, contra todas as contas configuradas, e já marca cada título como pago no seu histórico assim que detecta.
Toda rodada do verificador (a cada 15 minutos) fica registrada na tela Verificação de Pagamentos — inclusive quando não encontra nada de novo. É como você confirma que o monitoramento está ativo, e recebe um alerta (e-mail/WhatsApp) se ele parar de funcionar por 3 rodadas seguidas (cerca de 45 minutos).
Duas formas de saber que um boleto foi pago:
1. Webhook (recomendado)
Cadastre uma webhook_url na conta (aba Configurar conta). Assim que o verificador detecta o pagamento, o Boleto OnLine faz um POST assinado pra essa URL — sem você precisar perguntar nada.
2. Consultar quando quiser
Sem webhook configurado (ou como reforço), continue chamando GET /api/accounts/{account}/bankslips (aba ) quando precisar — ela sempre reflete o estado real do banco.
O corpo, a assinatura e o passo a passo de validação estão na aba .
Aviso de vencimento do certificado
Quando o certificado vence, a emissão de boletos daquela conta fica interrompida
até um novo certificado ser enviado. Por isso o Boleto OnLine avisa automaticamente
por e-mail (email_notificacao) e/ou
WhatsApp (whatsapp_notificacao) — os dois
canais, se os dois estiverem preenchidos.
O aviso não sai todo dia: só nos marcos de 30, 15, 7 e 1 dia antes do vencimento, e depois disso todo dia enquanto o certificado continuar vencido (a emissão continua interrompida até você trocar). A urgência da mensagem escala conforme o prazo (Aviso → URGENTE no dia anterior/no dia → CRÍTICO depois de vencido).
Na tela Configurar conta, ao lado de cada campo (e-mail e WhatsApp) tem um botão "Testar aviso" — dispara o mesmo texto oficial na hora, sem precisar esperar o certificado vencer de verdade nem o verificador automático rodar.
Enviar o boleto direto ao cliente (opcional)
Além de devolver o link na resposta da
emissão, o Boleto OnLine pode entregar o boleto sozinho por e-mail e/ou WhatsApp direto
ao cliente final (Sacado) — desligado por padrão, precisa ligar por conta.
Dois passos, os dois na tela Configurar conta, seção "Notificar cliente ao emitir boleto":
1. Ligar o interruptor da conta
Sem isso, os campos notificar_email/notificar_whatsapp na emissão (aba ) não têm efeito nenhum — é proposital, evita envio sem querer por quem só passa esse dado por outro motivo.
2. Token de notificação próprio (opcional)
Por padrão os envios saem pelo canal compartilhado da plataforma. Se o cliente tiver o próprio WhatsApp Business, configure o token dele aqui — os envios passam a sair pelo número dele.
Botões "Testar e-mail" / "Testar WhatsApp" disparam um envio real com dados de exemplo (sem precisar emitir um boleto de verdade) — pedem o destino na hora, não usam o e-mail/WhatsApp de aviso de certificado.
Como autenticar
Toda requisição vai para https://boleto.seacweb.com.br/api/...,
com o token do seu cliente (tenant) no cabeçalho Authorization
e o corpo (quando houver) em JSON. O token é único por cliente/integração e nunca deve ser compartilhado.
POST /api/accounts/{account}/bankslips HTTP/1.1
Host: boleto.seacweb.com.br
Authorization: Bearer <SEU_TOKEN_AQUI>
Content-Type: application/json
{ ... } Toda resposta segue o mesmo envelope, sucesso ou erro:
{
"status": "success",
"message": "descrição legível do resultado",
"data": { ... }
}
Sem token, com token inválido ou de um cliente diferente, a resposta é sempre
HTTP 401.
Novo cliente/integração: solicite o token ao administrador da plataforma (onboarding manual).
Configurar uma conta bancária
POST /api/accounts — chamado
uma vez (ou sempre que a credencial/certificado mudar). Pode ser feito por aqui
(tela Configurar conta) ou via API,
útil para integrações que provisionam contas automaticamente.
{
"account": "santander",
"bank": { "code": 2 },
"webservice": { "environment": 0, "version": "V1" },
"company": {
"tax_id_type": 1,
"tax_id": "01183645000170",
"name": "MINHA EMPRESA LTDA",
"address": {
"street": "RUA TESTE", "number": "100", "district": "CENTRO",
"city": "CASIMIRO DE ABREU", "state": "RJ", "zip_code": "28860000"
},
"agency": "3190", "agency_digit": "5",
"account": "9860193", "account_digit": "1",
"agreement": "9860193",
"modality": "101"
},
"credentials": { "client_id": "...", "client_secret": "...", "scope": "" },
"certificate": {
"crt": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
"key": "-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----"
},
"notification_email": "financeiro@meucliente.com.br",
"notification_whatsapp": "+5511999999999"
} account é o apelido dessa configuração (ex: santander, itau-filial-2) — é o identificador usado nas rotas /api/accounts/{account}/... e o que você vincula no SEAC. Só minúsculas, números e hífen, até 40 caracteres, sem começar/terminar com hífen. Opcional na criação (default padrao); não muda depois de criado. Use GET /api/accounts para listar os apelidos existentes.
bank.code é o código interno do motor de registro, não o número FEBRABAN do banco — ver aba pra lista completa. Santander = 2.
webservice.environment: 0 = Produção, 1 = Homologação, 2 = SandBox.
certificate.crt/key vão como CONTEÚDO (texto do arquivo PEM), não caminho de arquivo. Se o certificado só existir como .pfx, converta antes (openssl pkcs12 -clcerts -nokeys / -nocerts -nodes) — a tela web faz isso sozinha a partir do .pfx, a API ainda exige o par já separado.
Santander: não informe credentials.key_user — o Workspace é criado automaticamente na primeira configuração, usando company.agreement.
Santander: company.modality é obrigatório — código da carteira informado pelo banco na abertura do convênio (ex: "101"). O boleto é registrado mesmo sem ele, mas o código de barras/linha digitável saem com esse campo zerado — o pagador não consegue localizar o boleto ao digitar ou ler o código.
notification_whatsapp é opcional (formato internacional, com +55) — se vazio, o aviso de certificado só sai por e-mail.
Emitir / registrar um boleto
POST /api/accounts/{account}/bankslips
{
"reference": "ST0001",
"value": 150.00,
"due_date": "2026-12-31",
"payer": {
"name": "CLIENTE TESTE",
"document": "11144477735",
"address": {
"street": "RUA TESTE", "number": "100", "district": "CENTRO",
"city": "CASIMIRO DE ABREU", "state": "RJ", "zip_code": "28860000"
}
},
"notify": { "email": "cliente@exemplo.com.br", "whatsapp": "+5511999999999" }
} Resposta (sucesso, HTTP 201):
{
"status": "success",
"message": "Boleto created successfully.",
"data": {
"our_number": "00000042",
"reference": "ST0001",
"barcode": "...",
"digitable_line": "...",
"due_date": "2026-12-31",
"link": "https://boleto.seacweb.com.br/boleto_view.php?id=42&sig=..."
}
} our_number é gerado pelo Boleto OnLine — nunca é informado por quem chama (evita cada integração ter que implementar o próprio contador sem colisão).
Sem boleto em dobro: se a conta já tem um boleto ativo (emitido e não cancelado) com o mesmo reference, o mesmo value e o mesmo due_date (o vencimento atual, já considerando alteração), a emissão não registra outro: devolve o boleto existente (HTTP 200, mesmos campos, com data.already_issued = true) e não reenvia a notificação. Parcelas de um mesmo documento com o mesmo valor saem cada uma com seu boleto, porque o vencimento é diferente. Para emitir de novo a mesma parcela, cancele o boleto anterior. Se o existente já foi pago, a emissão é recusada (HTTP 409).
Nosso número já registrado no banco: se o banco responder que o nosso número já existe (registrado por outro sistema com o mesmo convênio), o Boleto OnLine pula para o próximo e tenta de novo sozinho.
Santander: reference tem limite de 15 caracteres. Endereço completo do payer é obrigatório.
data.link é a página que o CLIENTE FINAL abre para ver e pagar o boleto (valor, vencimento, linha digitável com botão "Copiar", botão "Baixar PDF") — repasse por SMS/e-mail/WhatsApp. É público (sem token), montado em runtime a cada acesso — não existe PDF salvo em disco. Sem preview de PDF embutido de propósito (funciona no desktop, mas falha em boa parte dos navegadores mobile) — copiar a linha digitável é o caminho principal de pagamento.
POST /api/accounts/{account}/bankslips/preview (mesmo corpo, sem notify) gera o boleto localmente (em runtime, sem falar com o banco, sem registrar nada) e devolve data.pdf pronto (base64) — para quem quer conferir antes de emitir de verdade.
GET /api/accounts/{account}/bankslips/{our_number} reobtém o status/link de um boleto já emitido, sem precisar reenviar o título inteiro. GET .../bankslips/pdf/{our_number} reobtém o PDF/código de barras.
notify é opcional — se informado, entrega o boleto direto ao cliente por e-mail/WhatsApp somente se a conta tiver essa notificação ligada (aba ). Sem o interruptor ligado, esse campo é ignorado.
payer.email / payer.phone são opcionais — quando informados, ficam guardados no boleto e alimentam a (aviso automático de vencimento ao sacado).
Alterar o vencimento de um boleto em aberto
PATCH /api/accounts/{account}/bankslips/{our_number} — corpo JSON com
due_date (yyyy-mm-dd), obrigatório.
O restante do título (pagador, referência) é mantido como foi emitido.
PATCH /api/accounts/santander/bankslips/00000042
{ "due_date": "2026-10-15" } Resposta (sucesso) — mesmo formato de "Emitir boleto":
{
"status": "success",
"message": "Bankslip updated successfully!",
"data": { "our_number": "00000042", "barcode": "...", "digitable_line": "...", "due_date": "2026-10-15", "link": "..." }
} Cancelar (dar baixa em) um boleto já emitido
POST /api/accounts/{account}/bankslips/cancel/{our_number} —
sem corpo (o resto dos dados da baixa já vem da própria configuração da conta, confirmado
no fonte do conector do banco).
POST /api/accounts/santander/bankslips/cancel/00000042 Resposta (sucesso) — mesmo formato de "Emitir boleto":
{
"status": "success",
"message": "Boleto cancel has been requested successfully!",
"data": { "our_number": "00000042", "barcode": null, "digitable_line": null }
} É uma ação real junto ao banco, não pode ser desfeita. Uma vez cancelado, o título não pode ser reativado — se precisar cobrar de novo, emita um boleto novo.
Também dá pra cancelar sem chamar a API: no painel, na tela Boletos Emitidos, menu de ações da linha → "Cancelar boleto" (só aparece em boletos emitidos com sucesso e ainda não cancelados). Quem integrou via SEAC também tem essa opção direto na tela de Contas a Receber, menu Imprimir → "Cancelar Boleto".
Um boleto cancelado aparece com a situação Cancelado na coluna "Situação" da tela Boletos Emitidos (também dá pra filtrar por essa situação).
A tela Boletos Emitidos mostra uma linha por boleto, sempre com o estado mais recente (se foi cancelado depois de emitido, a linha já aparece como Cancelado). Para ver a linha do tempo completa — emissão, tentativas com erro, cancelamento, cada uma com data e hora — use "Ver histórico" no menu de ações da linha.
Conferência de recebimentos: no filtro, "Período por" escolhe a qual data o período se aplica: data de emissão (padrão; mostra todos os boletos), data de crédito (o dia em que o valor entrou na conta, que é o que aparece no extrato) ou data de pagamento. Com crédito ou pagamento, a tela mostra só os boletos pagos; para conferir o recebido com o extrato, escolha data de crédito antes de imprimir. O botão Imprimir conferência gera uma listagem com os mesmos filtros, sem limite de linhas, agrupada por data de crédito, com o subtotal de cada dia (o valor a procurar no extrato) e o total recebido. O botão Exportar Excel gera a mesma listagem em planilha, um boleto por linha.
Consultar boletos pagos (baixas)
GET /api/accounts/{account}/bankslips?paid_from=&paid_to= —
uso típico: consultar periodicamente para processar as baixas dos boletos já pagos.
GET /api/accounts/santander/bankslips?paid_from=2026-07-01&paid_to=2026-08-25 Resposta:
{
"status": "success",
"message": "Paid bankslips retrieved successfully!",
"data": {
"total": 1,
"bankslips": [
{
"our_number": "00000042",
"reference": "ST0001",
"value": 150.00,
"paid_value": 150.00,
"due_date": "2026-12-31",
"paid_at": "2026-08-20",
"payer_name": "CLIENTE TESTE",
"payer_document": "11144477735"
}
]
}
} paid_from/paid_to em yyyy-mm-dd, ambos obrigatórios.
Santander: período máximo de consulta é de aproximadamente 3 meses retroativos.
O que é
Quando o verificador automático (ver aba
)
detecta que um boleto foi pago, o Boleto OnLine faz um POST
para a webhook_url cadastrada naquela conta
(tela Configurar conta). Sem
webhook_url, nada é enviado — você consulta quando quiser.
O contrato segue o mesmo padrão do resto da API: envelope
{ event, sent_at, data }, campos
snake_case em inglês, valores monetários
como número e datas em yyyy-mm-dd.
Formato
POST /seu-endpoint HTTP/1.1
Content-Type: application/json
X-Webhook-Signature: sha256=<HMAC-SHA256 hex do corpo cru>
Authorization: Bearer <token do destino> (opcional -- ver abaixo)
{
"event": "bankslip.paid",
"sent_at": "2026-08-28T02:00:00+00:00",
"data": {
"account": "santander",
"reference": "ST0001",
"our_number": "00000001",
"value": 150.00,
"paid_value": 150.00,
"interest": 0.00,
"discount": 0.00,
"due_date": "2026-12-31",
"paid_at": "2026-12-20",
"credit_date": "2026-12-21",
"payer_name": "FULANO DE TAL"
}
} | Campo | Descrição |
|---|---|
event | Sempre bankslip.paid hoje. Trate outros valores como ignoráveis. |
sent_at | Momento do envio, ISO 8601 UTC. |
data.account | Nome da conta bancária (o mesmo usado nas rotas /api/accounts/{account}/...). |
data.reference | Seu número de documento, informado na emissão. |
data.our_number | Nosso Número gerado pelo Boleto OnLine. É a chave para casar o título do seu lado. |
data.value | Valor do documento. |
data.paid_value | Valor efetivamente pago (pode divergir do documento). |
data.interest | Multa/juros que o banco aplicou na liquidação. 0 no pagamento em dia; null se o banco não informou. |
data.discount | Desconto aplicado pelo banco na liquidação. 0/null quando não houver. |
data.due_date | Vencimento, yyyy-mm-dd. |
data.paid_at | Data da liquidação (quando o sacado pagou), yyyy-mm-dd. Use no seu contas a receber. |
data.credit_date | Data do crédito na conta (o que aparece no extrato, normalmente D+1), yyyy-mm-dd. Use na conciliação bancária. Se o banco não informar, vem igual a paid_at. |
data.payer_name | Nome do sacado (pode vir vazio em emissões antigas). |
Validar a assinatura
O header X-Webhook-Signature é
sha256= + o HMAC-SHA256 (hex) do
corpo cru recebido. Recalcule e compare com igualdade em tempo constante:
$corpo = file_get_contents('php://input');
$esperado = 'sha256=' . hash_hmac('sha256', $corpo, $SEGREDO);
if (!hash_equals($esperado, $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$payload = json_decode($corpo, true); Qual é o SEGREDO:
se você não configurou Token de autenticação do webhook,
é o token do seu tenant (o mesmo que você usa no header
Authorization para chamar a API).
Se configurou, é esse token — o mesmo que chega no
Authorization: Bearer do webhook.
Destino que exige Authorization: Bearer
(um sistema que valida token antes de olhar o corpo): preencha o campo opcional
Token de autenticação do webhook na tela
Configurar conta. Ele vai no header Authorization: Bearer <token>
e passa a ser o segredo da assinatura. Deixe em branco se o destino não exigir Bearer.
Entrega e retentativa
Responda 2xx para confirmar o recebimento. Qualquer outro código (ou timeout de 10s) conta como falha.
Retentativa: uma falha é reentregue nas rodadas seguintes do verificador (a cada 15 minutos), até 80 tentativas por título — cerca de 20 horas até desistir. Na tela Verificação de Pagamentos, cada reenvio aparece na rodada em que aconteceu ("webhook reenviado e entregue", com o número da tentativa), e a rodada original que registrou a falha passa a indicar quando o webhook foi entregue depois.
Idempotência é sua responsabilidade: trate receber o mesmo our_number mais de uma vez sem duplicar a baixa.
Sem tempo real: o verificador roda periodicamente — o ganho é não precisar implementar o polling você mesmo, não latência zero.
Régua de cobrança
Com a régua ligada, o Boleto OnLine avisa o próprio sacado por e-mail (e WhatsApp, opcional) em marcos configuráveis antes e depois do vencimento, sempre com o link de pagamento. É opcional, por conta, e roda junto com o verificador de pagamentos (a cada 15 minutos).
1. Informe o contato do sacado na emissão. Campos opcionais no corpo de
POST /api/accounts/{account}/bankslips:
payer.email e
payer.phone. Sem contato guardado, o boleto
não entra na régua (fica registrado como "pulado"). O notify.email /
notify.whatsapp da mesma chamada também serve.
2. Ligue a régua na conta. Painel → Configurar conta
→ aba Geral → "Régua de cobrança". Defina os marcos (dias em relação ao vencimento: negativo = antes,
0 = no dia, positivo = depois — padrão -5,-1,0,1,5,10)
e os canais.
WhatsApp: só dispara se a conta tiver um token EasyChat próprio configurado (cada mensagem WhatsApp tem custo). O e-mail usa o canal da plataforma, sem custo.
Cobrar na hora
POST /api/accounts/{account}/bankslips/remind/{our_number}
— dispara o lembrete imediatamente para um boleto em aberto (independe dos marcos). Corpo opcional
{ "channels": ["email","whatsapp"] }; sem ele, usa os canais da conta.
No painel: Boletos Emitidos → menu da linha → "Cobrar agora".
POST /api/accounts/santander/bankslips/remind/00000042
{ "channels": ["email"] } {
"status": "success",
"message": "Reminder sent successfully!",
"data": { "sent_channels": 1, "detail": "" }
} O acompanhamento (lembretes enviados, taxa de recuperação) aparece no Dashboard, seção Cobrança.
Formato de erro e códigos HTTP
{
"status": "error",
"message": "descrição do problema",
"data": null
} | HTTP | Significado |
|---|---|
400 | JSON inválido no corpo da requisição |
401 | Token ausente ou inválido |
404 | Rota inexistente, ou recurso (conta/boleto) não encontrado |
422 | Campo obrigatório faltando/inválido, ou o banco recusou a operação (mensagem real do banco em message) |
500 | Erro interno/infraestrutura (não é problema no que você enviou) |
503 | Serviço de autenticação central (bd_system) temporariamente indisponível |