Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

ShippingEasy.com Calculate Signature for API Authentication

See more HTTP Misc Examples

Demonstrates how to calculate the shippingeasy.com API signature for authenticating requests.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Http,
  Chilkat.CkDateTime,
  Chilkat.HttpResponse,
  Chilkat.StringBuilder,
  Chilkat.JsonObject,
  Chilkat.Crypt2;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  sbStringToSign: TStringBuilder;
  httpVerb: string;
  uriPath: string;
  queryParamsStr: string;
  json: TJsonObject;
  dt: TCkDateTime;
  bLocalTime: Boolean;
  unixEpochTimestamp: string;
  your_api_key: string;
  numReplaced: Integer;
  your_api_secret: string;
  crypt: TCrypt2;
  api_signature: string;
  http: THttp;
  queryParams: TJsonObject;
  resp: THttpResponse;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  First, concatenate these into a plaintext string using the following order:
  //  
  //      Capitilized method of the request. E.g. "POST"
  //      The URI path
  //      The query parameters sorted alphabetically and concatenated together into a URL friendly format: param1=ABC&param2=XYZ
  //      The request body as a string if one exists
  //      All parts are then concatenated together with an ampersand. The result resembles something like this:
  //  
  //  "POST&/partners/api/accounts&api_key=f9a7c8ebdfd34beaf260d9b0296c7059&api_timestamp=1401803554&{ ... request body ... }"

  sbStringToSign := TStringBuilder.Create;

  httpVerb := 'POST';
  uriPath := '/partners/api/accounts';
  queryParamsStr := 'api_key=YOUR_API_KEY&api_timestamp=UNIX_EPOCH_TIMESTAMP';

  //  Build the following JSON that will be the body of the request:

  //  {
  //    "account": {
  //      "first_name": "Coralie",
  //      "last_name": "Waelchi",
  //      "company_name": "Hegmann, Cremin and Bradtke",
  //      "email": "se_greg_6d477b1e59e8ff24abadfb59d3a2de3e@shippingeasy.com",
  //      "phone_number": "1-381-014-3358",
  //      "address": "2476 Flo Inlet",
  //      "address2": "",
  //      "state": "SC",
  //      "city": "North Dennis",
  //      "postal_code": "29805",
  //      "country": "USA",
  //      "password": "abc123",
  //      "subscription_plan_code": "starter"
  //    }
  //  }

  json := TJsonObject.Create;
  json.UpdateString('account.first_name','Coralie');
  json.UpdateString('account.last_name','Waelchi');
  json.UpdateString('account.company_name','Hegmann, Cremin and Bradtke');
  json.UpdateString('account.email','se_greg_6d477b1e59e8ff24abadfb59d3a2de3e@shippingeasy.com');
  json.UpdateString('account.phone_number','1-381-014-3358');
  json.UpdateString('account.address','2476 Flo Inlet');
  json.UpdateString('account.address2','');
  json.UpdateString('account.state','SC');
  json.UpdateString('account.city','North Dennis');
  json.UpdateString('account.postal_code','29805');
  json.UpdateString('account.country','USA');
  json.UpdateString('account.password','abc123');
  json.UpdateString('account.subscription_plan_code','starter');

  json.EmitCompact := False;
  WriteLn(json.Emit());

  //  First, let's get the current date/time in the Unix Epoch Timestamp format (which is just an integer)
  dt := TCkDateTime.Create;
  dt.SetFromCurrentSystemTime();
  //  Get the UTC time.
  bLocalTime := False;
  unixEpochTimestamp := dt.GetAsUnixTimeStr(bLocalTime);

  //  Build the string to sign:
  sbStringToSign.Append(httpVerb);
  sbStringToSign.Append('&');
  sbStringToSign.Append(uriPath);
  sbStringToSign.Append('&');
  sbStringToSign.Append(queryParamsStr);
  sbStringToSign.Append('&');
  //  Make sure to send the JSON body of a request in compact form..
  json.EmitCompact := True;
  sbStringToSign.Append(json.Emit());

  //  Use your API key here:
  your_api_key := 'f9a7c8ebdfd34beaf260d9b0296c7059';

  numReplaced := sbStringToSign.Replace('YOUR_API_KEY',your_api_key);
  numReplaced := sbStringToSign.Replace('UNIX_EPOCH_TIMESTAMP',unixEpochTimestamp);

  //  Do the HMAC-SHA256 with your API secret:
  your_api_secret := 'ea210785fa4656af03c2e4ffcc2e7b5fc19f1fba577d137905cc97e74e1df53d';
  crypt := TCrypt2.Create;
  crypt.MacAlgorithm := 'hmac';
  crypt.EncodingMode := 'hexlower';
  crypt.SetMacKeyString(your_api_secret);
  crypt.HashAlgorithm := 'sha256';

  api_signature := crypt.MacStringENC(sbStringToSign.GetAsString());
  WriteLn('api_signature: ' + api_signature);

  //  --------------------------------------------------------------------
  //  Here's an example showing how to use the signature in a request:

  //  Build a new string-to-sign and create a new api_signature for the actual request we'll be sending...
  sbStringToSign.Clear();
  sbStringToSign.Append('GET');
  sbStringToSign.Append('&');
  sbStringToSign.Append('/app.shippingeasy.com/api/orders');
  sbStringToSign.Append('&');
  sbStringToSign.Append(queryParamsStr);
  sbStringToSign.Append('&');
  //  There is no body for a GET request.

  api_signature := crypt.MacStringENC(sbStringToSign.GetAsString());

  http := THttp.Create;
  queryParams := TJsonObject.Create;

  queryParams.UpdateString('api_signature',api_signature);
  queryParams.UpdateString('api_timestamp',unixEpochTimestamp);
  queryParams.UpdateString('api_key',your_api_key);

  resp := THttpResponse.Create;
  success := http.HttpParams('GET','https://app.shippingeasy.com/api/orders',queryParams,resp);
  if (success = False) then
    begin
      WriteLn(http.LastErrorText);
      Exit;
    end;

  WriteLn('response status code = ' + resp.StatusCode);
  WriteLn('response body:');
  WriteLn(resp.BodyStr);


  sbStringToSign.Free;
  json.Free;
  dt.Free;
  crypt.Free;
  http.Free;
  queryParams.Free;
  resp.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.