Jhonlenon Ribeiro Postado 6 Junho Postado 6 Junho Bom dia, já tem uns 8 meses que fiz a homologação da emissão do boleto c6Bank via API, até ai tudo certo, quando fiz a homologação do boleto percebi que o componente ACBrBoleto tentava registrar o mesmo boleto 2 vezes, então pensei deve ser erro no meu código, então ignorei o erro e na segunda tentativa dava certo, isso gerando varios boletos dentro de um while, sendo que o envio é individual de cada boleto e não em lote. Então como mesmo dando erro de duplicidade de registro tava dando certo, deixei quieto, então onten o Rodrigo da c6Bank me chamou no zap e falou que a minha integração já tinha registrado mais de 1000 erro de tentativa de registro de boleto no servidor da c6Bank. Então fui analisar a fundo e vi que no if FBoleto.ListadeBoletos.Count > 0 then da unit ACBrBoletoWS no segundo boleto ele ordenava errado e ao inves de pegar o o segundo boleto, pregava era o primeiro boleto causando duplicidade de registro, outros colegas me relataram a mesma coisa também. Fiz uma alteração na unit ACBrBoletoWS e estou postando em anexo para ser analisada se a alteração está correta, pois se trata de uma unit global onde varios bancos usa ela para o registro de boleto. Só alterei essa parte abaixo da unit. function TBoletoWS.Enviar: Boolean; var indice : Integer; LJsonEnvio: String; LUltimoEnvio: TDateTime; begin Banco := FBoleto.Banco.TipoCobranca; Result := False; FBoletoWSClass.FHTTPSend.Timeout := FBoleto.Configuracoes.WebService.TimeOut; try if FBoleto.ListadeBoletos.Count > 0 then begin // Pegando sempre o último registro indice := Pred(FBoleto.ListadeBoletos.Count); // último índice FBoletoWSClass.FTitulo := FBoleto.ListadeBoletos[indice]; LJsonEnvio := FBoletoWSClass.GerarRemessa; Result := FBoletoWSClass.Enviar; FRetornoWS := FBoletoWSClass.FRetornoWS; RetornoBanco.RetWS := FRetornoWS; RetornoBanco.FEnvWS := LJsonEnvio; RetornoBanco.RetornoEnvio(indice); end else if (FBoleto.Configuracoes.WebService.Operacao in [tpConsulta]) then // Apenas Consulta Genérica begin FBoletoWSClass.GerarRemessa; Result := FBoletoWSClass.Enviar; FRetornoWS := FBoletoWSClass.FRetornoWS; RetornoBanco.RetWS := FRetornoWS; RetornoBanco.RetornoEnvio(0); end; except on E: Exception do begin if not Assigned(FBoletoWSClass.RetornoBanco) or ((FBoletoWSClass.RetornoBanco.CodRetorno = 0) and (Trim(FBoletoWSClass.RetornoBanco.Msg) = '')) then DoLog('Falha Envio: ' + ACBrStr(E.Message), logSimples) else DoLog('Erro Envio: ' + ACBrStr(IntToStr(FBoletoWSClass.RetornoBanco.CodRetorno) + sLineBreak + FBoletoWSClass.RetornoBanco.Msg + sLineBreak + E.Message), logSimples); raise; end; end; ACBrBoletoWS.pas
Antonio Gomes Postado 6 Junho Postado 6 Junho @panda Então Jhoni, conforme conversamos, uma sugestão, é avaliar, se o boleto a ser enviado, já tem o dado que o retorno da API preenche, no caso, nosso numero é um caso. Tipo, colocar um continue, para nao mandar de novo, se tem ele já veja: try if FBoleto.ListadeBoletos.Count > 0 then begin for indice := 0 to Pred(FBoleto.ListadeBoletos.Count) do begin if NumeroDoBoletoAPI <> '' then // precisa pegar o campo que grava o retorno do numero do boleto Continue;
Consultores antonio.carlos Postado 6 Junho Consultores Postado 6 Junho Obrigado pela contribuição, em breve será validada para possível inclusão ao svn - #TK-7183
Antonio Gomes Postado 6 Junho Postado 6 Junho 1 hora atrás, antonio.carlos disse: Obrigado pela contribuição, em breve será validada para possível inclusão ao svn - #TK-7183 analisando, para que nao seja acionado o mesmo processo se algum boleto da lista estiver processado, ignorar: Analisando o retorno de cada unit Ret, no caso o C6 ele preenche isso: ARetornoWS.DadosRet.IDBoleto.CodBarras := OnlyNumber(LJsonObject.AsString['bar_code']); ARetornoWS.DadosRet.IDBoleto.LinhaDig := OnlyNumber(LJsonObject.AsString['digitable_line']); ARetornoWS.DadosRet.IDBoleto.NossoNum := LJsonObject.AsString['our_number'];//LinhaDigitavelExplodeInfo(ARetornoWS.DadosRet.IDBoleto.LinhaDig,TLDNossoNumero);//LJsonObject.AsString['internal_id']; ARetornoWS.DadosRet.IDBoleto.IDBoleto := LJsonObject.AsString['id']; ARetornoWS.DadosRet.TituloRet.NossoNumeroCorrespondente := ARetornoWS.DadosRet.IDBoleto.IDBoleto; ARetornoWS.DadosRet.TituloRet.CodBarras := ARetornoWS.DadosRet.IDBoleto.CodBarras; ARetornoWS.DadosRet.TituloRet.LinhaDig := ARetornoWS.DadosRet.IDBoleto.LinhaDig; ARetornoWS.DadosRet.TituloRet.NossoNumero := ARetornoWS.DadosRet.IDBoleto.NossoNum; ARetornoWS.DadosRet.TituloRet.Carteira := LJsonObject.AsString['billing_scheme']; ARetornoWS.DadosRet.TituloRet.Vencimento := DateToDateTime(LJsonObject.AsString['due_date']); Logo, penso que talvez criar um rotina virtual, de cada unit, ainda tem poucos para mexer, com uma coisa tipo; Hipotese, em cada banco: function TRetornoEnvio_C6.BoletoFoiEnviado(const ARetornoWS: TACBrBoletoRetornoWS): Boolean; begin // analisar se o boleto na fila está ja com dado que a api retorna, precisa ser cada banco, pois cada um manda de uma forma, precisa ser a informacao vital da existencia do boleto na api ou o retorno do sucesso do registro Result:= (ARetornoWS.DadosRet.IDBoleto.CodBarras <> '') and (ARetornoWS.DadosRet.IDBoleto.LinhaDig <> ''); end;
Jhonlenon Ribeiro Postado 6 Junho Autor Postado 6 Junho (editado) Testei a ideia do @Antonio Gomes e deu certo...como mostra o print abaixo..unit em anexo ACBrBoletoWS.pas Editado 6 Junho por Jhonlenon Ribeiro
Consultores Victor H. Gonzales - Panda Postado 6 Junho Consultores Postado 6 Junho 8 horas atrás, Jhonlenon Ribeiro disse: Bom dia, já tem uns 8 meses que fiz a homologação da emissão do boleto c6Bank via API, até ai tudo certo, quando fiz a homologação do boleto percebi que o componente ACBrBoleto tentava registrar o mesmo boleto 2 vezes, então pensei deve ser erro no meu código, então ignorei o erro e na segunda tentativa dava certo, isso gerando varios boletos dentro de um while, sendo que o envio é individual de cada boleto e não em lote. Então como mesmo dando erro de duplicidade de registro tava dando certo, deixei quieto, então onten o Rodrigo da c6Bank me chamou no zap e falou que a minha integração já tinha registrado mais de 1000 erro de tentativa de registro de boleto no servidor da c6Bank. Então fui analisar a fundo e vi que no if FBoleto.ListadeBoletos.Count > 0 then da unit ACBrBoletoWS no segundo boleto ele ordenava errado e ao inves de pegar o o segundo boleto, pregava era o primeiro boleto causando duplicidade de registro, outros colegas me relataram a mesma coisa também. Fiz uma alteração na unit ACBrBoletoWS e estou postando em anexo para ser analisada se a alteração está correta, pois se trata de uma unit global onde varios bancos usa ela para o registro de boleto. Só alterei essa parte abaixo da unit. function TBoletoWS.Enviar: Boolean; var indice : Integer; LJsonEnvio: String; LUltimoEnvio: TDateTime; begin Banco := FBoleto.Banco.TipoCobranca; Result := False; FBoletoWSClass.FHTTPSend.Timeout := FBoleto.Configuracoes.WebService.TimeOut; try if FBoleto.ListadeBoletos.Count > 0 then begin // Pegando sempre o último registro indice := Pred(FBoleto.ListadeBoletos.Count); // último índice FBoletoWSClass.FTitulo := FBoleto.ListadeBoletos[indice]; LJsonEnvio := FBoletoWSClass.GerarRemessa; Result := FBoletoWSClass.Enviar; FRetornoWS := FBoletoWSClass.FRetornoWS; RetornoBanco.RetWS := FRetornoWS; RetornoBanco.FEnvWS := LJsonEnvio; RetornoBanco.RetornoEnvio(indice); end else if (FBoleto.Configuracoes.WebService.Operacao in [tpConsulta]) then // Apenas Consulta Genérica begin FBoletoWSClass.GerarRemessa; Result := FBoletoWSClass.Enviar; FRetornoWS := FBoletoWSClass.FRetornoWS; RetornoBanco.RetWS := FRetornoWS; RetornoBanco.RetornoEnvio(0); end; except on E: Exception do begin if not Assigned(FBoletoWSClass.RetornoBanco) or ((FBoletoWSClass.RetornoBanco.CodRetorno = 0) and (Trim(FBoletoWSClass.RetornoBanco.Msg) = '')) then DoLog('Falha Envio: ' + ACBrStr(E.Message), logSimples) else DoLog('Erro Envio: ' + ACBrStr(IntToStr(FBoletoWSClass.RetornoBanco.CodRetorno) + sLineBreak + FBoletoWSClass.RetornoBanco.Msg + sLineBreak + E.Message), logSimples); raise; end; end; ACBrBoletoWS.pas 22.1 kB · 0 downloads no caso não é o while em si... mas em si deu problema na transmissão e vocês estão transmitindo a mesma lista pela segunda vez? 5 horas atrás, Antonio Gomes disse: analisando, para que nao seja acionado o mesmo processo se algum boleto da lista estiver processado, ignorar: Analisando o retorno de cada unit Ret, no caso o C6 ele preenche isso: ARetornoWS.DadosRet.IDBoleto.CodBarras := OnlyNumber(LJsonObject.AsString['bar_code']); ARetornoWS.DadosRet.IDBoleto.LinhaDig := OnlyNumber(LJsonObject.AsString['digitable_line']); ARetornoWS.DadosRet.IDBoleto.NossoNum := LJsonObject.AsString['our_number'];//LinhaDigitavelExplodeInfo(ARetornoWS.DadosRet.IDBoleto.LinhaDig,TLDNossoNumero);//LJsonObject.AsString['internal_id']; ARetornoWS.DadosRet.IDBoleto.IDBoleto := LJsonObject.AsString['id']; ARetornoWS.DadosRet.TituloRet.NossoNumeroCorrespondente := ARetornoWS.DadosRet.IDBoleto.IDBoleto; ARetornoWS.DadosRet.TituloRet.CodBarras := ARetornoWS.DadosRet.IDBoleto.CodBarras; ARetornoWS.DadosRet.TituloRet.LinhaDig := ARetornoWS.DadosRet.IDBoleto.LinhaDig; ARetornoWS.DadosRet.TituloRet.NossoNumero := ARetornoWS.DadosRet.IDBoleto.NossoNum; ARetornoWS.DadosRet.TituloRet.Carteira := LJsonObject.AsString['billing_scheme']; ARetornoWS.DadosRet.TituloRet.Vencimento := DateToDateTime(LJsonObject.AsString['due_date']); Logo, penso que talvez criar um rotina virtual, de cada unit, ainda tem poucos para mexer, com uma coisa tipo; Hipotese, em cada banco: function TRetornoEnvio_C6.BoletoFoiEnviado(const ARetornoWS: TACBrBoletoRetornoWS): Boolean; begin // analisar se o boleto na fila está ja com dado que a api retorna, precisa ser cada banco, pois cada um manda de uma forma, precisa ser a informacao vital da existencia do boleto na api ou o retorno do sucesso do registro Result:= (ARetornoWS.DadosRet.IDBoleto.CodBarras <> '') and (ARetornoWS.DadosRet.IDBoleto.LinhaDig <> ''); end; há bancos que não devolvem esses 2 casos. no caso vocês estão montando uma lista... envia... gera algum problema, vocês não reprocessam a lista e simplemente faz o envio novamente é isso? Victor H Gonzales - Pandaaa Ajude o Projeto ACBr crescer - Assine o SAC (15) 2105-0750 (15)99790-2976. Discord Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !! "Aprender é a única coisa que a mente nunca se cansa, nunca tem medo e nunca se arrepende” - Leonardo da Vinci "Ter sucesso é falhar repetidamente, mas sem perder o entusiasmo"
Jhonlenon Ribeiro Postado 6 Junho Autor Postado 6 Junho (editado) Boa tarde @Victor H. Gonzales - Panda realmente remover o for não pode, mais que tal validar com só em cima do c6Bank? porque existe varias formas de fazer o envio. print em anexo. Editado 6 Junho por Jhonlenon Ribeiro
Jhonlenon Ribeiro Postado 6 Junho Autor Postado 6 Junho @Victor H. Gonzales - Panda e se validasse por status não daria certo? 1
Consultores Victor H. Gonzales - Panda Postado 6 Junho Consultores Postado 6 Junho Indiferente isso em teoria só ocorreria se enviasse o comando enviar mais de uma vez Victor H Gonzales - Pandaaa Ajude o Projeto ACBr crescer - Assine o SAC (15) 2105-0750 (15)99790-2976. Discord Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !! "Aprender é a única coisa que a mente nunca se cansa, nunca tem medo e nunca se arrepende” - Leonardo da Vinci "Ter sucesso é falhar repetidamente, mas sem perder o entusiasmo"
Antonio Gomes Postado 7 Junho Postado 7 Junho 6 horas atrás, Victor H. Gonzales - Panda disse: Indiferente isso em teoria só ocorreria se enviasse o comando enviar mais de uma vez Se der erro no envio da api sim, isso acontece. Pense fora da caixa.
Consultores Victor H. Gonzales - Panda Postado Segunda as 14:41 Consultores Postado Segunda as 14:41 Em 07/06/2025 at 01:29, Antonio Gomes disse: Se der erro no envio da api sim, isso acontece. Pense fora da caixa. Bom dia, O Fluxo de todos os componentes você carrega a lista de envio, realiza o envio, faz o tratamento do retorno do envio, se necessário limpa a lista corrige as informações e faz um novo envio. Como é o caso da NFe, se tu adicionar uma NFe, a mesma gerar erro de NCM por exemplo, tu tem que tratar o retorno limpar a lista, corrigir a informação, criar uma nova NFe na lista depois realizar o envio. Os demais componentes o fluxo de operação é o mesmo, seja para correção de dados ou para evitar duplicidade, o retorno do envio precisa ser tratado sempre. Victor H Gonzales - Pandaaa Ajude o Projeto ACBr crescer - Assine o SAC (15) 2105-0750 (15)99790-2976. Discord Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !! "Aprender é a única coisa que a mente nunca se cansa, nunca tem medo e nunca se arrepende” - Leonardo da Vinci "Ter sucesso é falhar repetidamente, mas sem perder o entusiasmo"
Antonio Gomes Postado Segunda as 16:30 Postado Segunda as 16:30 (editado) 1 hora atrás, Victor H. Gonzales - Panda disse: Bom dia, O Fluxo de todos os componentes você carrega a lista de envio, realiza o envio, faz o tratamento do retorno do envio, se necessário limpa a lista corrige as informações e faz um novo envio. Como é o caso da NFe, se tu adicionar uma NFe, a mesma gerar erro de NCM por exemplo, tu tem que tratar o retorno limpar a lista, corrigir a informação, criar uma nova NFe na lista depois realizar o envio. Os demais componentes o fluxo de operação é o mesmo, seja para correção de dados ou para evitar duplicidade, o retorno do envio precisa ser tratado sempre. Não sei, eu não envio monte de NFe, sempre foi uma a uma, justamente para evitar esses problemas, mas o boleto, te dizer a verdade eu vi esse problema, pq estou sempre trocando ideias com quem mexe com as integrações de bancos, ainda mais o C6... Logo, eu não tenho o habito de usar o componente para enviar o pacote de carnes como vocês tem nos demos. Lembre-se, esse problema é com carnê. Mesmo eu com carnê eu processo um boleto por vez, nem impressão eu uso do objeto, pois se mexer nessa mesma lista que vc falou para limpar a impressão cai por terra. De novo, pense fora da caixa, com a mente do lado de cá. Obs: está propicio a data erro na parcela, mesmo sendo o mesmo cliente na lista, api falhar no final do envio.... Editado Segunda as 16:32 por Antonio Gomes
Consultores Daniel InfoCotidiano Postado Segunda as 17:10 Consultores Postado Segunda as 17:10 Seguimos este Fluxo. carrega 50 boletos. envia. tratar o retorno deste envio. (no retorno vc sabe se o banco aceitou ou não aquele boleto.) Os boletos que não foram *aceitos precisam ser corrigidos; (*Erros diversos, deste timeout, como seuNumero Duplicado,e campos inválidos, como CEP, CPF, ETC) Limpar a lista Add na lista apenas os boletos corrigidos e reenviar (nao reenviar boletos que foram incluso na primeira tentativa) Daniel de Morais (Infocotidiano) Ajude o Projeto ACBr crescer - Assine o SAC (15) 2105-0750 (15)99790-2976. Discord
Antonio Gomes Postado Segunda as 17:25 Postado Segunda as 17:25 Estamos quase lá então, uma ideia poderia ser salvar essa lista, e retornar para impressão? Das enviadas e que nao precisam mais ser transmitidas... Carece eu testar, se remover da lista as enviadas com sucesso se imprime certo as 50 parcelas colocadas, se limpa so a parte de envio, se sim qual comando é? Hoje precisa limpar o ListaDeBoletos, que penso que esteja atrelado o retorno em TBoleto.TotalListaRetornoWeb ou seja o titulo esta dentro da lista né? Ex: Boleto.ListadeBoletos.Clear; // tem nao fazer isso, mas limpar so lista de envio ?
Consultores Daniel InfoCotidiano Postado Segunda as 20:07 Consultores Postado Segunda as 20:07 1. Vou tratar a lista inteira, e qdo result code 200 persisto nos meus registros q ele foi aceito, o emv.. enfim 2. listo para o usuário todos títulos rejeitados para que ele possa ajustar conforme algum erro. (cep, cpf, valor... etc) 3. limpo a lista de titulo.. ela vai ficar zerada. 4. adiciono os títulos que o usuário ajustou/corrigiu o problema. pode ser 10 ou 30 rejeitados. não sabemos se o usuário corrigiu todos no mesmo dia. 5. para eu imprimir, limpo a lista e carrego todos títulos com status de registrado e não foi impresso e imprimo. (mas nada impede de vc rodar um "for" e imprimir o índice dos 10 primeiros vai dar certo) 1 Daniel de Morais (Infocotidiano) Ajude o Projeto ACBr crescer - Assine o SAC (15) 2105-0750 (15)99790-2976. Discord
Recommended Posts
Crie uma conta ou entre para comentar
Você precisar ser um membro para fazer um comentário
Criar uma conta
Crie uma nova conta em nossa comunidade. É fácil!
Crie uma nova contaEntrar
Já tem uma conta? Faça o login.
Entrar Agora