Ir para conteúdo
  • Cadastre-se

  • Este tópico foi criado há 378 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

  • Membros
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

  • Este tópico foi criado há 378 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

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.

The popup will be closed in 10 segundos...