robhercarlos
Members-
Content Count
5 -
Joined
-
Last visited
Community Reputation
0 NeutralTechnical Information
-
Delphi-Version
Delphi 10.2 Tokyo
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Converting C++ API Post Request into Delphi Code
robhercarlos replied to robhercarlos's topic in General Help
Post Update: Found solution answered on stackoverflow. https://stackoverflow.com/questions/74521060/converting-c-api-post-request-into-delphi-code/74602678#74602678 -
Converting C++ API Post Request into Delphi Code
robhercarlos replied to robhercarlos's topic in General Help
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. -
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!
-
Hey, thanks Remy! Turns out it was one of my SLL .dll files that did not get updated when I made the changes. I also went ahead and changed my SLLVersions property to the appropriate versions that I needed, and every thing is working how it should. Also, thanks for explaining and helping me understand better what the sslvSSLv23 flag is for.
-
Hello, I have a problem with a Win32 application using Indy. I am using Delphi 10.4 and am trying to make an XML Post request, but on making the call I get this error message: "ERROR: Error connecting with SSL. error: 140740BF:SSL routines:SSL23_CLIENT_HELLO:no protocols available" I am new to API's and I'm not sure in which direction to go next when trying to figure this out. Any suggestions or tips would be greatly appreciated. Below is the code I am using. procedure TformEditCUMaster.btnE2EstimateClick(Sender: TObject); var (* Document in XML to send *) ProntoResidentialXML, ResidentialXML: String; RESIDENTIAL_BASEURL, PRONTO_RESIDENTIAL_BASEURL: String; Username, Password: String; (* SSL Configuration *) ssl: TIdSSLIOHandlerSocketOpenSSL; EncodedXMLToSend: String; (* Used for API *) IdHttp: TidHttp; ReturnStr: String; (* Variables used in second attmp *) ResponseStream: TMemoryStream; InputStringList: TStringList; begin CodeSite.EnterMethod('TformEditCUMaster.btnE2EstimateClick'); //Inherited; (* Here add the login credentials *) (* Will be adding users own E2 value username and password *) Username := 'username'; Password := 'password'; (* Here are the BaseURLS *) RESIDENTIAL_BASEURL := 'https://evs.e2value.com/evs/xml/ballparkresidential.asp'; PRONTO_RESIDENTIAL_BASEURL := 'https://evs.e2value.com/evs/xml/1_0/pronto/default.aspx'; (* Send out request to e2 value that will retrieve an estimate on data provided. *) IdHttp := TidHttp.Create(); try (* Focus on Coverage unit for the current policy *) CovUnit.Locate('POLICY;SEQUENCE', VarArrayOf([Policy.FieldByName('POLICY').AsString, Policy.FieldByName('SEQUENCE').AsString]), [loPartialKey]); ResidentialXML := '<?xml version="1.0"?>' + '<estimate username="username" password="password">' + ' <version>1.0</version>' + ' <property>' + ' <address1>'+ Policy.FieldByName('ADDR1').AsString +'</address1>' + ' <address2>'+ Policy.FieldByName('ADDR2').AsString +'</address2>' + ' <city>' + Policy.FieldByName('CITY').AsString + '</city>' + ' <state>Virginia</state>' + ' <zipcode>'+ Policy.FieldByName('ZIP').AsString +'</zipcode>' + ' <locale></locale>' + ' <coverage_a>'+ CovUnit.FieldByName('COVA').AsString +'</coverage_a>' + ' <architectural_style></architectural_style>' + ' <construction_quality></construction_quality>' + ' <physical_shape></physical_shape>' + ' <construction_type></construction_type>' + ' <recent_renovations></recent_renovations>' + ' <historic_registry></historic_registry>' + ' <primary_exterior></primary_exterior>' + ' <primary_roof_covering>architectural shingle</primary_roof_covering>' + ' <living_area>' + ' <year_built>1990</year_built>' + ' <square_footage>1,000</square_footage>' + ' </living_area>' + ' <other_areas>' + ' <area>' + ' <area_name>breeze way</area_name>' + ' <year_built>1990</year_built>' + ' <square_footage>100</square_footage>' + ' </area>' + ' </other_areas>' + ' <unique_items>' + ' <item>' + ' <item_name>gargoyle</item_name>' + ' <cost>$500.00</cost>' + ' </item>' + ' </unique_items>' + ' <replacement_cost_type>full</replacement_cost_type>' + ' <return_acv value="yes">' + ' <structure_in_use>yes</structure_in_use>' + ' <condition>' + ' <general>good</general>' + ' <roof>good</roof>' + ' <wall>good</wall>' + ' <foundation>good</foundation>' + ' </condition>' + ' </return_acv>' + ' </property>' + '</estimate>'; //EncodedXMLToSend := TNetEncoding.URL.Encode(XMLDocument); ResponseStream := TMemoryStream.Create; InputStringList := TStringList.Create; InputStringList.Values['xml'] := ResidentialXML; (* attempt call to api *) Try (* Configure SSL options as needed... *) SSL := TIdSSLIOHandlerSocketOpenSSL.Create; SSL.SSLOptions.SSLVersions := [sslvTLSv1_1, sslvTLSv1_2, sslvSSLv23]; IdHTTP.IOHandler := SSL; (* Configure the http *) IdHttp.Request.ContentType := 'application/x-www-form-urlencoded'; IdHttp.Post(RESIDENTIAL_BASEURL, InputStringList, ResponseStream); Memo1.Lines.Add(Format('Response Code: %d', [IdHTTP.ResponseCode])); Memo1.Lines.Add(Format('Response Text: %s', [IdHTTP.ResponseText])); ResponseStream.Position := 0; InputStringList.LoadFromStream(ResponseStream); Memo1.Lines.Add('---- Pronto Full Residential -----'); Memo1.Lines.AddStrings(InputStringList); Memo1.Lines.Add('-----------------------'); Finally ResponseStream.Free; InputStringList.Free; End; finally SSL.Free; end; CodeSite.ExitMethod('TformEditCUMaster.btnE2EstimateClick'); end; I have updated and placed all my SLL .dll files in the same folder as my .exe file, but I'm still getting the same error message. Could someone point me in the right direction? Thanks! - Roberto