Ir para conteúdo
  • Cadastre-se

HelioNeto

Membros
  • Total de ítens

    44
  • Registro em

  • Última visita

1 Seguidor

Últimos Visitantes

1.397 visualizações

HelioNeto's Achievements

  1. Boa Tarde @guilherm5 O Erro de assinatura invalida é o mesmo que está retonando no meu teste em Delphi. Eu consegui registrar o boleto via Postman, utilizando um pré-script em JavaScript, Mas eu preciso em Delphi, ai parei de mexer por enquanto. Se vc estiver usando o Python em Windows, faz um teste rodando em Linux Vê se o erro muda.
  2. Boa Tarde Pessoal! Eu fiz um vídeo e postei no Youtube falando sobre a Geração do TOKEN que funcionou Belezinha, Mas a criação do boleto ainda está com erro e por isso eu não postei a continuação. E de todos os testes que eu fiz ainda está com o Erro: "Assinatura Inválida". Todos estes testes me fez perder Horas de esforço e inclusive o sono e mesmo assim ainda não consegui fazer funcionar. No meu entendimento tem a ver com a forma como é realizada a Assinatura no Windows e talvez não tenha solução ainda. Bom, como tem varias pessoas me perguntando, vou postar aqui um Teste que fiz até onde eu parei em DELPHI. Tem vários comentários de tentativas que fiz não estranhe não. Acredito que falta pouco para funcionar usando o Indy com OpenSSL, mas não consegui Detalhe, precisa trocar a constante CLIENT_ID, informando a sua de TESTE. Lembrando que as dlls e o .PEM precisa ficar na mesma pasta do Exe (que já é de praxe). Segue em anexo, Favor, quem conseguir fazer funcionar no Windows pelo Delphi, compartilha com a gente. Abraço! Fonte-Delphi-BradescoApiBoletoHibrido.rar
  3. @Jhonlenon Ribeiro Bom dia! Consegui fazer utilizando JavaScript via Postman, tiveram pessoas que me falaram que resolveram em PHP e C# Eu parei essa implementação com o Boleto Hibrido do Bradesco no Delphi, acredito que eu venha retomar só ano que vêm. Mas a princípio, não consegui fazer funcionar a parte da assinatura com o OpenSSL diretamente pelo Delphi, instanciando as funções da DLL. Ainda não tive uma conclusão mas a princípio o problema é na Forma de Assinar estando no S.O Windows, comparando ao S.O Linux, quando o Servidor do Bradesco vai Descriptografar acusa o erro.
  4. @Victor H. Gonzales - Panda Consegui auxilio do pessoal do Bradesco e o Problema não é na minha credencial, eu estava enviando uma informação incorreta. Agora para tentar solucionar a assinatura, testei todos os tipos de assinatura que encontrei na ACBr: DFeSSL.CalcHashArquivo('request.txt', dgstSHA256, outBase64, True); //usando o PFX. ACBrEAD.CalcularAssinaturaArquivo('request.txt', dgstSHA256, outBase64); //usando o PEM na função ACBrEADGetChavePrivada. ACBrOpenSSLUtils.CalcHashFromFile('request.txt', algSHA256, sttBase64, True) //usando o PEM passando ele LoadPrivateKeyFromFile. Todas elas a Assinatura fica diferente do comando via LINUX passado via Manual de integração: echo -n "$(cat request.txt)" openssl dgst -sha256 -keyform pem -sign certificado.pem | base64 | tr -d '=[:space:]' | tr '+/' '-_' Na pasta eu tenho o certificado.pem e o arquivo request.txtrequest.txt Está ocorrendo erro de assinatura pois essa assinatura não está sendo validada pelo Bradesco.
  5. @Victor H. Gonzales - Panda Obrigado pela disponibilidade. Houve um problema nas minhas credenciais, estou esperando o Bradesco me responder, quando estiver com as Credenciais atualizadas ou quando eles resolverem eu vou retomar essa demanda, no momento, estou vendo outra tarefa. Mas se quiser fazer o teste, no Anexo que eu coloquei, informei os dados fictícios, com estes dados já consegue fazer os testes.
  6. @Victor H. Gonzales - Panda Eu já tentei mas não consegui fazer funcionar. Se você baixar o arquivo que eu anexei, vai ver que eu Copiei o arquivo ACBrBancoW_Bancoob.pas alterei para ACBrBoletoW_Bradesco.pas E fiz as modificações no Método: function TBoletoW_Bradesco.GerarTokenAutenticacao: {*** MONTAGEM DO BODY COM O JWS (JSON Web Signature) ***} xRequestBody := TStringList.Create; xRequestBody.Add('grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'); xRequestBody.Add('assertion='+strAssertion); HTTPSend.Document.Clear; //Esse xRequestBody precisa ser enviado no Body do Post, não consegui fazer funcionar. {*** FIM MONTAGEM BODY ***} OAuth.ContentType := 'application/x-www-form-urlencoded'; OAuth.Payload := true; OAuth.AuthorizationType := atNoAuth; //precisa alterar para NoAuth para não mandar o Basic. Result := inherited GerarTokenAutenticacao;
  7. @Lucio Bittes Pelo que analisei, nos fontes da ACBr: Então teria que criar um overload desse método HTTPMethod com opção de enviar Parâmetros no Body Como este ajuste é na Base do componente, eu não quis tentar criar algo nesse sentido, mas acredito que se houver essa opção vai funcionar a geração do Token. Depois vem outros detalhes bem específicos da API do Bradesco na parte de Registrar o Boleto que pode ser que seja necessário mais algum ajuste. Eu Tive um problema nas minhas credenciais de teste com o Bradesco, eles abriram um Ticket Interno, estou esperando há umas 2 semanas eles me responderem para dar sequencia na implementação.
  8. Pois é, Tivemos uma longa discussão aqui na Empresa e vamos seguir o MOC que trata do preenchimento da NFe. Como O Total da NFe não considera a retenção, não vamos aplicar desconto no Total da Nota. E Se houver um questionamento por parte do Órgão Público, vamos exigir uma Comprovação Legal.
  9. Boa Tarde! Estamos com esta situação aqui Também. Mesmo informando a TAG referente a Retenção: <retTrib> <vBCIRRF>1185859.35</vBCIRRF> <vIRRF>14230.31</vIRRF> </retTrib> Descontando o Valor da Fatura, não está sendo aceito pelo Órgão Publico. Alguém tem mais alguma explicação?
  10. @rafabarzotto Que bom que deu Certo! Meu intuito era colaborar mesmo. Bacana seu projeto, eu desenvolvo em PHP também.
  11. @rafabarzotto Dessa forma que coloquei aí funcionou. o X-Brad-Signature não vai mesmo não, ele só vai no Body coloquei para gerar o arquivo Request.txt para mostrar como está sendo montado, no meu caso saiu conforme o anexo (Request.txt) No código que eu postei estava errado, tem a variável strLinha2 estava repetida e o strObj estava vazio por que eu movi ele para baixo antes de copiar para cá. Atualizei o Arquivo que segue em anexo(Exemplo-RegistroBoleto.txt) o X-Brad-Timestamp usa a variável strTimeStamp que gera a data no formato solicitado pelo Bradesco, conforme a função ConverteDateISO No meu caso, é -04:00 por que Estou em Campo Grande/MS, aí monta assim: 2023-08-30T14:20:06-04:00 Exemplo-RegistroBoleto.txt Request.txt
  12. @Daniel InfoCotidiano Obrigado! Pois é, eu tentei fazer, mas da forma como foi implementado o ACBrBoleto, não consegui fazer a requisição. Observei que a geração do Token faz a requisição com opção de adicionar parâmetros no "Header", mas o Bradesco tem uma particularidade que precisa enviar no "Body". O Bradesco usa uma abordagem diferente das demais, no Primeiro post aqui desse tópico, eu explico essa dificuldade que tive. Então acabei implementando de forma separada usando TIdHTTP do Indy juntamente com o DFeSSL para realizar as Assinaturas. Acredito que dá para adaptar o componente do ACBr que usa o synapse para enviar parâmetros no Body da requisição POST, mas eu não consegui.
  13. @rafabarzotto eu quebrei a cabeça também, mas consegui fazer a requisição. No meu caso, está retornando um ERRO que os caras do Bradesco estão tentando resolver internamente, abriram um Ticket para tentar resolver. mas vou colocar o código que eu fiz aqui para você dar uma olhada: const URL_CRIABOLETO = 'https://proxy.api.prebanco.com.br/v1/boleto/registrarBoleto'; URI_REG_BOLETO = '/v1/boleto/registrarBoleto'; procedure TfrmBradescoApi.CriarBoleto; var strResult: String; objJson: TJSONObject; strTimeStamp, strObj, strLinha1, strLinha2, strLinha3, strLinha4, strLinha5, strLinha6, strLinha7, strLinha8 : String; intMiliSegundos: int64; dataAtual: TDateTime; stremRequest : TStringStream; strRequestAssinado : WideString; xRequestBody : TStringStream; objCriaBoleto : TLibBradescoApiCriaBoleto; begin {*** BLOCO FORMATACAO DA DATA***} dataAtual := Now; intMiliSegundos := DateTimeToUnix(dataAtual, False) * 1000 + MilliSecondsBetween(dataAtual, Trunc(dataAtual)); //Data Atual UTC em Milisegundos. strTimeStamp := ConverteDateISO(dataAtual, False); {*** FIM BLOCO FORMATACAO DA***} {*** BLOCO DE ASSINATURA ***} DFeSSL.SSLCryptLib := cryOpenSSL; DFeSSL.ArquivoPFX := 'certificado.pfx'; DFeSSL.Senha := '123456'; DFeSSL.CarregarCertificado; strLinha1 := 'POST'+#10; //Methodo HTTP strLinha2 := URI_REG_BOLETO+#10; //URI de Requisição strLinha2 := ''+#10; //Parâmetros. quando houver, se não tem deixa linha em branco. strLinha4 := strObj+#10; //Json de criação do Boleto que vai no Body. strLinha5 := editToken.Text+#10; //Access-token retornado da API. strLinha6 := IntToStr(intMiliSegundos)+#10; //Hora Atual em Milisegundos. strLinha7 := strTimeStamp+#10; //TimeStamp; strLinha8 := 'SHA256'; //Algoritimo Usado. stremRequest := TStringStream.Create(strLinha1+strLinha2+strLinha3+strLinha4+strLinha5+strLinha6+strLinha7+strLinha8); //Aqui vai o arquivo para Assinar. stremRequest.SaveToFile('request.txt'); strRequestAssinado := CalcularHash(stremRequest);//aqui realiza a assinatura. {*** FIM BLOCO DE ASSINATURA ***} {*** CRIAÇAO DO PAYLOAD DO BOLETO ***} objCriaBoleto := TLibBradescoApiCriaBoleto.Create; //Classe contento todos os campos do boleto. objCriaBoleto.isacdoTitloCobr := 'HELIO NETO'; //NOME DO CLIENTE objCriaBoleto.elogdrSacdoTitlo := 'RUA AFONSO PENA'; //RUA. objCriaBoleto.enroLogdrSacdo := 999; //NUMERO objCriaBoleto.ccepSacdoTitlo := 79000000; //CEP objCriaBoleto.ebairoLogdrSacdo := 'CENTRO'; //BAIRRO objCriaBoleto.imunSacdoTitlo := 'CAMPO GRANDE'; //CIDADE CLIENTE objCriaBoleto.csglUfSacdo := 'MS'; //UF CLIENTE objCriaBoleto.indCpfCnpjSacdo := 1; //TIPO 1 CPF objCriaBoleto.nroCpfCnpjSacdo := '00000000000'; //CEP DO CLIENTE. objCriaBoleto.demisTitloCobr := FormatDateTime('dd.mm.yyyy', Now); //'30.08.2023'; //Data Emissão. objCriaBoleto.dvctoTitloCobr := FormatDateTime('dd.mm.yyyy', IncDay(Now,1)); //'31.08.2023'; //Data Vencimento. strObj := TJson.ObjectToJsonString(objCriaBoleto); //Converte de Objeto para Json. {*** FIM CRIAÇAO DO PAYLOAD DO BOLETO ***} {*** MONTAGEM DO HEADER ***} FHTTP.Request.Clear; FHTTP.Request.CustomHeaders.Clear; FHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Maxthon; InfoPath.1; .NET CLR 3.5.30729; .NET CLR 3.0.30618)'; FHTTP.Request.AcceptCharSet := 'UTF-8, *;q=0.8'; FHTTP.Request.AcceptEncoding := 'gzip, deflate, br'; FHTTP.Request.BasicAuthentication := False; FHTTP.Request.CustomHeaders.FoldLines := False; FHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; FHTTP.Request.CustomHeaders.Add('Authorization: Bearer ' + editToken.Text); //TOKEN OBTIDO. FHTTP.Request.CustomHeaders.Add('cpf-cnpj: 00000000000000'); //CNPJ DA EMPRESA FHTTP.Request.CustomHeaders.Add('X-Brad-Nonce: ' + IntToStr(intMiliSegundos)); FHTTP.Request.CustomHeaders.Add('X-Brad-Timestamp: ' + strTimeStamp); FHTTP.Request.CustomHeaders.Add('X-Brad-Algorithm: SHA256'); {*** FIM MONTAGEM DO HEADER ***} xRequestBody := TStringStream.Create(strObj); //Preenche o Body para enviar no Post. try strResult := FHTTP.Post(URL_CRIABOLETO, xRequestBody); //Envia. MemoResp.lines.add(strResult); objJson := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(strResult), 0) as TJSONObject; except on E: EIdHTTPProtocolException do begin MemoResp.Lines.add(E.ErrorMessage); end; end; FreeAndNil(xRequestBody); end; function TfrmBradescoApi.ConverteDateISO(AData: TDateTime; AInputIsUTC : Boolean = True): String; const SDateFormat: string = 'yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''Z'''; { Do not localize } SOffsetFormat: string = '%s%s%.02d:%.02d'; { Do not localize } Neg: array[Boolean] of string = ('+', '-'); { Do not localize } var Bias: Integer; TimeZone: TTimeZone; begin Result := FormatDateTime(SDateFormat, AData); if not AInputIsUTC then begin TimeZone := TTimeZone.Local; Bias := Trunc(TimeZone.GetUTCOffset(AData).Negate.TotalMinutes); if Bias <> 0 then begin // Remove the Z, in order to add the UTC_Offset to the string. SetLength(Result, Result.Length - 1); Result := Format(SOffsetFormat, [Result, Neg[Bias > 0], Abs(Bias) div MinsPerHour, Abs(Bias) mod MinsPerHour]); end end; end; Entendo que eles tem essas regras de segurança, mas eles poderiam simplificar algumas coisas. Espero ter ajudado.
  14. Boa Tarde! Vi que ainda não tem o Boleto Híbrido do Bradesco implementado no ACBrBoleto. Consegui contato com o Gerente e geraram as chaves e me mandaram o manual de configuração. Fiquei meio perdido com o manual, e acho que é por isso que ainda não tem esse Boleto Hibrido aqui..kkkkk No fim de uns 2 dias fazendo testes consegui entender e fazer funcionar a Requisição do Token no Postman e no TidHttp. Inclusive para atender os clientes aqui da Empresa vou fazer usando o TidHttp do Indy. Para tentar colocar na ACBr fiz a copia dos arquivos do Bancoob e comecei a mexer. Criei o arquivo: ..\svn\trunk2\Fontes\ACBrBoleto\WS\ACBrBoletoW_Bradesco.pas ..\svn\trunk2\Fontes\ACBrBoleto\WS\ACBrBoletoRet_Bradesco.pas Abaixo, segue todo o código que fiz na função GerarTokenAutenticacao no arquvo ..\svn\trunk2\Fontes\ACBrBoleto\WS\ACBrBoletoW_Bradesco.pas: function TBoletoW_Bradesco.GerarTokenAutenticacao: string; var strheaderJSON, strPayloadJSON : String; JsonHeader, JsonPayload: TJsonObject; intMiliSegundos, intSegundos, intSegundos1h: int64; dataAtual: TDateTime; stremHeadPayload : TStringStream; strHeaderBase64, strPayloadBase64, strHeadPayloadAssinado, strAssertion: WideString; xRequestBody : TStringList; begin {*** BLOCO FORMATACAO DA DATA DO PAYLOAD***} dataAtual := Now; intSegundos := DateTimeToUnix(dataAtual, False); //Data Atual UTC em Segundos. intSegundos1h := DateTimeToUnix(IncHour(dataAtual, 1), False); //Data Atual UTC em Segundos + Horario 1h intMiliSegundos := DateTimeToUnix(dataAtual, False) * 1000 + MilliSecondsBetween(dataAtual, Trunc(dataAtual)); //Data Atual UTC em Milisegundos. {*** FIM BLOCO FORMATACAO DA DATA DO PAYLOAD***} {*** BLOCO MONTAGEM DO HEADER JSON ***} JsonHeader := TJsonObject.Create; try JsonHeader.Add('alg').Value.asString := 'RS256'; JsonHeader.Add('typ').Value.asString := 'JWT'; strheaderJSON := JsonHeader.Stringify; strHeaderBase64 := EncodeBase64(strheaderJSON); except end; {*** FIM BLOCO MONTAGEM DO HEADER JSON ***} {*** BLOCO MONTAGEM DO PAYLOAD JSON ***} JsonPayload := TJsonObject.Create; try JsonPayload.Add('aud').Value.asString := 'https://proxy.api.prebanco.com.br/auth/server/v1.1/token'; //URL; JsonPayload.Add('sub').Value.asString := 'cliente_id'; //Client ID; JsonPayload.Add('iat').Value.asString := IntToStr(intSegundos); //data atual em segundos; JsonPayload.Add('exp').Value.asString := IntToStr(intSegundos1h); //data atual adicionando uma hora à frente, em segundos; JsonPayload.Add('jti').Value.asString := IntToStr(intMiliSegundos); //data atual em milissegundos; JsonPayload.Add('ver').Value.asString := '1.1'; strPayloadJSON := JsonPayload.Stringify; strPayloadBase64 := EncodeBase64(strPayloadJSON); except end; {*** FIM BLOCO MONTAGEM DO PAYLOAD JSON ***} {*** BLOCO DE ASSINATURA ***} FSSLDigest := dgstSHA256; FSSLHashOutput := outBase64; DFeSSL.SSLCryptLib := cryOpenSSL; DFeSSL.SSLHttpLib := httpOpenSSL; DFeSSL.SSLXmlSignLib := xsLibXml2; DFeSSL.ArquivoPFX := 'certificado.pfx'; DFeSSL.Senha := 'senha'; DFeSSL.CarregarCertificado; stremHeadPayload := TStringStream.Create(strHeaderBase64+'.'+strPayloadBase64); //concatena conforme o manual. strHeadPayloadAssinado := CalcularHash(stremHeadPayload);//aqui realiza a assinatura. strAssertion := strHeaderBase64+'.'+strPayloadBase64+'.'+strHeadPayloadAssinado; //HeaderBase64 + PayloadBase64 + JWT assinado = JWS. {*** FIM BLOCO DE ASSINATURA ***} {*** MONTAGEM DO BODY COM O JWS (JSON Web Signature) ***} xRequestBody := TStringList.Create; xRequestBody.Add('grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'); xRequestBody.Add('assertion='+strAssertion); HTTPSend.Document.Clear; //Esse xRequestBody precisa ser enviado no Body do Post, não consegui fazer funcionar. {*** FIM MONTAGEM BODY ***} OAuth.ContentType := 'application/x-www-form-urlencoded'; OAuth.Payload := true; OAuth.AuthorizationType := atNoAuth; //precisa alterar para NoAuth para não mandar o Basic. Result := inherited GerarTokenAutenticacao; end; Todo esse código é somente para Gerar o JWS (JSON Web Signature). Não segui muito as boas praticas, só queria fazer funcionar, e até consegui montar todos os dados, inclusive o JWS gerado aqui foi o que eu Utilizei no Postman. mas no momento de enviar, o FHTTPSend.HTTPMethod(MetodoHTTPToStr(htPOST), URL) manda esses dados pelo Header e o Bradesco só aceita se mandar pelo Body. Esse pequeno, grande detalhe foi o que fez eu não conseguir gerar o Token, a resposta que está vindo é esta: Erro: 400 - Bad Request { "code": "100", "message": "invalid token", "details": null } Pelo que li no manual, todos os endpoints precisam de Assinatura no Payload. Não encontrei outro Banco já configurado que tenha este tipo de abordagem e acho que o Bradesco só está dificultando as coisas. Se mais alguém quiser colaborar, para colocar no ACBrBoleto, está aí, pelo menos a parte de geração do Token. Segue em anexo o Manual e os arquivos alterados para conseguir utilizar no ACBrBoleto. ACBrBoleto-Bradesco.zip
  15. Na função de gerar código de barras, você pode informar diretamente uma String ao invés de enviar um TACBrTipoCodBarra. Abaixo segue a String correspondente ao TACBrTipoCodBarra para cada Linguagem da Etiquetadora: Etiquetadora na Linguagem PPLA: ...\trunk2\Fontes\ACBrSerial\ACBrETQPpla.pas 'A' = barCODE39; 'E' = barCODE128; 'F' = barEAN13; 'G' = barEAN8; 'O' = barCODE93; Etiquetadora na PPLB: ...\trunk2\Fontes\ACBrSerial\ACBrETQEpl2.pas '3' = barCODE39; '1' = barCODE128; 'E30' = barEAN13; 'E80' = barEAN8; 'B9' = barCODE93; Etiquetadora na PPLZ: ...\trunk2\Fontes\ACBrSerial\ACBrETQZplII.pas 'B3' = barCODE39 'C' = barCODE128; 'E' = barEAN13; 'B8' = barEAN8; 'A' = barCODE93; Para realizar os testes utilizei o Exemplo: ...trunk2\Exemplos\ACBrSerial\ACBrETQ\Delphi\ETQTeste.dpr E criei um campo para informar manualmente os dígitos do código de barras, e no evento bEtqCarreirasClick fiz os ajustes: ImprimirTexto(orNormal, 2, 1, 2, 2, 1, 'TESTE barEAN13'); ImprimirTexto(orNormal, 2, 1, 1, 6, 1, 'COD:'+strCod); ImprimirBarras(orNormal, barEAN13, 2, 2, 8, 1, strCod, 10); ImprimirTexto(orNormal, 2, 1, 2, 2, 36, 'TESTE barCODE93'); ImprimirTexto(orNormal, 2, 1, 1, 6, 36, 'COD:'+strCod); ImprimirBarras(orNormal, barCODE93, 2, 2, 8, 36, strCod, 10); ImprimirTexto(orNormal, 2, 1, 2, 2, 72, 'TESTE barCODE128'); ImprimirTexto(orNormal, 2, 1, 1, 6, 72, 'COD:'+strCod); ImprimirBarras(orNormal, barCODE128, 2, 2, 8, 72, strCod, 10); Fui realizando a troca do bloco de 3 linhas com todos os tipos e desta forma consegui chegar nesta conclusão. Nos testes que realizei em etiquetas de 3 colunas, observei que: - Para códigos de barras entre 3 e 9 dígitos é melhor utilizar o barCODE93 - Para códigos de barras com 13 dígitos é melhor utilizar o barEAN13 (Com a ressalva de que é feita uma validação se o o digito verificar está de acordo, podendo mudar os dígitos do código). - Não deve-se usar código de barras com menos de 3 dígitos, nem entre 10 e 12 e nem maior que 13. Espero ter ajudado!
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.