BoletoNet / boletonet

Boleto.Net is a library developed for use in Brazil, given it has been programmed with Brazilian retail legislation and business rules for bank registered billing integration.
Apache License 2.0
479 stars 382 forks source link

Alguém já esta desenvolvendo o boleto e registro conforme a nova plataforma do Febraban ? #306

Open leonardomsgoncalves opened 7 years ago

leonardomsgoncalves commented 7 years ago

Recebi o manual do Bradesco, será através de web service mas o serviço ainda não esta disponível.

guigomesa commented 7 years ago

Fiz esse projeto na implementação do webservice do Bradesco https://github.com/onlinesites/Boleto-Bradesco

Nesse momento estou em processo de homologação para funcionamento do ecommerce

cfasilva commented 7 years ago

@guigomesa aqui na empresa estamos pensando numa espécie de "Registrador de Boletos" a ideia seria centralizar em uma única solução todas as formas de comunicação que o clientes (no nosso caso os bancos) disponibilizariam para o registro (REST/SOAP). E daí enfileirar os boletos para serem direcionados para os seus respectivos canais. Alguma sugestão nesta linha?

leonardomsgoncalves commented 7 years ago

@guigomesa o Bradesco esta desenvolvendo uma solução via webservice (https:\www.cobranca.bradesconetempresa.b.br\boletoecommerce) sem utilizar o shopfácil, só que o ambiente ainda não esta disponível.

Quanto ao ShopFácil, tem algum custo adicional além da tarifa de registro e liquidação ?

guigomesa commented 7 years ago

@cfasilva Isso pode ser complicado pois com a necessidade do envio de remessa nem todos os bancos disponibilizam de forma facilitada o envio e leitura do arquivo de remessa. No caso do Bradesco eles estão disponilizando para as empresas de ECommerce o Shop Facil onde você gera a requisição e eles te devolvem os dados/link do boleto. Dependendo do caso pode ser vantajoso fazer uso de um gateway e evitar re inventar a roda. Mas seria interessante ter um micro serviço pra agilizar essa comunicação. e deixar transparente a geração de um boleto independente de banco ou serviço

@leonardomsgoncalves eu realmente não conhecia essa solução (vou inclusive passa-la para a gerência da empresa). O pessoal do comercial passou foi a integração com o ShopFácil devido as lojas virtuais que alguns clientes optaram por contratar esse serviço. Com relação a taxas eu realmente não sei lhe falar valores.

guigomesa commented 7 years ago

@leonardomsgoncalves eles liberando a documentação desse outro webservice se for no mesmo caminho do ShopFacil eu implemento e disponibilizo sem problemas

Francislei commented 7 years ago

Desculpe ressuscitar o assunto, mas tem alguém trabalhando com o registro online de boletos no Bradesco pelo webservice: https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao ?

ivanteles commented 7 years ago

Eu utilizei recentemente este endpoint: https://homolog.meiosdepagamentobradesco.com.br/api

leonardomsgoncalves commented 7 years ago

Alguém já tem o manual do registro online e algum projeto já funcionando ?

@guigomesa séria ótimo se conseguir, obrigado.

Francislei commented 7 years ago

Recebi este manual do Bradesco. Manual Registro de Boleto Bancário On-line_v1 5.pdf

leonardomsgoncalves commented 7 years ago

@Francislei tentei adicionar a referência de serviço e estou tomando o erro abaixo:

Ocorreu um erro ao baixar 'https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao/$metadata'. A solicitação falhou com a mensagem de erro:

<?xml version="1.0" encoding="UTF-8"?> {"cdErro":"810", "msgErro":"Erro Certificado / Formatacao dos campos da mensagem invalida [0x00c30008]"}</ns2:registrarTituloResponse></S:Body></S:Envelope> --. O metadados contém uma referência que não pode ser resolvida: 'https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao'. O servidor remoto retornou uma resposta inesperada: (400) Bad Request. O servidor remoto retornou um erro: (400) Solicitação Incorreta. Se o serviço está definido na solução atual, tente compilar a solução e adicionar a referência de serviço novamente.

sabe o motivo ?

Francislei commented 7 years ago

@leonardomsgoncalves desculpe a demora em responder. Tive o mesmo problema, e em contato com o suporte me retornaram a informação abaixo:

_

Para realizar a comunicação com o Endpoint é necessário o cliente assinar a mensagem JSON com o par de chaves (adquiridos com o certificado), no formato pkcs#7 e o resultado deve ser enviado através de POST para o Endpoint desejado (Homologação ou Registro).

_

anaotero commented 7 years ago

Estou com o mesmo erro. Já fiz pelo Shop Facil, mas eles ainda não estão registrando. Depois comecei a tentar direto com o Bradesco e esse é o terceiro manual que eles me passam, cada hora uma url e configurações diferentes.

brunoDionizio commented 7 years ago

Algum avanço?

Vou implementar essa solução para registro de boletos. A documentação cita o certificado ICP Brasil (suponho que seja esse https://banco.bradesco/html/empresas/ferramentas/certificado-digital-icp-brasil.shtm), mas essa é a única forma? Vocês conseguiram?

anaotero commented 7 years ago

@jrodrig20 não sei se entendi a sua pergunta pq em msg.json, na função openssl_pkcs7_sign é onde tem que colocar os dados do boleto. Vc não colocou?

jrodrig20 commented 7 years ago

@anaotero Olá! Desculpa, acabei removendo o comentário por achar que não seria o local correto aqui! Mas em relação a sua pergunta, os dados do boleto estão dentro do arquivo msg.json sim. Só que a função openssl_pkcs7_sign cria um arquivo com a assinatura digital (base64) e conteúdo do arquivo msg,json separados (arquivo em anexo). Preciso que os dados do boleto (do msg.json) sejam inseridos juntos na assinatura (base64), entendestes? signed.txt

anaotero commented 7 years ago

Agora eu entendi. tenta assim openssl_pkcs7_sign( 'msg.json', 'signature.txt', $certificado, $private_key, PKCS7_TEXT );

jrodrig20 commented 7 years ago

@anaotero Valeu, muito obrigado! Era isto mesmo.

anaotero commented 7 years ago

@jrodrig20 conseguiu gerar o boleto? Ainda estou com erros.

jrodrig20 commented 7 years ago

Olá @anaotero! Eu parei do desenvolvimento semana passada, vou continuar segunda e pretendo terminar neste dia, se conseguir trabalhar exclusivamente nisto. Qual é o erro que está a ocorrer é o citado pelo @Francislei (cdErro:810), isto?

gutofreitas commented 7 years ago

Olá @anaotero , @jrodrig20, @Francislei Boa noite pessoal, segue solução para assinatura. $signature = openssl_pkcs7_sign(realpath("signatureBoleto.json"), realpath("signatureBoleto.txt"), 'file://' . $this->certKey, 'file://' . $this->pryKey, $this->headers, PKCS7_BINARY | PKCS7_TEXT, $this->pubKey);

jrodrig20 commented 7 years ago

@gutofreitas Valeu!! Pessoal consegui finalizar o processo todo para o registro, se alguém precisar de ajuda estou a disposição!

anaotero commented 7 years ago

Boa tarde. Estou com erro de certificado novamente, toda vez que incluo a chave pública. @jrodrig20 você esta colocando algo no headers tb?

jrodrig20 commented 7 years ago

Olá @anaotero ! Estou passando um array vazio no headers, segue a parte do código de onde extraio o certificado e a chave privada e também como estou fazendo para assinar a mensagem: `

    file_put_contents('file_msg', $mensagem);
    $certificado_pfx = file_get_contents(PASTA_CERTIFICADOS . 'certificado.pfx');
    if (!openssl_pkcs12_read($certificado_pfx, $result, 'senha')) {
        throw new Exception('Não foi possível ler o certificado .pfx');
    }

    $certificado_key = openssl_x509_read($result['cert']);
    $private_key = openssl_pkey_get_private($result['pkey'], 'senha');

    openssl_pkcs7_sign(
            'file_msg', 'signature', $certificado_key, $private_key, [], PKCS7_BINARY | PKCS7_TEXT
    );

    $signature = file_get_contents('signature');`
xbennes commented 7 years ago

Olá @jrodrig20! Você conseguiu registrar o boleto no bradesco? E dados assinados, como ficaram no final?

jrodrig20 commented 7 years ago

Olá @xbennes ! Consegui registrar. No final é criado uma mensagem contendo os dados do boleto e do certificado na base64. Se precisar de algo mais específico me avisa que compartilho aqui. Abraço!

xbennes commented 7 years ago

@jrodrig20, você teria como compartilhar um exemplo?

marcelovsantos commented 7 years ago

@jrodrig20 você poderia compartilhar um exemplo de como você envia o json e a assinatura. Você enviar com curl?

jrodrig20 commented 7 years ago

@xbennes e @marcelovsantos segue um exemplo com envio: `
$mensagem = '{"nuCPFCNPJ": "123456789","filialCPFCNPJ": "0001","ctrlCPFCNPJ": "39","cdTipoAcesso": "2","clubBanco": "0","cdTipoContrato": "0","nuSequenciaContrato": "0","idProduto": "09","nuNegociacao": "123400000001234567","cdBanco": "237","eNuSequenciaContrato": "0","tpRegistro": "1","cdProduto": "0","nuTitulo": "0","nuCliente": "123456","dtEmissaoTitulo": "25.05.2017","dtVencimentoTitulo": "20.06.2017","tpVencimento": "0","vlNominalTitulo": "100","cdEspecieTitulo": "04","tpProtestoAutomaticoNegativacao": "0","prazoProtestoAutomaticoNegativacao": "0","controleParticipante": "","cdPagamentoParcial": "","qtdePagamentoParcial": "0","percentualJuros": "0","vlJuros": "0","qtdeDiasJuros": "0","percentualMulta": "0","vlMulta": "0","qtdeDiasMulta": "0","percentualDesconto1": "0","vlDesconto1": "0","dataLimiteDesconto1": "","percentualDesconto2": "0","vlDesconto2": "0","dataLimiteDesconto2": "","percentualDesconto3": "0","vlDesconto3": "0","dataLimiteDesconto3": "","prazoBonificacao": "0","percentualBonificacao": "0","vlBonificacao": "0","dtLimiteBonificacao": "","vlAbatimento": "0","vlIOF": "0","nomePagador": "Cliente Teste","logradouroPagador": "rua Teste","nuLogradouroPagador": "90","complementoLogradouroPagador": "","cepPagador": "12345","complementoCepPagador": "500","bairroPagador": "bairro Teste","municipioPagador": "Teste","ufPagador": "SP","cdIndCpfcnpjPagador": "1","nuCpfcnpjPagador": "12345648901234","endEletronicoPagador": "","nomeSacadorAvalista": "","logradouroSacadorAvalista": "","nuLogradouroSacadorAvalista": "0","complementoLogradouroSacadorAvalista": "","cepSacadorAvalista": "0","complementoCepSacadorAvalista": "0","bairroSacadorAvalista": "","municipioSacadorAvalista": "","ufSacadorAvalista": "","cdIndCpfcnpjSacadorAvalista": "0","nuCpfcnpjSacadorAvalista": "0","endEletronicoSacadorAvalista": ""}'; //Dados extraídos do manual

    file_put_contents('file_msg', $mensagem);
    $certificado_pfx = file_get_contents(PASTA_CERTIFICADOS . 'certificado.pfx');
    if (!openssl_pkcs12_read($certificado_pfx, $result, 'senha')) {
        throw new Exception('Não foi possível ler o certificado .pfx');
    }

    $certificado_key = openssl_x509_read($result['cert']);
    $private_key = openssl_pkey_get_private($result['pkey'], 'senha');

    openssl_pkcs7_sign(
            'file_msg', 'signature', $certificado_key, $private_key, [], PKCS7_BINARY | PKCS7_TEXT
    );

    $signature = file_get_contents('signature');
    $parts = preg_split("#\n\s*\n#Uis", $signature);
    $mensagem_assinada_base64 = $parts[1];

    $ch = curl_init('https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $mensagem_assinada_base64);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $retorno = curl_exec($ch);
    if (curl_errno($ch)) {
        $info = curl_getinfo($ch);
        throw new Exception('Não foi possível registrar o boleto. ' . 'Erro:' . curl_errno($ch) . '.<br>' . $info);
    }

    $doc = new DOMDocument();
    $doc->loadXML($retorno);
    $retorno = $doc->getElementsByTagName('return')->item(0)->nodeValue;
    $retorno = preg_replace('/, }/i', '}', $retorno); 
    $retorno = json_decode($retorno);

    if (!empty($retorno->cdErro)) {
        throw new Exception('Não foi possível registrar o boleto. ' . $retorno->msgErro);
    }

`

marcelovsantos commented 7 years ago

@jrodrig20 muito esclarecedor, obrigado! só mais uma dúvida você teve que enviar algum certificado pro banco para conseguir acesso? Pois estou recebendo o retorno:

cdErro: 810 msgErro: Erro Certificado / Formatacao dos campos da mensagem invalida [0x00d30003]

jrodrig20 commented 7 years ago

@marcelovsantos Não precisa enviar certificado para o banco, o certificado só é necessário no projeto para realizar a assinatura da mensagem a ser enviada. Eu estava com este erro quando estava assinando a mensagem incorretamente. O erro ocorria pois estava usando os parâmetros incorretos na função openssl_pkcs7_sign. Não estava passando o sexto parâmetro "flags" (http://php.net/manual/pt_BR/function.openssl-pkcs7-sign.php), nesta caso a mensagem na base64 estava somente com a assinatura sem os dados do boleto. Antes de enviar a mensagem via curl aplica a função base64_decode e verifica o que tem nela, na mensagem deve haver os dados do boleto. Em anexo tem um código em java que a equipe de desenvolvimento do Bradesco me passou como exemplo, talvez possa te ajudar em algo. AssinaturaPKCS7.zip

marcelovsantos commented 7 years ago

@jrodrig20 consegui aqui e deu certo, o problema é que eu não estava utilziando um certificado e-CPF. Agora funcionou certinho, muito obrigado.

xbennes commented 7 years ago

@jrodrig20, sua contribuição foi muito valiosa. Muito obrigado!

guigomesa commented 7 years ago

Opa desculpe a demora em responder, vou avaliar o que passaram aqui e ver o que posso contribuir (:

hgmauri commented 7 years ago

Bom dia pessoal

@Francislei, você teria algum exemplo em C# para eu seguir como base o registro de boleto online utilizando o link https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao?

Francislei commented 7 years ago

Bom dia!

Infelizmente não, desisti (momentaneamente) e fiz em java. Mas meu objetivo ainda é ter isso em c#.

hgmauri commented 7 years ago

beleza @Francislei, obrigado! Vou seguir aqui em C# então, assim que eu avançar eu coloco no git e compartilho aqui! Abraço

alexandregms commented 7 years ago

Boa tarde @Francislei ... Estou penando para fazer isto em java por falta de conhecimentos mesmo... Como conseguiu teria como, de alguma forma me dar um help nisto? Qualquer coisa se eu lhe passar meu email ajudaria?

Muito obrigado desde já... Alexandre Silva

ByNeto commented 7 years ago

Boa tarde @jrodrig20 e @marcelovsantos, gostaria de saber se podem me ajudar na questão da assinatura, vi o exemplo que postou sobre o certificado e-CPF ou e-CNPJ. Inseri um certificado valido ICP-BRASIL, do tipo A1, sendo e-CNPJ. Mas ainda retorna o erro 810. Utilizei o código exemplo que vc postou e inseri o certificado comprado pela empresa, do tipo A1, sendo e-CNPJ. Mas mesmo no seu exemplo segue o erro 810. Poderia me ajudar me informando sobre o certificado como posso gerar ou adquirir o mesmo que fez com que seu projeto funcionasse. Entrei em contato com Bradesco com todas as informações, aguardando que eles me ajudassem. Mas a resposta foi frustrante e obsoleta. Poderia me ajudar na questão do certificado apenas me informando como posso solucionar essa questão?

jrodrig20 commented 7 years ago

Boa tarde @ByNeto ! Provavelmente estás enviando a mensagem na base64 com algum dado faltando ou sobrando (provavelmente não tem problema com o certificado em si). Junto com a assinatura na base64 deve estar os dados de registro do boleto. Sugestão: da uma debugada (da um decode base64 na mensagem antes de enviar) na mensagem que está sendo enviada e verifica se tem os dados do boleto ou se não tem alguma informação a mais. Qualquer coisa, se quiser, podes colocar a saída aqui que tento ver o que precisas fazer para deixar a composição da mensagem correta. Qualquer coisa estou a disposição.

Francislei commented 7 years ago

Boa tarde! @alexandregms, desculpe a demora em responder, meu conhecimento em java também é bem limitado, mas consegui o suficiente para deixar o projeto funcional. Eu estou a disposição, pode contar comigo.

ByNeto commented 7 years ago

Primeiramente obrigado pelo retorno @jrodrig20 segue abaixo o debug do retorno base64 usei seu código que esta bem claro de entender, dei um decode na variável $mensagem_assinadabase64 0�� �H�� ��}0�y10  `�He0�� �H�� �����{ "nuCPFCNPJ":"04014192000146", "filialCPFCNPJ":"1", "ctrlCPFCNPJ":"59", "cdTipoAcesso":"2", "idProduto":"9", "nuNegociacao":"15090095875", "nuCliente":"4598254", "dtEmissaoTitulo":"30.08.2017", "dtVencimentoTitulo":"30.09.2017", "vlNominalTitulo":"100000", "cdEspecieTitulo":"2", "nomePagador":"LINDOLPHO NETO", "logradouroPagador":"RUA JOAO DUQUE ", "nuLogradouroPagador":"222", "complementoLogradouroPagador":"CASA", "cepPagador":"13097", "complementoCepPagador":"116", "bairroPagador":"PARQUE IMPERADOR", "municipioPagador":"CAMPINAS", "ufPagador":"SP", "cdIndCpfcnpjPagador":"2", "nuCpfcnpjPagador":"22605009866", "endEletronicoPagador":"LINDOLPHO@AUTOPEC.COM.BR", "nomeSacadorAvalista":"NOME SACADOR AVALISTA", "logradouroSacadorAvalista":"ENDERECO SACADOR AVALISTA", "nuLogradouroSacadorAvalista":"5555", "complementoLogradouroSacadorAvalista":"BLOCO 23", "cepSacadorAvalista":"13097", "complementoCepSacadorAvalista":"116", "bairroSacadorAvalista":"BAIRRO SACADOR AVALISTA", "municipioSacadorAvalista":"MUNICIPIO SACADOR AVALISTA", "ufSacadorAvalista":"SP", "cdIndCpfcnpjSacadorAvalista":"2", "nuCpfcnpjSacadorAvalista":"12668000159", "endEletronicoSacadorAvalista":"SACADOR@BRADESCO.COM.BR" }���0��0�ݠv����?�PZ�K�h&�0  �H��  0u1 0 UBR10U  ICP-Brasil1604U -Secretaria da Receita Federal do Brasil - RFB10UAC SINCOR RFB G50 170801164858Z 180801164858Z0��1 0 UBR10U ICP-Brasil1 0 U SP10U CAMPINAS1604U -Secretaria da Receita Federal do Brasil - RFB10U RFB e-CNPJ A11#0!U Autenticado por AR Eloiseg1;09U 2AUTOPEC COMERCIO DE AUTO PECAS LTDA:040141920001460�"0  �H�� �0� ��>�v�9M��~����l/��Oz�U#5�l�Y�(�'���0[�Oto��n��L��u�.����D�����$��(r�Y�<.q�^I&���Ģ��ڒ��H:C�n������6����i�&��*�<�j��w�;�E G0!�rD��t��ӏM�^�<�ޠ�Vv ���Hg-GCxO��޼GPY$;���NJz�)�f�+|b,��bp��єxEc:o�a����������@tS�%��i@>ya@ �����0��0��U��0���=L�42220819833189591881200000000000000000033874322SSPSP�*L�!CARLOS EDUARDO DA SILVA CAVALLI�L�04014192000146�L� 000000000000�leticia@autopec.com.br0 U00U#0�g�B��8I����]��"0xU q0o0mL0c0a+Uhttp://icp-brasil.acsincor.com.br/repositorio/dpc/AC_SINCOR_RFB/DPC_AC_SINCOR_RFB.pdf0��U��0��0T�R�P�Nhttp://icp-brasil.certisign.com.br/repositorio/lcr/ACSINCORRFBG5/LatestCRL.crl0S�Q�O�Mhttp://icp-brasil.outralcr.com.br/repositorio/lcr/ACSINCORRFBG5/LatestCRL.crl0U��0U%0++0��+��0��0[+0�Ohttp://icp-brasil.acsincor.com.br/repositorio/certificados/AC_SINCOR_RFB_G5.p7c06+0�*http://ocsp-ac-sincor-rfb.certisign.com.br0  *�H��  �xc���>e�_Kh'�]�-���,�$�x}!������܃Q�%�@^拉�v ��i���>�G|:�"��O$% �"U�maYv���\@�sy��Lod�a駾�ظ�V����R�'<��������e�5�;�'�9 H �%�+� �㕃x07�0�c��,�����뤜�f �Ɉ���/�-_�&�!�����V֝ �[hI�ύϔ�e<7�Yf���m�{�..�Abă�vy�G���<��ݻ�����T�c=kusu>�c�ܥet��_���V<�ZlQ&�D-P23e��?� ��<s�zB2�I���N���F*�������V �l"�h��)��L��!eH�Q��@�'��P"_��4��T�WZ�B(��/0;!�v4@�����QX����T�����k$��m�u{�*NȔ��y)�ΔE��[�f��{xjB��o�\F8����#�Р��Jh��T '����F�n4Vt��rƖ�{[� ��p�KXH[��?� ��W1��0��0��0u1 0 UBR10U  ICP-Brasil1604U -Secretaria da Receita Federal do Brasil - RFB10UAC SINCOR RFB G5v����?�PZ�K�h&�0  �He���0 *�H��  1  *�H�� 0 *�H��  1 170830195900Z0/ *�H��  1" �@�:e�����A�m��v��3t<�o.��3��0y *�H��  1l0j0 �He0  �He0 �He0 �H�� 0�H�� �0 �H�� @0+0 �H�� (0  �H�� �p)P�E<Ƙτtۀ ��N����]2&�W�Rə31ZC�#�� �f�� ��)�JX�*F�6��"��*�~�g6d 5�졩ifAcd �E����@�;Ձ�l�@8G��-q�W�ek;y��M��a�p�-u(�c��#�oc�9ף"+��Q�n��ą��:O��.����_-���ђ7�9�u"uR�ĥ�(n�1�M���R���Q攰�`� ��(�w?��w� ���c��!@��-}��G�?8i�����

Desde já agradeço pela colaboração

jrodrig20 commented 7 years ago

@ByNeto acredito que sua mensagem esteja com todos os dados necessários. O que pode estar acontecendo é que tenha dados a mais. Vou compartilhar algo que ocorreu comigo não sei se é o seu caso, mas daqui a pouco pode ajudar. Num e-mail que enviei ao suporte do Bradesco relatando o mesmo problema que relatastes, eles me responderam o seguinte: "A divergência não está no certificado, está na mensagem assinada. Está sendo assinado junto com o JSON o Content-Type: text/plain, conforme print abaixo. Na assinatura, deverá ser assinado somente o JSON." bradesco_print

rondosoftlss commented 7 years ago

Vocês estão usando esse projeto

https://github.com/onlinesites/Boleto-Bradesco

ByNeto commented 7 years ago

Bom dia @rondosoftlss, este projeto e do Shop Facil. Esse projeto já esta em funcionamento aqui na empresa. A pedido da diretoria estamos de mudança para esse novo webservice de boletos registrados. Mas o bradesco nao esta ajudando nas informações. Estou seguindo com as informações postadas nesta issue, dos colaboradores que tiveram sucesso. Como o @jrodrig20 e @marcelovsantos

Bom dia @jrodrig20, obrigado pelo seu retorno foi muito útil. Realizei contato com o suporte do bradesco, no qual foi encaminhado pelo gerente da conta da empresa no qual trabalho. Mas me encaminharam para uma empresa chamada www.7comm.com.br, no qual tive retorno de uma moça que me retornou nada com nada, a mesma nem sabe imagino eu o que seja um web-service. Até o atual momento a unica informação que tenho e o manual bem vago fornecido pelo suporte bradesco. E as orientação que estão sendo de grande ajuda por esta issue. Pedi a eles do bradesco que me digam o que estou enviando para o web-service, como foi o print de tela que vc me enviou, mas vc teve mais sucesso do que eu, pq ate o momento não tive resposta nenhuma do bradesco. Eu retirei da mensagem a seguinte informação no escopo como vc havia informado:

MIME-Version: 1.0 Content-Disposition: attachment; filename="smime.p7m" Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m" Content-Transfer-Encoding: base64

ficando apenas o corpo da mensagem em base64, mas ainda continua o erro 810 que diz que pode ser a assinatura ou o conteúdo da mensagem. Juro que nao entendo o pq o bradesco não esta nos ajudando aqui na empresa. Sendo que somos clientes e é dever deles colaborar com essa integração. Por aqui temos varias integrações com outros bancos e adquirentes e até o atual momento esta integração e a mais menosprezada e vaga de informações por meio do próprio fornecedor no caso o Bradesco.

Agradeço muito pelo que já informado @jrodrig20 mas de alguma forma poderia me ajudar estou seguindo todas as informações que vc esta enviando até mesmo estou usando o código que postou acima. Existe algo a mais no qual eu possa fazer? ou alguém com quem eu possa falar dentro do bradesco? Pq sempre que entramos em contato com o bradesco eles nos encaminham para essa empresa 7comm que só responde coisas sem sentido algum.

O código que estou utilizando e o seu, apenas inseri uma função que limpa o escopo da mensagem

<?php $mensagem = '{ "nuCPFCNPJ":"04014192000146", "filialCPFCNPJ":"1", "ctrlCPFCNPJ":"59", "cdTipoAcesso":"2", "idProduto":"9", "nuNegociacao":"15090095875", "nuCliente":"4598254", "dtEmissaoTitulo":"30.08.2017", "dtVencimentoTitulo":"30.09.2017", "vlNominalTitulo":"100000", "cdEspecieTitulo":"2", "nomePagador":"FABIO LINUX DA SILVA WINDOWS", "logradouroPagador":"RUA JOAO DUQUE ", "nuLogradouroPagador":"222", "complementoLogradouroPagador":"CASA", "cepPagador":"13097", "complementoCepPagador":"116", "bairroPagador":"PARQUE IMPERADOR", "municipioPagador":"CAMPINAS", "ufPagador":"SP", "cdIndCpfcnpjPagador":"2", "nuCpfcnpjPagador":"22605009866", "endEletronicoPagador":"TI@AUTOPEC.COM.BR", "nomeSacadorAvalista":"NOME SACADOR AVALISTA", "logradouroSacadorAvalista":"ENDERECO SACADOR AVALISTA", "nuLogradouroSacadorAvalista":"5555", "complementoLogradouroSacadorAvalista":"BLOCO 23", "cepSacadorAvalista":"13097", "complementoCepSacadorAvalista":"116", "bairroSacadorAvalista":"BAIRRO SACADOR AVALISTA", "municipioSacadorAvalista":"MUNICIPIO SACADOR AVALISTA", "ufSacadorAvalista":"SP", "cdIndCpfcnpjSacadorAvalista":"2", "nuCpfcnpjSacadorAvalista":"12668000159", "endEletronicoSacadorAvalista":"SACADOR@BRADESCO.COM.BR" }';

file_put_contents('file_msg.json', $mensagem);
$certificado_pfx = file_get_contents('Cert2018ExtE-CNPJ.pfx');
if (!openssl_pkcs12_read($certificado_pfx, $result, 'Senha123')) {
    throw new Exception('Não foi possível ler o certificado .pfx');
}

$certificado_key = openssl_x509_read($result['cert']);
$private_key = openssl_pkey_get_private($result['pkey'], 'Senha123');

openssl_pkcs7_sign('file_msg.json', 'signature.txt', $certificado_key, $private_key, [], PKCS7_BINARY | PKCS7_TEXT);

$signature = file_get_contents('signature.txt'); $obj = new FunctionsClass; // Classe da função que retira todo escopo Content-Type: text/plain $signature_no_header = $obj->signatureSemEscopo($signature);

$parts = preg_split("#\n\s*\n#Uis", $signature_no_header);
$mensagem_assinada_base64 = $parts[1];

$ch = curl_init('https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $mensagem_assinada_base64);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$retorno = curl_exec($ch);
print_r($retorno);
if (curl_errno($ch)) {
    $info = curl_getinfo($ch);
    throw new Exception('Não foi possível registrar o boleto. ' . 'Erro:' . curl_errno($ch) . '.<br>' . $info);
}

$doc = new DOMDocument();
$doc->loadXML($retorno);
$retorno = $doc->getElementsByTagName('return')->item(0)->nodeValue;
$retorno = preg_replace('/, }/i', '}', $retorno);
$retorno = json_decode($retorno);

var_dump($retorno); if (!empty($retorno->cdErro)) { throw new Exception('Não foi possível registrar o boleto. ' . $retorno->msgErro); }

?>

Desde ja sou grato pela colaboração! Deus abençoe!

agichihara commented 7 years ago

Boa tarde pessoal, Vi que o pessoal esta bem avançado, estou comecei a ver a pouco tempo este assunto e lendo a documentação, fiquei com varias dúvidas que acredito que para vocês são simples.

Poderia me ajudar informando se estou no caminho certo? pesquisei e localizei o código abaixo para enviar o Jason (post)

void POST(string url, string jsonContent) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST";

        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        Byte[] byteArray = encoding.GetBytes(jsonContent);

        request.ContentLength = byteArray.Length;
        request.ContentType = @"application/json";

        using (Stream dataStream = request.GetRequestStream())
        {
            dataStream.Write(byteArray, 0, byteArray.Length);
        }
        long length = 0;
        try
        {
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                length = response.ContentLength;
            }
        }
        catch (WebException ex)
        {
            // Log exception and throw as for GET example above
        }
    }

Só que no código acima, não entendi onde vai chegar o retorno... Sei também que precisa assinar PKCS#7

alguém pode me dar uma dica de como fazer isso? Não entendo nada de certificado / assinaturas. E quando pesquiso sobre o assunto, tem muita informação. Estou totalmente perdido... Obrigado.

Biux commented 7 years ago

Olá Pessoal, estou tentando aqui também, a princípio deu certo, Segue trecho de código:

static byte[] SignDataPKCS_7CMS(string data, string certSubject) { X509Certificate2 cert = GetCertificateFromStore(certSubject); ContentInfo content = new ContentInfo(new UTF8Encoding().GetBytes(data)); SignedCms scms = new SignedCms(content, false); CmsSigner signer = new CmsSigner(cert); signer.IncludeOption = X509IncludeOption.EndCertOnly; scms.ComputeSignature(signer); return scms.Encode(); } private static X509Certificate2 GetCertificateFromStore(string certName) { X509Store store = new X509Store(StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certCollection = store.Certificates; X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false); if (signingCert.Count == 0) return null; return signingCert[0]; } finally { store.Close(); } }

brunoDionizio commented 7 years ago

@Biux Muito obrigado pela ajuda, é isso mesmo. Eu estava assinando com um código diferente e obtendo erro 810. Agora deu erro 800, mas é questão do Json, então esse é o caminho.

Só pra constar, eu estou abrindo o certificado em PFX ao invés de recuperar da máquina/usuário.

BrunoZanholo commented 7 years ago

e ai galera! alguém teve problema no retorno com o código de erro "06 - Dados inconsistentes"??

elianasouza commented 7 years ago

Boa tarde galera,

ultilizei o codigo php acima e me retornou o seguinte erro:

Warning: openssl_pkcs7_sign(): error opening input file file_msg! in C:\xampp\htdocs\libpedidos\teste.php on line 16

Warning: file_get_contents(signature): failed to open stream: No such file or directory in C:\xampp\htdocs\libpedidos\teste.php on line 18

Notice: Undefined offset: 1 in C:\xampp\htdocs\libpedidos\teste.php on line 20 string(434) " {"cdErro":"810", "msgErro":"Erro Certificado / Formatacao dos campos da mensagem invalida [0x00d30003]"}"

elianasouza commented 7 years ago

segue codigo

$mensagem = '{"nuCPFCNPJ": "046888703","filialCPFCNPJ": "0","ctrlCPFCNPJ": "29","cdTipoAcesso": "2","clubBanco": "0","cdTipoContrato": "0","nuSequenciaContrato": "0","idProduto": "09","nuNegociacao": "123400000001234567","cdBanco": "237","eNuSequenciaContrato": "0","tpRegistro": "1","cdProduto": "0","nuTitulo": "0","nuCliente": "123456","dtEmissaoTitulo": "25.05.2017","dtVencimentoTitulo": "20.06.2017","tpVencimento": "0","vlNominalTitulo": "100","cdEspecieTitulo": "04","tpProtestoAutomaticoNegativacao": "0","prazoProtestoAutomaticoNegativacao": "0","controleParticipante": "","cdPagamentoParcial": "","qtdePagamentoParcial": "0","percentualJuros": "0","vlJuros": "0","qtdeDiasJuros": "0","percentualMulta": "0","vlMulta": "0","qtdeDiasMulta": "0","percentualDesconto1": "0","vlDesconto1": "0","dataLimiteDesconto1": "","percentualDesconto2": "0","vlDesconto2": "0","dataLimiteDesconto2": "","percentualDesconto3": "0","vlDesconto3": "0","dataLimiteDesconto3": "","prazoBonificacao": "0","percentualBonificacao": "0","vlBonificacao": "0","dtLimiteBonificacao": "","vlAbatimento": "0","vlIOF": "0","nomePagador": "Cliente Teste","logradouroPagador": "rua Teste","nuLogradouroPagador": "90","complementoLogradouroPagador": "","cepPagador": "12345","complementoCepPagador": "500","bairroPagador": "bairro Teste","municipioPagador": "Teste","ufPagador": "SP","cdIndCpfcnpjPagador": "1","nuCpfcnpjPagador": "04688870329","endEletronicoPagador": "","nomeSacadorAvalista": "","logradouroSacadorAvalista": "","nuLogradouroSacadorAvalista": "0","complementoLogradouroSacadorAvalista": "","cepSacadorAvalista": "0","complementoCepSacadorAvalista": "0","bairroSacadorAvalista": "","municipioSacadorAvalista": "","ufSacadorAvalista": "","cdIndCpfcnpjSacadorAvalista": "0","nuCpfcnpjSacadorAvalista": "0","endEletronicoSacadorAvalista": ""}';

file_put_contents('file_msg', $mensagem); $certificado_pfx = file_get_contents('cetificacao.pfx'); $result = array(); if (!openssl_pkcs12_read($certificado_pfx, $result, 'senha')) { throw new Exception('Não foi possível ler o certificado .pfx'); }; echo chaveBoleto($mensagem)."

"; die($result['cert']."

".$result['pkey']); $certificado_key = openssl_x509_read($result['cert']); $private_key = openssl_pkey_get_private($result['pkey'], 'senha');

openssl_pkcs7_sign(
        'file_msg', 'signature', $certificado_key, $private_key, [], PKCS7_BINARY | PKCS7_TEXT
);

$signature = file_get_contents('signature');
$parts = preg_split("#\n\s*\n#Uis", $signature);
$mensagem_assinada_base64 = $parts[1];
//$mensagem_assinada_base64 = chaveBoleto($mensagem);

$ch = curl_init('https://cobranca.bradesconetempresa.b.br/ibpjregistrotitulows/registrotitulohomologacao');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $mensagem_assinada_base64);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$retorno = curl_exec($ch);
die(var_dump($retorno));
if (curl_errno($ch)) {
    $info = curl_getinfo($ch);
    throw new Exception('Não foi possível registrar o boleto. ' . 'Erro:' . curl_errno($ch) . '.<br>' . $info);
}

$doc = new DOMDocument();
$doc->loadXML($retorno);
$retorno = $doc->getElementsByTagName('return')->item(0)->nodeValue;
$retorno = preg_replace('/, }/i', '}', $retorno); 
$retorno = json_decode($retorno);

if (!empty($retorno->cdErro)) {
    throw new Exception('Não foi possível registrar o boleto. ' . $retorno->msgErro);
}