Ir para conteúdo
  • Cadastre-se

dev botao

Recommended Posts

Postado

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

Postado

@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;

 

Postado
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;

  • Consultores
Postado
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?

Consultor SAC ACBr

Victor H Gonzales - Pandaaa
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(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"

  • Consultores
Postado

Indiferente isso em teoria só ocorreria se enviasse o comando enviar mais de uma vez

Consultor SAC ACBr

Victor H Gonzales - Pandaaa
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(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"

Postado
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
Postado
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.

Consultor SAC ACBr

Victor H Gonzales - Pandaaa
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(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"

Postado (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 por Antonio Gomes
  • Consultores
Postado

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)

 

 

Consultor SAC ACBr

Daniel de Morais (Infocotidiano)
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Postado

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
Postado

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)



 

  • Obrigado 1
Consultor SAC ACBr

Daniel de Morais (Infocotidiano)
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

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 conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • 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.