ANDERSON JUNIOR GADO DA SILVA Postado 11 Junho Postado 11 Junho Ao tentar enviar um boleto pelo banco inter via api, ele precisa fazer uma consulta, essa consulta precisa alterar o scopo para *.read em vez de write, fiz uma justes vou enviar abaixo. function TBoletoW_Inter_API.Enviar: boolean; var LJsonObject : TACBrJSONObject; LOrigScope : String; begin Result := inherited Enviar; (* Tratamento automatico qdo tpINCLUI com pix. Entao ele vai enviar capturar a reposta para pegar o codigoSolicitacao e realizar uma consulta detalhe automaticamente para retornar o boleto com QrCODE *) if (Boleto.Cedente.CedenteWS.IndicadorPix) and (Boleto.Configuracoes.WebService.Operacao = tpInclui) then begin LJsonObject := TACBrJSONObject.Parse( FRetornoWS ); try if NaoEstaVazio(LJsonObject.AsString['codigoSolicitacao']) then begin ATitulo.NossoNumeroCorrespondente := LJsonObject.AsString['codigoSolicitacao']; Boleto.Configuracoes.WebService.Operacao := tpConsultaDetalhe; // Salva o scope original (boleto-cobranca.write) usado na criacao do boleto LOrigScope := Boleto.Cedente.CedenteWS.Scope; // Troca para scope de leitura: a API v3 do Inter exige boleto-cobranca.read // no endpoint GET de consulta detalhe, rejeitando tokens com scope write (HTTP 401) Boleto.Cedente.CedenteWS.Scope := 'boleto-cobranca.read'; try GerarDados; Result := inherited Enviar; finally // Restaura o scope original para nao afetar proximas operacoes Boleto.Cedente.CedenteWS.Scope := LOrigScope; end; end; finally LJsonObject.Free; Boleto.Configuracoes.WebService.Operacao := tpInclui; end; end; end;
Antonio Gomes Postado 12 Junho Postado 12 Junho Interessante, eu coloco ele todos de uma vez só e não gera problema, voce tentou?
ANDERSON JUNIOR GADO DA SILVA Postado 12 Junho Autor Postado 12 Junho (editado) eu fiz um teste com um boleto só, não sei se entendi a sua colocação, o erro que tive ao enviar apenas um registro foi falha na autenticação ao tentar executar a consulta, não tenho o log do acbr, mas basicamente reclamada da autenticação do scopo, ao fazer o ajuste foi resolvido, abaixou vou postar a minha rotina. function TBoletoEnviaWS.About: IDataStream; Var VBanco: IJSONValue; VCedente: IJSONValue; VTitulos: IJSONValue; VRequizicao: IJSONObject; VReturn: IReturn; VApelido: String; VRetry: Integer; begin try VRequizicao:=TJSONObject.New(FRequisicao); VBanco:=VRequizicao.Path('Banco'); VCedente:=VRequizicao.Path('Cedente'); VTitulos:=VRequizicao.Path('Titulos'); VApelido:=VRequizicao['banco_apelido'].AsString; VRetry := 0; repeat with TBoleto.Create(FPerfil, VApelido) do try VReturn:=RegistrarBoletosWS(VBanco, VCedente, VTitulos, VRequizicao.Get('scope', ''), FGeraPDF); if Assigned(FLogger) then FLogger.LogDebug(VReturn.AsString, 'TBoletoEnviaWS.About'); if VReturn.Fail and TemRateLimitNaResposta(VReturn) and (VRetry < C_INTER_RATE_LIMIT_MAX_RETRY) then begin Inc(VRetry); if Assigned(FLogger) then FLogger.LogDebug( Format('Rate limit detectado (HTTP 429). Aguardando %ds antes de retentar (tentativa %d/%d)...', [C_INTER_RATE_LIMIT_SLEEP_MS div 1000, VRetry, C_INTER_RATE_LIMIT_MAX_RETRY]), 'TBoletoEnviaWS.About' ); Sleep(C_INTER_RATE_LIMIT_SLEEP_MS); end else Break; finally Free; end; until VRetry >= C_INTER_RATE_LIMIT_MAX_RETRY; if VReturn.Fail then raise Exception.Create(VReturn.AsString); Result:=VReturn.Content; Except on E: Exception do begin if Assigned(FLogger) then FLogger.LogError(E.Message, 'TBoletoEnviaWS.About'); raise Exception.CreateFmt('Erro ao enviar por WS: %s', [E.Message]); end; end; end; e aqui a outra function TBoleto.RegistrarBoletosWS(const ABanco, ACedente, ATitulos: IJSONValue; const AScope: String; const ARetPDF: Boolean): IReturn; Var VSucesso: Boolean; VRetorno: IJSONObject; VRejeicao: IJSONObject; VListaBoletos: IJSONArray; I,J,Y: Integer; VPDF: IDataStream; begin VRetorno:=TJSONObject.New(); VListaBoletos:=TJSONArray.New(); ConfigInicial((ABanco as IJSONObject), (ACedente as IJSONObject)); Cedente.CedenteWS.Scope:=AScope; try case ATitulos.JSONType of TEnumJSONType.ejtArray: begin CriarTitulos(ATitulos as IJSONArray); end; TEnumJSONType.ejtObject: begin CriarTitulo(ATitulos as IJSONObject); end; end; Configuracoes.WebService.Operacao:=tpInclui; VSucesso:=Enviar; if TotalListaRetornoWeb > 0 then begin for I:= 0 to TotalListaRetornoWeb -1 do begin VRetorno:=TJSONObject.New(); VRetorno.Put('Cod_Retorno', ListaRetornoWeb[I].CodRetorno); VRetorno.Put('Msg_Retorno', ListaRetornoWeb[I].MsgRetorno); VRetorno.Put('Ori_Retorno', ListaRetornoWeb[I].OriRetorno); VRetorno.Put('HTTP_Result', ListaRetornoWeb[I].HTTPResultCode); VRetorno.Put('JSON', ListaRetornoWeb[I].JSON); VRejeicao:=TJSONObject.New(); for J:= 0 to ListaRetornoWeb[I].ListaRejeicao.Count - 1 do begin VRejeicao.Put(J.ToString, TJSONObject.New() .Put('Campo', ListaRetornoWeb[i].ListaRejeicao[j].Campo) .Put('Codigo', ListaRetornoWeb[i].ListaRejeicao[j].Codigo) .Put('Versao', ListaRetornoWeb[i].ListaRejeicao[j].Versao) .Put('Mensagem', ListaRetornoWeb[i].ListaRejeicao[j].Mensagem) .Put('Ocorrencia', ListaRetornoWeb[i].ListaRejeicao[j].Ocorrencia) .Put('Valor', ListaRetornoWeb[i].ListaRejeicao[j].Valor) ); end; VRetorno.Put('Rejeicao', VRejeicao); VRetorno.Put('Header', TJSONObject.New() .Put('Versao', ListaRetornoWeb[i].Header.Versao) .Put('Autenticacao', ListaRetornoWeb[i].Header.Autenticacao) .Put('Usuario_Servico', ListaRetornoWeb[i].Header.Usuario_Servico) .Put('Usuario', ListaRetornoWeb[i].Header.Usuario) .Put('Operacao', TipoOperacaoToStr(ListaRetornoWeb[i].Header.Operacao)) .Put('Indice', ListaRetornoWeb[i].Header.Indice) .Put('Sistema_Origem', ListaRetornoWeb[i].Header.Sistema_Origem) .Put('Agencia', ListaRetornoWeb[i].Header.Agencia) .Put('ID_Origem', ListaRetornoWeb[i].Header.Id_Origem) .Put('Data_Hora', ListaRetornoWeb[i].Header.Data_Hora) .Put('ID_Processo', ListaRetornoWeb[i].Header.Id_Processo) .Put('Excessao', ListaRetornoWeb[i].DadosRet.Excecao) .Put('Origem_Retorno', ListaRetornoWeb[i].DadosRet.ControleNegocial.OriRetorno) .Put('NSU', ListaRetornoWeb[i].DadosRet.ControleNegocial.NSU) .Put('Cod_Retorno', ListaRetornoWeb[i].DadosRet.ControleNegocial.CodRetorno) .Put('Msg_Retorno', ListaRetornoWeb[i].DadosRet.ControleNegocial.Retorno) .Put('Data', ListaRetornoWeb[i].DadosRet.Comprovante.Data) .Put('Hora', ListaRetornoWeb[i].DadosRet.Comprovante.Hora) .Put('Codigo_Barras', ListaRetornoWeb[i].DadosRet.IDBoleto.CodBarras) .Put('Linha_Digitavel', ListaRetornoWeb[i].DadosRet.IDBoleto.LinhaDig) .Put('Nosso_Numero', ListaRetornoWeb[i].DadosRet.IDBoleto.NossoNum) .Put('URL', ListaRetornoWeb[i].DadosRet.IDBoleto.URL) .Put('Numero_Documento', ListaRetornoWeb[i].DadosRet.TituloRet.NumeroDocumento) .Put('Data_Vencimento', ListaRetornoWeb[i].DadosRet.TituloRet.Vencimento) .Put('Valor', ListaRetornoWeb[i].DadosRet.TituloRet.ValorDocumento) ); if not ListaRetornoWeb[i].DadosRet.TituloRet.CodBarras.IsEmpty then begin VRetorno.Put('Titulo', TJSONObject.New() .Put('vencimento_titulo', ListaRetornoWeb[i].DadosRet.TituloRet.Vencimento) .Put('tipo_carteira_titulo', ListaRetornoWeb[i].DadosRet.TituloRet.Carteira) .Put('nosso_numero', ListaRetornoWeb[i].DadosRet.TituloRet.NossoNumero) .Put('seu_numero', ListaRetornoWeb[i].DadosRet.TituloRet.SeuNumero) .Put('especie', ListaRetornoWeb[i].DadosRet.TituloRet.EspecieDoc) .Put('codigo_barras', ListaRetornoWeb[i].DadosRet.TituloRet.CodBarras) .Put('numero_linha_digitavel', ListaRetornoWeb[i].DadosRet.TituloRet.LinhaDig) .Put('local_pagamento', ListaRetornoWeb[i].DadosRet.TituloRet.Mensagem.Text) .Put('data_processamento', ListaRetornoWeb[i].DadosRet.TituloRet.DataProcessamento) .Put('data_emissao', ListaRetornoWeb[i].DadosRet.TituloRet.DataDocumento) .Put('uso_banco', ListaRetornoWeb[i].DadosRet.TituloRet.UsoBanco) .Put('valor_titulo', ListaRetornoWeb[i].DadosRet.TituloRet.ValorDocumento) .Put('valor_desconto', ListaRetornoWeb[i].DadosRet.TituloRet.ValorDesconto) .Put('valor_outra_deducao', ListaRetornoWeb[i].DadosRet.TituloRet.ValorDespesaCobranca) .Put('valor_juro_multa', ListaRetornoWeb[i].DadosRet.TituloRet.ValorMoraJuros) .Put('valor_outro_acrescimo', ListaRetornoWeb[i].DadosRet.TituloRet.ValorOutrosCreditos) .Put('valor_total_cobrado', ListaRetornoWeb[i].DadosRet.TituloRet.ValorPago) .Put('texto_informacao_cliente_beneficiario', ListaRetornoWeb[i].DadosRet.TituloRet.Informativo.Text) ); //localizar o titulo na lista de retornos e alterar a propriedade nosso numero, no momento isso só testado no banco inter if Banco.TipoCobranca = cobBancoInter then begin Y:=ListadeBoletos.IndexOfSeuNumero(ListaRetornoWeb[i].DadosRet.TituloRet.SeuNumero); if Y > -1 then begin ListadeBoletos[Y].NossoNumero:=ListaRetornoWeb[i].DadosRet.TituloRet.NossoNumero; end; end; end; VListaBoletos.Put(VRetorno); end; end; VPDF:=TDataStream.New; if ARetPDF then begin GeraBoletoPDF(VPDF, FLayoutImpressao); end; Result:=TReturn.New( VSucesso, TJSONObject.New() .Put('Retorno', VListaBoletos) .Put('PDF', VPDF) ); except on E: Exception do begin Result:=TReturn.New(False, 'Erro ao enviar boletos ws: '+E.Message); raise Exception.CreateFmt('Erro ao enviar boletos ws: %s', [E.Message]); end; end; end; Editado 12 Junho por ANDERSON JUNIOR GADO DA SILVA Complementação
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