IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web & réseau Delphi Discussion :

Delphi appel API ne fonctionne pas sous Delphi mais ok sous postman et powershell


Sujet :

Web & réseau Delphi

  1. #1
    Membre du Club
    Homme Profil pro
    Responsable d'un système d'information métier
    Inscrit en
    Novembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Responsable d'un système d'information métier
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2014
    Messages : 9
    Par défaut Delphi appel API ne fonctionne pas sous Delphi mais ok sous postman et powershell
    bonjour je dois faire un appel post vers une serveur pour mettre à jour des datas
    je fait un 1er appel afin de recupérer un Bearer , cela fonctionne dans Delphi

    puis un second appel pour faire la MAJ des données et là alors que ça fonctionne sans souci dans postman , dans powershell impossible de le faire fonctionner dans débogueur REST 12.0 ni dans Delphi


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzA5MjIwOCIsImV4cCI6MTc3MzgyNTcyOH0.U44uVs-aopxqLf-cmvREwjSvwxo57NrK6QAn21WeerU")
    $headers.Add("Content-Type", "application/json")
     
    $body = @"
    {
      `"documentNumber`": `"V445013-0000001`",
      `"orderType`": `"VAD`",
      `"paymentDetails`": [
        {
          `"lineNumber`": `"1`",
          `"amount`": `"1`",
          `"paymentMethod`": `"ZZ26`"
        },
         {
          `"lineNumber`": `"2`",
          `"amount`": `"1`",
          `"paymentMethod`": `"ZZ26`"
        }
      ]
    }
    "@
     
    $response = Invoke-RestMethod 'https://api.ptsrc.adeiz.com/services/orderservice/api/v1/sales-orders-lite' -Method 'POST' -Headers $headers -Body $body
    $response | ConvertTo-Json]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    procedure SendSalesOrder;
    var
      RESTClient: TRESTClient;
      RESTRequest: TRESTRequest;
      RESTResponse: TRESTResponse;
       paymentDetailsArray:tjsonarray;
      jsonBody, payment1, payment2: TJSONObject;
      jsonObject, paymentDetailsObject: TJSONObject;
    begin
      // Créer le client REST
      RESTClient := TRESTClient.Create(nil);
      try
        RESTClient.BaseURL := 'https://api.ptsrc.adeiz.com/services/orderservice/api/v1/sales-orders-lite';
     
        // Créer la requête
        RESTRequest := TRESTRequest.Create(nil);
        try
          RESTRequest.Client := RESTClient;
          RESTRequest.Method := rmPOST;
     
          // Ajouter les en-têtes
    //      restrequest.AddParameter('Authorization');
          restrequest.AddParameter('"Authorization"','"Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzEzMjIzMCIsImV4cCI6MTc3Mzg0MDE1MH0.tIflejQyPcCKp52zPRhYCuiSB0XMkHLIAHyoF*****"',pkHTTPHEADER);
    //      RESTRequest.AddHeader('Authorization', 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzA5MjIwOCIsImV4cCI6MTc3MzgyNTcyOH0.U44uVs-aopxqLf-cmvREwjSvwxo57NrK6QAn21*****');
          RESTRequest.Addparameter('Content-Type', 'application/json');
     
          // Construire le corps JSON
          jsonBody := TJSONobject.Create;
     
          // Créer la partie principale
          jsonObject := TJSONObject.Create;
          try
            jsonObject.AddPair('documentNumber', 'V445013-0000001');
            jsonObject.AddPair('orderType', 'VAD');
     
            // PaymentDetails array
            paymentDetailsArray := TJSONarray.Create;
     
            // Payment 1
            payment1 := TJSONObject.Create;
            payment1.AddPair('lineNumber', '1');
            payment1.AddPair('amount', '1');
            payment1.AddPair('paymentMethod', 'ZZ26');
     
            // Payment 2
            payment2 := TJSONObject.Create;
            payment2.AddPair('lineNumber', '2');
            payment2.AddPair('amount', '1');
            payment2.AddPair('paymentMethod', 'ZZ26');
     
            paymentDetailsArray.Add(payment1);
            paymentDetailsArray.Add(payment2);
     
            jsonObject.AddPair('paymentDetails', paymentDetailsArray);
     
            // Convertir en string
            jsonBody:=jsonObject;
          finally
            // Libérer les objets temporaires
            // Note: jsonObject, paymentDetailsArray, payment1, payment2 sont ajoutés à jsonBody
            // et seront libérés avec jsonBody si on ne les libère pas ici
          end;
     
          // Définir le corps de la requête
          restrequest.AddBody(jsonBody.ToString);
    //      RESTRequest.Body := TEncoding.UTF8.GetBytes(jsonBody.ToString);
    //      RESTRequest.ContentType:=application/json;
     
          // Exécuter la requête
          RESTResponse := TRESTResponse.Create(nil);
          try
            RESTRequest.Response := RESTResponse;
            RESTRequest.Execute;
     
            // Traiter la réponse
    //        showmessage ('Réponse: ', RESTResponse.Content);
            form5.memo1.lines.add(RESTResponse.Content);
            finally
            RESTResponse.Free;
          end;
     
        finally
          RESTRequest.Free;
        end;
     
      finally
        RESTClient.Free;
      end;
    end;
    Le bearer est différent car récupérer à chaque fois


    et là l'export de REST DEBOGUEUR

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    object RESTClient1: TRESTClient
      BaseURL = 
        'https://api.ptsrc.adeiz.com/services/orderservice/api/v1/sales-o' +
        'rders-lite'
      Params = <>
      SynchronizedEvents = False
    end
    object RESTRequest1: TRESTRequest
      AssignedValues = [rvConnectTimeout, rvReadTimeout]
      Client = RESTClient1
      Method = rmPOST
      Params = <
        item
          Kind = pkHTTPHEADER
          Name = 'Authorization'
          Options = [poDoNotEncode]
          Value = 
            'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlz' +
            'dHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2' +
            'MDMxNjE0MjMxOSIsImV4cCI6MTc3Mzc1NzM5OX0.esg-OQXCTo_Nwke8G_6HkuGM' +
            'dGa3g3Z7b0uK5mrH_xY'
        end
        item
          Kind = pkREQUESTBODY
          Name = 'bodyB6827D9362784EE6BA295D02118AD896'
          Value = 
            'bodyB6827D9362784EE6BA295D02118AD896{'#13#10'  "documentNumber": "V445013-0000001",'#13#10'  "orderType": "VAD",' +
            #13#10'  "paymentDetails": ['#13#10'    {'#13#10'      "lineNumber": "1",'#13#10'      ' +
            '"amount": "1",'#13#10'      "paymentMethod": "ZZ26"'#13#10'    },'#13#10'     {'#13#10' ' +
            '     "lineNumber": "2",'#13#10'      "amount": "1",'#13#10'      "paymentMet' +
            'hod": "ZZ26"'#13#10'    }'#13#10'  ]'#13#10'}'
          ContentTypeStr = 'application/json'
        end>
      Response = RESTResponse1
      SynchronizedEvents = False
    end
    object RESTResponse1: TRESTResponse
    end
    je ne comprend pas pourquoi j'ai toujours cette erreur en Ddelphi ou REST debogueur
    {"status ":"UNAUTHORIZED","statusCode":"401 Unauthorized","ExceptionType":"org.springframework.security.authentication.InsufficientAuthenticationException","message":"Full authentication is required to access this resource","path":"/api/v1/sales-orders-lite","resourceVarName":""}

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 231
    Par défaut
    Vous pouviez poursuivre dans l'autre sujet surtout que j'avais anticipé le problème de l'utilisation du jeton dans le code fourni de TxxxServiceClientHTTPByRESTClientIPPeer.Post en utilisant un TCustomAuthenticator

    C'est un peu le bazar ces Addparameter, pourquoi des " un peu partout ?

    Pourquoi ne pas utiliser un TOAuth2Authenticator affecté dans la propriété Authenticator du TRESTClient ?
    Cela gère nettement mieux ainsi les headers et les RFC à l'instar du THTTPBasicAuthenticator


    Pensez à préciser la version de Delphi et la version du REST Debuger, certaines n'étaient franchement pas folichone pour le REST avec OAuth.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    RESTRequest.Client.Authenticator := TOAuth2Authenticator.Create(RESTRequest.Client);
    TOAuth2Authenticator(RESTRequest.Client.Authenticator).AccessToken := 'eyJhbGci...';
    TOAuth2Authenticator(RESTRequest.Client.Authenticator).TokenType := TOAuth2TokenType.ttBEARER;
    Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    727
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2017
    Messages : 727
    Billets dans le blog
    1
    Par défaut
    Compare la requête HTTP envoyée par Delphi avec celle de Postman (Fiddler, Wireshark ou HTTP proxy) pour voir si il y a une différence.
    On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:

  4. #4
    Membre du Club
    Homme Profil pro
    Responsable d'un système d'information métier
    Inscrit en
    Novembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Responsable d'un système d'information métier
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2014
    Messages : 9
    Par défaut
    Bonjour XeGregory c'est bien là mon problème la requête fonctionne sous Postman, sous PowerShell mais quand on la met en Delphi c'est ko même en demande à Chatgtp la requête ou en demandant de traduire la requête PowerShell en Delphi
    n'étant pas du tout à l'aise avec les PAI et vu le peu de DOC DELPHI sur le sujet, c'est compliqué.

    Bonjour ShaiLeTroll je vais regardé le lien que tu fournis je suis étonné de devoir utiliser TOAuth2Authenticator puisque dans tous les exemple d'autre langage ils n'utilisent pas TOAuth2Authenticator. Je vais don regarder de ce côté.
    mais si sou savez ou trouver de la doc sur le sujet je suis preneur .

    Merci à vous je reviens clôturer j'espère le sujet rapidement

  5. #5
    Membre chevronné Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    1 340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 340
    Par défaut
    pour convertir ceci en Delphi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $headers.Add("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzA5MjIwOCIsImV4cCI6MTc3MzgyNTcyOH0.U44uVs-aopxqLf-cmvREwjSvwxo57NrK6QAn21WeerU")
    $headers.Add("Content-Type", "application/json")
    Cela devrais être codé comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    RESTRequest.AddHeader('Authorization', 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzA5MjIwOCIsImV4cCI6MTc3MzgyNTcyOH0.U44uVs-aopxqLf-cmvREwjSvwxo57NrK6QAn21*****');
    RESTRequest.AddHeader('Content-Type', 'application/json');

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 231
    Par défaut
    Citation Envoyé par nakos91 Voir le message
    je suis étonné de devoir utiliser TOAuth2Authenticator puisque dans tous les exemple d'autre langage ils n'utilisent pas TOAuth2Authenticator.
    Ce n'est pas de devoir mais de pouvoir !
    C'est justement pour simplifier l'usage sans faire soi-même l'ajout des headers, c'est une assistance.
    C'est logique que les autres langages n'utilisent pas TOAuth2Authenticator puisque c'est une classe strictement Delphi qui a justement le but de simplifier cet aspect, tout comme pour le Content-Type est automatiquement défini avec AddBody + ctAPPLICATION_JSON, tout cela a déjà été encapsulé pour éviter ce genre de bricolage approximatif. +

    En ASP.net c'est UseOAuthBearerTokens(OAuthAuthorizationServerOptions) l'équivalent du TOAuth2Authenticator
    Chaque langage a ses propres wrappers.

    Vu le nombre de service que l'on invoque de nos jours, heureusement qu'un code générique bien pensé permet de ne plus se poser ce genre de question, je ne crée plus de TRESTClient\TRESTRequest directement depuis des années au profit d'un Wrapper qui peut au besoin débrayer sur un TIdHTTP pour des cas subtil de Proxy, de Certificat, et l'encapsulation rend cela transparent.


    Sinon
    - RESTResponse n'a pas besoin d'être instancié mais cela permet un peu plus de liberté sur le cycle de vie de la réponse
    - TJSONobject.Create est appelé deux fois et votre construction provoquera une fuite mémoire
    - RESTRequest peut-être libéré automatiquement si on lui fourni un TRESTClient en paramètre du constructeur


    Enfin

    Avez-vous une gestion de scope sur votre serveur 'https://api.ptsrc.adeiz.com' ?
    Est-ce que votre token contient l'audience appropriée pour accéder à la ressource 'services/orderservice/api/v1/sales-orders-lite' ?

    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {
      "sub": "13",
      "auth": "Administrateur",
      "orgCode": "445",
      "authentDateTime": "20260316142319",
      "exp": 1773757399
    }

    Par exemple l'expiration est au "Tue Mar 17 2026 15:23:19 GMT+0100 (heure normale d’Europe centrale)"


    Prompt sur Copilot

    On travaille sur une conversion d'un code PowerShell vers Delphi
    puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMyIsImF1dGgiOiJBZG1pbmlzdHJhdGV1ciIsIm9yZ0NvZGUiOiI0NDUiLCJhdXRoZW50RGF0ZVRpbWUiOiIyMDI2MDMxNzA5MjIwOCIsImV4cCI6MTc3MzgyNTcyOH0.U44uVs-aopxqLf-cmvREwjSvwxo57NrK6QAn21WeerU")
    $headers.Add("Content-Type", "application/json")
     
    $body = @"
    {
      `"documentNumber`": `"V445013-0000001`",
      `"orderType`": `"VAD`",
      `"paymentDetails`": [
        {
          `"lineNumber`": `"1`",
          `"amount`": `"1`",
          `"paymentMethod`": `"ZZ26`"
        },
         {
          `"lineNumber`": `"2`",
          `"amount`": `"1`",
          `"paymentMethod`": `"ZZ26`"
        }
      ]
    }
    "@
     
    $response = Invoke-RestMethod 'https://api.ptsrc.adeiz.com/services/orderservice/api/v1/sales-orders-lite' -Method 'POST' -Headers $headers -Body $body
    $response | ConvertTo-Json]

    Voici sa réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    program PostSalesOrderLite;
     
    {$APPTYPE CONSOLE}
     
    uses
      System.SysUtils,
      System.JSON,
      System.Classes,
      System.Net.URLClient,
      System.Net.HttpClient;
     
    function PrettyJson(const AText: string): string;
    var
      V: TJSONValue;
    begin
      V := TJSONObject.ParseJSONValue(AText);
      try
        if Assigned(V) then
          Result := V.ToString()
        else
          Result := AText;
      finally
        V.Free;
      end;
    end;
     
    var
      Http: THTTPClient;
      Headers: TNetHeaders;
      BodyObj: TJSONObject;
      PaymentDetails: TJSONArray;
      Item: TJSONObject;
      BodyStream: TStringStream;
      Resp: IHTTPResponse;
      RespText: string;
      Token: string;
    begin
      try
        Token := 'METS_TON_TOKEN_ICI'; // Evite de hardcoder en prod (env var, vault, config chiffrée)
     
        BodyObj := TJSONObject.Create;
        try
          BodyObj.AddPair('documentNumber', 'V445013-0000001');
          BodyObj.AddPair('orderType', 'VAD');
     
          PaymentDetails := TJSONArray.Create;
     
          Item := TJSONObject.Create;
          Item.AddPair('lineNumber', '1');
          Item.AddPair('amount', '1');
          Item.AddPair('paymentMethod', 'ZZ26');
          PaymentDetails.AddElement(Item);
     
          Item := TJSONObject.Create;
          Item.AddPair('lineNumber', '2');
          Item.AddPair('amount', '1');
          Item.AddPair('paymentMethod', 'ZZ26');
          PaymentDetails.AddElement(Item);
     
          BodyObj.AddPair('paymentDetails', PaymentDetails);
     
          BodyStream := TStringStream.Create(BodyObj.ToJSON, TEncoding.UTF8);
          try
            Http := THTTPClient.Create;
            try
              SetLength(Headers, 2);
              Headers[0].Name := 'Authorization';
              Headers[0].Value := 'Bearer ' + Token;
              Headers[1].Name := 'Content-Type';
              Headers[1].Value := 'application/json';
     
              Resp := Http.Post(
                'https://api.ptsrc.adeiz.com/services/orderservice/api/v1/sales-orders-lite',
                BodyStream,
                nil,
                Headers
              );
     
              RespText := Resp.ContentAsString(TEncoding.UTF8);
     
              Writeln('HTTP Status: ', Resp.StatusCode);
              Writeln(PrettyJson(RespText));
            finally
              Http.Free;
            end;
          finally
            BodyStream.Free;
          end;
        finally
          BodyObj.Free;
        end;
     
      except
        on E: Exception do
        begin
          Writeln('Erreur: ', E.Message);
          Halt(1);
        end;
      end;
    end.
    Troisième Prompt :
    Récrit avec un TRESTClient et TRESTRequest
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    program PostSalesOrderLite_RESTClient;
     
    {$APPTYPE CONSOLE}
     
    uses
      System.SysUtils,
      System.JSON,
      REST.Client,
      REST.Types,
      IPPeerCommon,
      IPPeerClient;
     
    function PrettyJson(const AText: string): string;
    var
      V: TJSONValue;
    begin
      V := TJSONObject.ParseJSONValue(AText);
      try
        if Assigned(V) then
          Result := V.ToString()
        else
          Result := AText;
      finally
        V.Free;
      end;
    end;
     
    var
      Client: TRESTClient;
      Request: TRESTRequest;
      Response: TRESTResponse;
      BodyObj: TJSONObject;
      PaymentDetails: TJSONArray;
      Item: TJSONObject;
      Token: string;
    begin
      try
        Token := 'METS_TON_TOKEN_ICI'; // En prod: variable d'environnement / coffre de secrets
     
        BodyObj := TJSONObject.Create;
        try
          BodyObj.AddPair('documentNumber', 'V445013-0000001');
          BodyObj.AddPair('orderType', 'VAD');
     
          PaymentDetails := TJSONArray.Create;
     
          Item := TJSONObject.Create;
          Item.AddPair('lineNumber', '1');
          Item.AddPair('amount', '1');
          Item.AddPair('paymentMethod', 'ZZ26');
          PaymentDetails.AddElement(Item);
     
          Item := TJSONObject.Create;
          Item.AddPair('lineNumber', '2');
          Item.AddPair('amount', '1');
          Item.AddPair('paymentMethod', 'ZZ26');
          PaymentDetails.AddElement(Item);
     
          BodyObj.AddPair('paymentDetails', PaymentDetails);
     
          Client := TRESTClient.Create('https://api.ptsrc.adeiz.com');
          Request := TRESTRequest.Create(nil);
          Response := TRESTResponse.Create(nil);
          try
            Request.Client := Client;
            Request.Response := Response;
            Request.Method := rmPOST;
            Request.Resource := 'services/orderservice/api/v1/sales-orders-lite';
     
            // Headers
            Request.Params.Clear;
            Request.AddParameter('Authorization', 'Bearer ' + Token, pkHTTPHEADER, [poDoNotEncode]);
            Request.AddParameter('Content-Type', 'application/json', pkHTTPHEADER, [poDoNotEncode]);
     
            // Body JSON
            Request.AddBody(BodyObj.ToJSON, ctAPPLICATION_JSON);
     
            // Exécution
            Request.Execute;
     
            Writeln('HTTP Status: ', Response.StatusCode);
            Writeln(PrettyJson(Response.Content));
          finally
            Response.Free;
            Request.Free;
            Client.Free;
          end;
        finally
          BodyObj.Free;
        end;
     
      except
        on E: Exception do
        begin
          Writeln('Erreur: ', E.Message);
          Halt(1);
        end;
      end;
    end.
    On constate que le code fourni par l'IA est proche du votre, je me pencherais activement sur la gestion des droits \ scope côté serveur.

    Note le [poDoNotEncode] qui est à mon avis très important pour fournir ce type de header !
    Par habitude, j'utilise d'ailleurs plus AddAuthParameter que AddParameter et évidemment + pkHTTPHEADER
    C'est ce que fait TOAuth2Authenticator :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    case FTokenType of
        TOAuth2TokenType.ttBEARER:
          begin
            ARequest.AddAuthParameter(HTTP_HEADERFIELD_AUTH, 'Bearer ' + FAccessToken,
              TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]);
          end;
      else
    Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre du Club
    Homme Profil pro
    Responsable d'un système d'information métier
    Inscrit en
    Novembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Responsable d'un système d'information métier
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2014
    Messages : 9
    Par défaut résolu
    Merci beaucoup à tous et à ShaiLeTroll surtout

    en effet l'utilisation du TOAuth2Authenticator a corrigé le problème d'erreur 401 et l'autre modif sur la génération du BODY en JSON a corrigé le reste et l'appel fonctionne maintenant
    un grand merci, de m'avoir fait progressé ainsi, et bonne journée à tous

  8. #8
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 231
    Par défaut
    Peut-être fournir le code final fonctionnel ici, ça servira pour d'autres membres du forum ultérieurement.

    et un petit ?
    Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Delphi appel API ne fonctionne pas
    Par nakos91 dans le forum Delphi
    Réponses: 3
    Dernier message: 17/03/2026, 13h05
  2. Delphi, Compilé sous Oracle 10g ne fonctionne pas sous 9i
    Par l0pez dans le forum Bases de données
    Réponses: 1
    Dernier message: 15/12/2011, 10h11
  3. Réponses: 18
    Dernier message: 19/08/2004, 15h11
  4. Java ne fonctionne pas sous Firefox
    Par Info-Rital dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 29/07/2004, 23h37
  5. Réponses: 6
    Dernier message: 27/01/2004, 11h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo