robhercarlos 0 Posted November 21, 2022 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
Fr0sT.Brutal 900 Posted November 21, 2022 Universal solution: examine dumps of both requests and look for differences 2 Share this post Link to post
David Schwartz 426 Posted November 22, 2022 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 1 Share this post Link to post
Remy Lebeau 1394 Posted November 22, 2022 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
robhercarlos 0 Posted November 23, 2022 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
robhercarlos 0 Posted November 28, 2022 Post Update: Found solution answered on stackoverflow. https://stackoverflow.com/questions/74521060/converting-c-api-post-request-into-delphi-code/74602678#74602678 Share this post Link to post
vfbb 285 Posted November 28, 2022 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; 2 1 Share this post Link to post
David Schwartz 426 Posted November 30, 2022 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