Jump to content
robhercarlos

Converting C++ API Post Request into Delphi Code

Recommended Posts

I am trying to make an api post request using Delphi. I have the working example in c++ but cannot figure what I am doing wrong when I convert it to Delphi code. I posted my original question on Stackoverflow here:

https://stackoverflow.com/questions/74521060/converting-c-api-post-request-into-delphi-code

 

C++ Code:

CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_URL, "https://sandbox.checkbook.io/v3/check/digital");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
headers = curl_slist_append(headers, "Authorization: xxxxxxxxxxxx:xxxxxxxxxxxxx");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "{\"recipient\":\"testing@checkbook.io\",\"name\":\"Widgets Inc.\",\"amount\":5,\"description\":\"Test Payment\"}");

CURLcode ret = curl_easy_perform(hnd);

My Delphi Code:

unit API_InvoiceCloud;

interface

uses
  DB, SysUtils,  System.Classes, System.JSON, IdSSLOpenSSL, VCL.Dialogs,
  IdHTTP, XML.XMLIntf, xml.xmlDom, xml.XMLDoc, IDCoder, IDCoderMIME,
  IdBaseComponent, IdException, IdZLibCompressorBase, IdCompressorZLib,
  Rest.Client;

procedure CreateDigitalPayment_CheckBookAPI(mRecipientEmailAddress,
                                      mRecipientName : String;
                                      mPaymentAmount : Double;
                                      mPaymentNumber,
                                      mPaymentDescription : String);


implementation

var
  //{ INDY COMPONENT TO CONNECT TO API SERVER; MAKES CONNECTION }
  IDHTTP1 : TidHttp;
  //{ SSL Connection }
  SSL : TIdSSLIOHandlerSocketOpenSSL;
  //{ Request and Response vars }
  JsonRequest, InJson : String;
  JsonToSend : TStringStream;    //object to store json text and pass API
  JObj : TJSONObject;
Const
  //{ Constant variables holding the APIKEY+APISECRET and BASEURL }
  nBASEURL = 'https://sandbox.checkbook.io/v3/check/digital';
  nAPIKEY = 'xxxxxxxxx:xxxxxxxx';

procedure CreateDigitalPayment_CheckBookAPI(mRecipientEmailAddress,
										    mRecipientName : String;
										    mPaymentAmount : Double;
										    mPaymentNumber,
										    mPaymentDescription : String);
var
  //{ Response into String }
  ResponseCode : String;  
  { -----------Testing---------- }
  //lParamList: TStringList;
  nBASEURL : String;
  RequestBody : TStream;
  ResponseBody : String;
begin
  CodeSite.EnterMethod('DigitalPayment_CheckBookAPI');

  nBASEURL := 'https://sandbox.checkbook.io/v3/check/digital';

  //{ JSON body with request string }
  JsonRequest := '{"recipient":"' + mRecipientEmailAddress
                + '","name":"' + mRecipientName
                + '","amount":' + FloatToStr(mPaymentAmount)
                + ',"number":"' + mPaymentNumber
                + '","description":"' + mPaymentDescription + '"}';
  
  try

    try
      //{ Create connection instance }
      IDHTTP1 := TidHttp.Create;

      //{ SSL Configuration }
      SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
      SSL.SSLOptions.SSLVersions := [sslvTLSv1_1, sslvTLSv1_2];
      IDHTTP1.IOHandler := SSL;

	  //{ Headers/Params }
      IDHTTP1.Request.Clear;
      IDHTTP1.Request.CustomHeaders.FoldLines := False;
      IDHTTP1.Request.Accept := 'application/json';
      IDHTTP1.Request.ContentType := 'application/json';
      IDHTTP1.Request.CustomHeaders.Values['Authorization'] := nAPIKEY;
      
      //{ Saving JSON text to TStringStream Object }
      JsonToSend := TStringStream.Create(JsonRequest, TEncoding.UTF8);
      //JsonToSend := TStringStream.Create(JsonRequest, TEncoding.ASCII);

      //{ Making POST Request using INDYs TidHTTP component; Params are: URL, JsonStringObj - saving into variable }
      SinglePartyResponse := IDHTTP1.Post(nBASEURL, JsonToSend);
      
      ShowMessage(IDHTTP1.ResponseCode.ToString);

    except
      on E : Exception do
        //{ Display error message if cannot do API CALL }
        begin
          ShowMessage(E.ClassName+' error raised, with message : "' + E.Message + '".');
          Abort;
        end
    end;

  finally
    //{ Free objects from memory }
    IDHTTP1.Free;
    SSL.Free;
    JsonToSend.Free;
  end;
  
end;

end.

Any help is appreciated, thanks!

Share this post


Link to post

This looks like the same question that Randell Carpenter posted in the Cross Platform section.

 

Have you searched Google for curl examples in Delphi?

Here's one:

 

 

This might be useful:

 

https://github.com/Mercury13/curl4delphi

 

 

Here's another example:

http://thundaxsoftware.blogspot.com/2015/12/sending-rest-api-messages-with-delphi.html

 

 

 

  • Thanks 1

Share this post


Link to post
On 11/21/2022 at 7:39 AM, robhercarlos said:

I am trying to make an api post request using Delphi. I have the working example in c++ but cannot figure what I am doing wrong when I convert it to Delphi code. I posted my original question on Stackoverflow here:

https://stackoverflow.com/questions/74521060/converting-c-api-post-request-into-delphi-code

You already received comments on there, which you have not fully responded to.  So why are you posting it here, too?

Share this post


Link to post

No. I posted this at the same time as my original question thinking I could reach a broader audience, but I guess that's a no-no on these forums. 

Share this post


Link to post

You can try using Refit, which is a library to consume apis rest in a simple way, without manipulating strings, json, or http components.

 

First you would create a unit for your api:

 

unit CheckBook;

interface

uses
  iPub.Rtl.Refit; // Just download and add it to your project: https://github.com/viniciusfbb/ipub-refit

type
  TNewPayment = record
    Recipient: string;
    Name: string;
    Amount: Double;
    Number: string;
    Description: string;
  end;

  [BaseUrl('https://sandbox.checkbook.io/v3')]
  ICheckBookApi = interface(IipRestApi)
    ['{97789B20-5C26-4359-AC41-D2042C4FAEC7}']

    [Post('/check/digital')]
    [Headers('Authorization', '{AuthToken}')]
    function CreateDigitalPayment(const ABody: TNewPayment): string;

    function GetAuthToken: string;
    procedure SetAuthToken(const AValue: string);
    property AuthToken: string read GetAuthToken write SetAuthToken;
  end;

var
  FCheckBookApi: ICheckBookApi;

implementation

initialization
  FCheckBookApi := GRestService.&For<ICheckBookApi>;
end.

 

Then you would consume it in your forms as follows:

 

uses
  CheckBook;

procedure TForm1.Button1Click(Sender: TObject);
var
  LNewPayment: TNewPayment;
begin
  LNewPayment.Recipient := 'testing@checkbook.io';
  LNewPayment.Name := 'Widgets Inc.';
  LNewPayment.Amount := 5;
  LNewPayment.Number := '';
  LNewPayment.Description := 'Test Payment';

  FCheckBookApi.AuthToken := 'xxxxxxxxx:xxxxxxxx';
  ShowMessage(FCheckBookApi.CreateDigitalPayment(LNewPayment));
end;

 

  • Like 2
  • Thanks 1

Share this post


Link to post
On 11/28/2022 at 2:04 PM, vfbb said:

You can try using Refit, which is a library to consume apis rest in a simple way, without manipulating strings, json, or http components.

Thanks for pointing this out. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×