BrBoleto
Emissão de Boletos Bancários em Ruby.
O que essa gem faz?
- Boleto bancário (apenas os cálculos para o boleto, sem a interface) para os bancos:
- Banco do Brasil
- Bradesco (em andamento)
- Caixa
- Cecred
- Itaú
- Santander (em andamento)
- Sicoob
- Sicredi
- Unicred
- Arquivo de remessa para os Bancos:
- Banco do Brasil (CNAB240 e CNAB400)
- Bradesco (CNAB240 e CNAB400)
- Caixa (CNAB240 e CNAB400)
- Cecred (CNAB240)
- Itaú (CNAB240 e CNAB400)
- Santander (CNAB240 e CNAB400)
- Sicoob (CNAB240 e CNAB400)
- Sicredi (CNAB240 e CNAB400)
- Unicred (CNAB240 e CNAB400)
- Arquivo de retorno para os Bancos:
- Banco do Brasil (CNAB240 e CNAB400)
- Bradesco (CNAB240 e CNAB400)
- Caixa (CNAB240 e CNAB400)
- Cecred (CNAB240)
- Itaú (CNAB240 e CNAB400)
- Santander (CNAB240 e CNAB400)
- Sicoob (CNAB240 e CNAB400)
- Sicredi (CNAB240 e CNAB400)
- Unicred (CNAB240 e CNAB400)
Instalação
Manualmente
gem install br_boleto
Gemfile
gem 'br_boleto'
Documentação
Seguimos as documentações descritas abaixo:
- [Banco do Brasil](documentacoes_boletos/Banco do Brasil)
- Bradesco
- Caixa
- Cecred
- Itaú
- Santander
- Sicoob
- Sicredi
- Unicred
Bancos Suportados
Para todos os bancos e carteiras implementadas, seguimos as documentações que estão dentro do repositório:
Boletos
Nome do Banco | Carteiras Suportadas | Testada/Homologada no banco | Autor |
---|---|---|---|
Sicoob | 1, 3. | Homologado dia 03/08/2015 | Bruno M. Mergen |
Caixa | 1, 2. | Homologado dia 11/11/2016 | Bruno M. Mergen |
Cecred | 1. | Homologado dia 07/11/2016 | Ricardo Zanuzzo |
Unicred | 09. | Homologado dia 11/11/2016 | Ricardo Zanuzzo |
Sicredi | 1, 3. | Homologado dia 17/11/2016 | Ricardo Zanuzzo |
Banco do Brasil | 11, 12, 15, 16, 17, 18, 31, 51. | Homologado dia 15/12/2016 | Ricardo Zanuzzo |
Itaú | 104, 105, 107, 108, 109, 112, 113, 116, 117, 119, 121, 122, 126, 131, 134, 135, 136, 142, 143, 146, 147, 150, 168, 169, 174, 175, 180, 191, 196, 198. | Homologado dia 16/12/2016 | Ricardo Zanuzzo |
Bradesco | 06, 09, 19, 21, 22. | Pendente | Ricardo Zanuzzo |
Santander | 101, 102, 121. | Pendente | Ricardo Zanuzzo |
Arquivos de remessa
Nome do Banco | CNAB | Testada/Homologada no banco | Autor |
---|---|---|---|
Sicoob | 240 | Homologado dia 07/08/2015 | Bruno M. Mergen |
Sicoob | 400 | Pendente | Bruno M. Mergen |
Caixa | 240 | Homologado dia 11/11/2016 | Bruno M. Merge |
Caixa | 400 | Homologado dia 29/12/2016 | Ricardo Zanuzzo |
Cecred | 240 | Homologado dia 07/11/2016 | Ricardo Zanuzzo |
Unicred | 240 | Homologado dia 11/11/2016 | Ricardo Zanuzzo |
Unicred | 400 | Pendente | Ricardo Zanuzzo |
Sicredi | 240 | Homologado dia 17/11/2016 | Ricardo Zanuzzo |
Sicredi | 400 | Pendente | Ricardo Zanuzzo |
Banco do Brasil | 240 | Homologado dia 30/12/2016 | Ricardo Zanuzzo |
Banco do Brasil | 400 | Homologado dia 15/12/2016 | Ricardo Zanuzzo |
Itaú | 240 | Pendente | Ricardo Zanuzzo |
Itaú | 400 | Homologado dia 16/12/2016 | Ricardo Zanuzzo |
Bradesco | 240 | Pendente | Ricardo Zanuzzo |
Bradesco | 400 | Pendente | Ricardo Zanuzzo |
Santander | 240 | Pendente | Ricardo Zanuzzo |
Santander | 400 | Pendente | Ricardo Zanuzzo |
Como usar
Começando
Em todas as classes desenvolvidas é possível instanciar objetos em forma de Hash
ou Block
. Exemplo:
obj1 = BrBoleto::Pagador.new(nome: 'João')
obj2 = BrBoleto::Pagador.new do |pagador|
pagador.nome = 'João'
end
As associações também podem ser instanciadas em forma de Hash
ou Block
. Exemplo:
boleto1 = BrBoleto::Boleto::Sicoob.new do |boleto|
boleto.conta do |ct|
ct.agencia = 1234
ct.carteira = 1
end
end
boleto1.conta.agencia
# => "1234"
# OU
boleto2 = BrBoleto::Boleto::Sicoob.new({
conta: {
agencia: 7465,
carteira: 2
}
}
boleto2.conta.agencia
# => "7465"
# OU
conta = BrBoleto::Conta::Sicoob.new(agencia: 4522)
boleto2 = BrBoleto::Boleto::Sicoob.new(conta: conta)
boleto2.conta.agencia
# => "4522"
Classes auxiliares
Devido a falta de padronização de regras e nomenclaturas entre os banco, essa gem é composta por classes auxiliares para conseguir manter o minimo de padronização com sua utilização e nomenclaturas.
Conta
Para gerar boletos e remessas é necessário de uma conta bancária, certo? Pensando nisso foi criado uma classe onde contém todas as regras e informações referente a conta bancária. Existe uma classe para cada banco desenvolvido. Vejamos um exemplo com o banco Sicoob:
conta = BrBoleto::Conta::Sicoob.new({
codigo_beneficiario: '253167',
codigo_beneficiario_dv: '4', # Se não passar o dv irá gerar automaticamente
conta_corrente: '887469',
conta_corrente_dv: '7', # Se não passar o dv irá gerar automaticamente
agencia: '3069',
carteira: '1',
modalidade: '02' ,
razao_social: 'Razao Social emitente',
cpf_cnpj: '98137264000196',
endereco: 'Rua nome da rua, 9999',
})
Pagador
O pagador é o "cliente" que vai pagar o boleto/cobrança. É utilizado no boleto e no Pagamento da remessa.
pagador = BrBoleto::Pagador.new do |pagador|
pagador.nome = 'João da Silva'
pagador.cpf_cnpj = '33.669.170/0001-12' # Gerado pelo gerador de cnpj
pagador.endereco = 'RUA DO PAGADOR'
pagador.bairro = 'Bairro do pagador'
pagador.cep = '89885-000'
pagador.cidade = 'Chapecó'
pagador.uf = 'SC'
pagador.nome_avalista = 'Maria avalista'
pagador.documento_avalista = '840.106.990-43' # Gerado pelo gerador de CPF
end
Pagamento
É utilizado apenas para gerar remessas. Cada pagamento representa 1 boleto (por exemplo). Exemplo:
pagamento = BrBoleto::Remessa::Pagamento.new({
nosso_numero: "123456",
numero_documento: "977897",
data_vencimento: Date.tomorrow,
valor_documento: 100.12,
pagador: {
nome: 'João da Silva',
cpf_cnpj: '33.669.170/0001-12', # Gerado pelo gerador de pdf online
# ....
},
data_emissao: Date.today, # Valor default
valor_desconto: 0.0, # Valor default
valor_iof: 0.0, # Valor default
valor_abatimento: 0.0, # Valor default
cod_desconto: '0', # Valor default
desconto_2_codigo: '0', # Valor default
desconto_2_valor: 0.0, # Valor default
desconto_3_codigo: '0', # Valor default
desconto_3_valor: 0.0, # Valor default
codigo_multa: '3', # Valor default
codigo_juros: '3', # Valor default
valor_multa: 0.0, # Valor default
valor_juros: 0.0, # Valor default
parcela: '1', # Valor default
tipo_impressao: '1', # Valor default
tipo_emissao: '2', # Valor default
identificacao_ocorrencia: '01', # Valor default
especie_titulo: '01', # Valor default
codigo_moeda: '9', # Valor default
forma_cadastramento: '0', # Valor default
emissao_boleto: '2', # Valor default
distribuicao_boleto: '2', # Valor default
})
Sobrescrevendo classes e validações
Você pode usar as próprias classes da gem, porém, recomendo criar uma subclasse para os bancos que você gostaria de desenvolver. Com isso também é possível sobrescrever validações e métodos da gem. (Isso pode ser útil caso precise tratar alguma particularidade)
Exemplo:
class BoletoSicoob < BrBoleto::Boleto::Sicoob
def default_values
{
local_pagamento: 'PREFERENCIALMENTE NA EMPRESA XXXXX',
aceite: true
}
end
end
boleto = BoletoSicoob.new()
boleto.aceite # true
boleto.local_pagamento # PREFERENCIALMENTE NA EMPRESA XXXXX
Você pode também sobrescrever a class
da conta, mas para isso será necessário sobrescrever um método na class
do boleto para que funcione adequadamente:
class MinhaContaSicoob < BrBoleto::Conta::Sicoob
# Suas regras aqui
end
class MeuBoletoSicoob < BrBoleto::Boleto::Sicoob
def conta_class
MinhaContaSicoob # Sem isso sua conta personalizada não vai funcioanr
end
end
boleto = MeuBoletoSicoob.new
boleto.conta.class
# => MinhaContaSicoob
Você pode sobrescrever os comportamentos na subclasse. Por exemplo, imagine que você quer sobrescrever a forma como é tratada a segunda parte do código de barras. Seguindo a interface da classe BrBoleto::Boleto::Base fica bem simples:
class BoletoSicoob < BrBoleto::Boleto::Sicoob
def codigo_de_barras_do_banco
# Sua implementação ...
end
end
Criando os boletos / Validações
Agora você pode emitir um boleto, usando a classe criada no exemplo anterior:
BoletoSicoob.new(conta: {agencia: '3195', codigo_cedente: '6532', carteira: '1'}, numero_documento: '1101', valor_documento: 105.78)
Você pode usar blocos se quiser:
boleto_sicoob = BoletoSicoob.new do |boleto|
boleto.conta = {
agencia: '0097',
carteira: '1',
modalidade: '01',
razao_social: 'Razao Social da Empresa',
codigo_cedente: '90901',
endereco: 'Rua nome da rua, 9999',
cpf_cnpj: '98137264000196', # Gerado pelo gerador de cnpj
}
boleto.pagador do |pag|
pag.nome = 'Nome do Sacado'
pag.cpf_cnpj = '35433793990'
end
boleto.numero_documento = '12345678'
boleto.data_vencimento = Date.tomorrow
boleto.valor_documento = 31_678.99
end
Cada banco possui suas próprias validações de campo e de tamanho. Primeiramente, antes de renderizar qualquer boleto você precisar verificar se esse o boleto é válido.
if boleto_sicoob.valid?
# Renderiza o boleto
else
# Tratar erros
end
Campos do Boleto
Segue abaixo os métodos para serem chamados, no momento de renderizar os boletos. Os campos são de mesmo nome:
boleto_sicoob.codigo_banco_formatado # Retorna o código do banco, junto com seu dígito
boleto_sicoob.codigo_de_barras
boleto_sicoob.linha_digitavel
boleto_sicoob.nosso_numero
boleto_sicoob.conta.agencia_codigo_cedente
boleto_sicoob.conta.carteira_formatada # Formata a carteira, para mostrar no boleto.
boleto_sicoob.numero_documento
boleto_sicoob.valor_documento
boleto_sicoob.especie
boleto_sicoob.especie_documento
#Arquivo de remessa
CNAB 240
Um arquivo de remessa é composto de UM ou VÁRIOS lotes (class BrBoleto::Remessa::Lote). Estes lotes são compostos de UM ou VÁRIOS pagamentos (class BrBoleto::Remessa::Pagamento).
Por exemplo, você gerou 2 boletos, e precisa criar um arquivo de remessa para os mesmos. Deve ser criado(instanciado) 2 pagamentos(BrBoleto::Remessa::Pagamento) onde deverão ter os dados requeridos do pagamento de cada boleto. (pagamento 1 com dados do boleto 1 e pagamento 2 com os dados do boleto 2).
Com isso, deve-se instanciar um lote passando os dois pagamentos instanciados. Esse lote você adiciona aos lotes da remessa e chama o método dados_do_arquivo
do objeto de Remessa do banco referente.
Exemplo:
boleto_1 = BrBoleto::Boleto::Sicoob.new({
conta: {
agencia: 3069,
codigo_cedente: 6532,
carteira: 1,
conta_corrente: '5679',
razao_social: 'Cedente 1',
cpf_cnpj: '12345678901',
},
pagador: {
nome: 'Sacado',
cpf_cnpj: '725.275.005-10',
endereco: 'Rua teste, 23045',
bairro: 'Centro',
cep: '89804-457',
cidade: 'Chapecó',
uf: 'SC'
},
numero_documento: 10001,
valor_documento: 100.78,
data_vencimento: Date.tomorrow,
instrucoes1: 'Lembrar de algo 1',
instrucoes2: 'Lembrar de algo 2',
instrucoes3: 'Lembrar de algo 3',
instrucoes4: 'Lembrar de algo 4',
instrucoes5: 'Lembrar de algo 5',
instrucoes6: 'Lembrar de algo 6'
})
boleto_2 = BrBoleto::Boleto::Sicoob.new({
conta: {
agencia: 3069,
codigo_cedente: 6532,
carteira: 1,
conta_corrente: '5679',
razao_social: 'Cedente 1',
cpf_cnpj: '12345678901',
},
pagador: {
nome: 'Sacado 2',
cpf_cnpj: '725.275.005-10',
endereco: 'Rua teste, 648',
bairro: 'Centro',
cep: '89804-301',
cidade: 'Xaxim',
uf: 'SC'
},
valor_documento: 200.78,
data_vencimento: Date.tomorrow,
numero_documento: 10002,
instrucoes1: 'Lembrar de algo 1',
instrucoes2: 'Lembrar de algo 2',
instrucoes3: 'Lembrar de algo 3',
instrucoes4: 'Lembrar de algo 4',
instrucoes5: 'Lembrar de algo 5',
instrucoes6: 'Lembrar de algo 6'
})
pagamento_1 = BrBoleto::Remessa::Pagamento.new({
nosso_numero: boleto_1.nosso_numero,
data_vencimento: boleto_1.data_vencimento,
valor_documento: boleto_1.valor_documento,
pagador: boleto_1.pagador
})
pagamento_2 = BrBoleto::Remessa::Pagamento.new({
nosso_numero: boleto_2.nosso_numero,
data_vencimento: boleto_2.data_vencimento,
valor_documento: boleto_2.valor_documento,
pagador: boleto_2.pagador
})
lote = BrBoleto::Remessa::Lote.new(pagamentos: [pagamento_1, pagamento_2])
remessa = BrBoleto::Remessa::Cnab240::Sicoob.new({
conta: {
agencia: 3069,
codigo_cedente: 6532,
carteira: 1,
conta_corrente: '5679',
razao_social: 'Cedente 1',
cpf_cnpj: '12345678901',
},
lotes: lote,
sequencial_remessa: 1
})
remessa.dados_do_arquivo
Com isso irá gerar uma string com os dados para o arquivo de remessa. Ele irá ficar no seguinte formato
HEADER_ARQUIVO
HEADER_LOTE
SEGMENTO_P # Do pagamento 1
SEGMENTO_Q # Do pagamento 1
SEGMENTO_R # Do pagamento 1
SEGMENTO_S # Do pagamento 1
SEGMENTO_P # Do pagamento 2
SEGMENTO_Q # Do pagamento 2
SEGMENTO_R # Do pagamento 2
SEGMENTO_S # Do pagamento 2
TRAILER_LOTE
TRAILER_ARQUIVO
Está nesse formato pois somente assim consegui homologar junto ao banco.
Mas se você deseja colocar o arquivo no formato:
HEADER_ARQUIVO
HEADER_LOTE # Do pagamento 1
SEGMENTO_P
SEGMENTO_Q
SEGMENTO_R
SEGMENTO_S
TRAILER_LOTE
HEADER_LOTE # Do pagamento 2
SEGMENTO_P
SEGMENTO_Q
SEGMENTO_R
SEGMENTO_S
TRAILER_LOTE
TRAILER_ARQUIVO
basta criar um lote para cada pagamento. Exemplo:
lotes = []
lotes << BrBoleto::Remessa::Lote.new(pagamentos: pagamento_1)
lotes << BrBoleto::Remessa::Lote.new(pagamentos: pagamento_2)
remessa = BrBoleto::Remessa::Cnab240::Sicoob.new({
lotes: lotes,
conta: {
agencia: 3069,
codigo_cedente: 6532,
carteira: 1,
conta_corrente: '5679',
razao_social: 'Cedente 1',
cpf_cnpj: '12345678901',
},
sequencial_remessa: 2
})
##CNAB 400 O CNAB400 é composto por 1 ou vários pagamentos. A diferença de utilização entre o CNAB 240 e o 400 é que no 400 não existe lotes, apenas pagamentos. Exemplo:
remessa = BrBoleto::Remessa::Cnab400::Sicoob.new do |rem|
rem.conta = {
agencia: 3069,
codigo_cedente: 6532,
carteira: 1,
conta_corrente: '5679',
razao_social: 'Cedente 1',
cpf_cnpj: '12345678901',
}
pagamentos = [pagamento1, pagamento2]
sequencial_remessa = 5
end
Alternativas
Essa biblioteca é baseada em outras ótimas bibliotecas. Recomendo analisar muito bem cada solução:
- Brcobranca https://github.com/kivanio/brcobranca
- Gem de Boleto Bancário https://github.com/tomas-stefano/boleto_bancario
Contribuições
Seja um contribuidor. Você pode contribuir de N formas. Seguem elas:
- Criar boletos para outros bancos.
- Homologando boletos junto ao banco.
- Fornecendo documentações mais atualizadas dos Bancos.
- Escrevendo novos formatos (PDF, PNG), e me avisando para divulgar no Readme.
- Refatorando código!!
- Fornecendo Feedback construtivo! (Sempre bem vindo!)
Licença
- MIT
- Copyleft 2016 Bruno M. Mergen