Ir para conteúdo
  • Cadastre-se

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

Recommended Posts

Postado

O Banco Central (BC) está lançando a duplicata escritural, uma versão eletrônica e totalmente rastreável da duplicata física, para modernizar e dar mais segurança ao mercado de crédito. A transição está em andamento, com testes ocorrendo até novembro de 2025 e o sistema com funcionalidades restritas até outubro de 2026, quando se prevê o pleno funcionamento a partir dessa data. A adoção será gradual, começando por grandes empresas e expandindo para outras até abril de 2028, com o objetivo de reduzir custos, fraudes e aumentar a oferta de crédito.

  • Consultores
Postado

Tem o link das documentações? e maiores informações?

 

Consultora ACBr Pro

Juliomar Marchetti

Ajude o Projeto ACBr crescer - Seja Pro

discord: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br

 

MVP_NewLogo_100x100_Transparent-02.png
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 !!

Postado
Em 18/11/2025 at 23:23, Juliomar Marchetti disse:

Tem o link das documentações? e maiores informações?

Consegui muitas informações no ChatGPT. Inclusive a Inteligência Artificial me deu comandos prontos em Delphi já para rodar e conectar com a CERC/B3

abaixo está um módulo Delphi pronto que implementa OAuth2 (client_credentials e refresh_token) com exemplos de uso, tratamento de erros, thread-safety e dicas de segurança. Pressuposições que fiz (comuns para registradoras como CERC/B3):

  • você usará client_credentials (mais comum para sistemas server-to-server);

  • o token_endpoint retorna JSON com access_token, expires_in e possivelmente refresh_token.

Cole este unit no seu projeto e adapte TokenURL, ClientID, ClientSecret e Scope conforme a registradora.

 
 
unit OAuth2Client; interface uses System.SysUtils, System.Classes, System.SyncObjs, System.DateUtils, System.Generics.Collections, System.JSON, System.Net.HttpClient, System.Net.URLClient; type EOAuth2Error = class(Exception); TOAuth2Token = record AccessToken: string; RefreshToken: string; ExpiresAt: TDateTime; // UTC Scope: string; TokenType: string; function IsValid: Boolean; end; TOAuth2Client = class private FTokenURL: string; FClientID: string; FClientSecret: string; FScope: string; FHTTP: TNetHTTPClient; FToken: TOAuth2Token; FLock: TObject; FLastError: string; procedure ParseTokenResponse(const JSONText: string); function RequestToken_ClientCredentials: TOAuth2Token; function RequestToken_WithRefresh(const ARefreshToken: string): TOAuth2Token; procedure SecureEraseClientSecret; public constructor Create(const ATokenURL, AClientID, AClientSecret, AScope: string; AHTTP: TNetHTTPClient = nil); destructor Destroy; override; { Retorna authorization header, garantindo que o token está válido. Exemplo: 'Bearer <token>' } function GetAuthorizationHeader: string; { Força obtenção de token (útil para testes) } procedure AcquireToken; { Se houver refresh_token, tenta renovar; caso contrário, pede novo token via client_credentials } procedure EnsureTokenValid; property LastError: string read FLastError; end; implementation { TOAuth2Token } function TOAuth2Token.IsValid: Boolean; begin // considera válido com 60s de margem Result := (AccessToken <> '') and (MinutesBetween(NowToUTC, ExpiresAt) > 0); end; { TOAuth2Client } constructor TOAuth2Client.Create(const ATokenURL, AClientID, AClientSecret, AScope: string; AHTTP: TNetHTTPClient); begin inherited Create; FTokenURL := ATokenURL; FClientID := AClientID; FClientSecret := AClientSecret; FScope := AScope; if AHTTP = nil then begin FHTTP := TNetHTTPClient.Create(nil); // ajustar timeouts se desejar: FHTTP.ConnectionTimeout := 30000; FHTTP.ResponseTimeout := 30000; end else FHTTP := AHTTP; FLock := TObject.Create; FToken := Default(TOAuth2Token); end; destructor TOAuth2Client.Destroy; begin SecureEraseClientSecret; FHTTP.Free; FreeAndNil(FLock); inherited; end; procedure TOAuth2Client.SecureEraseClientSecret; begin // Limpa a string do client secret (melhor do que deixar em memória) FClientSecret := StringOfChar(#0, Length(FClientSecret)); FClientSecret := ''; end; procedure TOAuth2Client.ParseTokenResponse(const JSONText: string); var J: TJSONValue; jobj: TJSONObject; expires_in: Integer; s: string; begin J := TJSONObject.ParseJSONValue(JSONText); if not Assigned(J) then raise EOAuth2Error.Create('Resposta do token não é JSON válido'); try if not (J is TJSONObject) then raise EOAuth2Error.Create('Resposta do token inesperada'); jobj := J as TJSONObject; if jobj.GetValue('error') <> nil then begin s := jobj.GetValue<string>('error_description', jobj.GetValue<string>('error', 'erro desconhecido')); raise EOAuth2Error.CreateFmt('OAuth2 error: %s', [s]); end; FToken.AccessToken := jobj.GetValue<string>('access_token', ''); FToken.TokenType := jobj.GetValue<string>('token_type', 'Bearer'); FToken.Scope := jobj.GetValue<string>('scope', FScope); FToken.RefreshToken := jobj.GetValue<string>('refresh_token', ''); expires_in := jobj.GetValue<Integer>('expires_in', 0); // ExpiresAt em UTC: NowToUTC + expires_in segundos if expires_in > 0 then FToken.ExpiresAt := IncSecond(NowToUTC, expires_in) else // default para 5 minutos se não informado (evitar ficar inválido) FToken.ExpiresAt := IncMinute(NowToUTC, 5); finally J.Free; end; end; function TOAuth2Client.RequestToken_ClientCredentials: TOAuth2Token; var Resp: IHTTPResponse; Body: TStringStream; Params: TStringList; Headers: TNetHeaders; Encoded: string; sBody: string; begin Params := TStringList.Create; try // Form-encoded body (application/x-www-form-urlencoded) Params.Add('grant_type=client_credentials'); if FScope <> '' then Params.Add('scope=' + TNetEncoding.URL.Encode(FScope)); Body := TStringStream.Create(Params.DelimitedText.Replace(#13#10,'&',[rfReplaceAll]), TEncoding.UTF8); try Headers := [ TNameValuePair.Create('Content-Type', 'application/x-www-form-urlencoded') ]; // credencial via Authorization basic (recomendado) Encoded := TNetEncoding.Base64.Encode(FClientID + ':' + FClientSecret); Headers := Headers + [TNameValuePair.Create('Authorization', 'Basic ' + Encoded)]; Resp := FHTTP.Post(FTokenURL, Body, nil, Headers); sBody := Resp.ContentAsString(TEncoding.UTF8); if not (Resp.StatusCode in [200,201]) then raise EOAuth2Error.CreateFmt('Token endpoint retornou %d: %s', [Resp.StatusCode, sBody]); // parseia e popula FToken ParseTokenResponse(sBody); Result := FToken; finally Body.Free; end; finally Params.Free; end; end; function TOAuth2Client.RequestToken_WithRefresh(const ARefreshToken: string): TOAuth2Token; var Body: TStringStream; Params: TStringList; Headers: TNetHeaders; Resp: IHTTPResponse; sBody: string; Encoded: string; begin Params := TStringList.Create; try Params.Add('grant_type=refresh_token'); Params.Add('refresh_token=' + TNetEncoding.URL.Encode(ARefreshToken)); Body := TStringStream.Create(Params.DelimitedText.Replace(#13#10,'&',[rfReplaceAll]), TEncoding.UTF8); try Headers := [ TNameValuePair.Create('Content-Type','application/x-www-form-urlencoded') ]; Encoded := TNetEncoding.Base64.Encode(FClientID + ':' + FClientSecret); Headers := Headers + [TNameValuePair.Create('Authorization', 'Basic ' + Encoded)]; Resp := FHTTP.Post(FTokenURL, Body, nil, Headers); sBody := Resp.ContentAsString(TEncoding.UTF8); if not (Resp.StatusCode in [200,201]) then raise EOAuth2Error.CreateFmt('Refresh token endpoint retornou %d: %s', [Resp.StatusCode, sBody]); ParseTokenResponse(sBody); Result := FToken; finally Body.Free; end; finally Params.Free; end; end; procedure TOAuth2Client.AcquireToken; var TokenLocal: TOAuth2Token; begin TMonitor.Enter(FLock); try FLastError := ''; try // tenta via client_credentials TokenLocal := RequestToken_ClientCredentials; FToken := TokenLocal; except on E: Exception do begin FLastError := E.Message; raise; end; end; finally TMonitor.Exit(FLock); end; end; procedure TOAuth2Client.EnsureTokenValid; var tokenCopy: TOAuth2Token; begin TMonitor.Enter(FLock); try // se token válido, nada a fazer if FToken.IsValid then Exit; // se temos refresh token, tente renovar if FToken.RefreshToken <> '' then begin try RequestToken_WithRefresh(FToken.RefreshToken); Exit; except // se falhar, limpa e tenta client_credentials FToken := Default(TOAuth2Token); end; end; // pede novo token via client_credentials RequestToken_ClientCredentials; finally TMonitor.Exit(FLock); end; end; function TOAuth2Client.GetAuthorizationHeader: string; begin EnsureTokenValid; if FToken.AccessToken = '' then raise EOAuth2Error.Create('Nenhum access_token disponível'); Result := FToken.TokenType + ' ' + FToken.AccessToken; end; end.

Como usar (exemplo simples)

 
 
var OAuth: TOAuth2Client; AuthHeader: string; Client: TNetHTTPClient; Resp: IHTTPResponse; begin Client := TNetHTTPClient.Create(nil); try OAuth := TOAuth2Client.Create( 'https://registradora.exemplo/oauth2/token', 'seu_client_id', 'seu_client_secret', 'scope-necessario', Client); try // pode chamar EnsureTokenValid antes de cada requisição AuthHeader := OAuth.GetAuthorizationHeader; // 'Bearer <token>' // Exemplo de chamada à API de consulta usando o token Resp := Client.Get('https://registradora.exemplo/api/duplicata/consultar', nil, [TNameValuePair.Create('Authorization', AuthHeader)]); // tratar Resp.ContentAsString... finally OAuth.Free; end; finally Client.Free; end; end;

Dicas e pontos importantes

  1. Fluxo mais comum: client_credentials (server-to-server). Alguns provedores podem exigir MTLS (client certificate) — nesse caso a autenticação muda e você precisa configurar certificado no HTTP client.

  2. Armazenamento seguro do client_secret: não guarde em texto claro. Use DPAPI (Windows CryptoAPI), arquivo criptografado, ou HSM/KeyVault.

  3. Timeouts e retry: implemente re-tries exponenciais para chamadas de token e trate códigos 5xx.

  4. Logs e compliance: armazene respostas cruas (somente em ambiente seguro) para auditoria — mas não registre client_secret.

  5. Rate limits: confira limites da registradora e implemente backoff.

  6. Testes: rode em homologação da registradora e simule expiração de tokens.

  7. MTLS: se a registradora exigir certificado do cliente, o TNetHTTPClient precisa ser configurado com o certificado PFX (TLS client cert). Eu posso te mostrar o snippet se precisar.


Quer que eu:

  • adapte este módulo para MTLS (client cert) em vez de Basic auth?

  • gere uma classe pronta que também faça a chamada da API /duplicata/consultar e parseie o retorno em registros Delphi?

Escolhe uma opção e eu já preparo.

  • Confuso 1
  • 3 semanas depois ...
  • Este tópico foi criado há 179 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.