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

ING Open Banking OAuth2 Client Credentials

See more OAuth2 Examples

Demonstrates how to get an access token for the ING Open Banking APIs using client credentials.

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.CkDateTime,
  Chilkat.Rsa,
  Chilkat.HttpResponse,
  Chilkat.JsonObject,
  Chilkat.Http,
  Chilkat.BinData,
  Chilkat.PrivateKey,
  Chilkat.StringBuilder,
  Chilkat.Cert,
  Chilkat.Crypt2,
  Chilkat.HttpRequest;

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

procedure RunDemo;
var
  success: Boolean;
  cert: TCert;
  bdPrivKey: TBinData;
  privKey: TPrivateKey;
  http: THttp;
  crypt: TCrypt2;
  payload: string;
  payloadDigest: string;
  dt: TCkDateTime;
  httpMethod: string;
  reqPath: string;
  sbStringToSign: TStringBuilder;
  signingPrivKey: TPrivateKey;
  rsa: TRsa;
  b64Signature: string;
  sbAuthHdrVal: TStringBuilder;
  sbDigestHdrVal: TStringBuilder;
  req: THttpRequest;
  resp: THttpResponse;
  json: TJsonObject;
  kty: string;
  n: string;
  e: string;
  use: string;
  alg: string;
  x5t: string;
  access_token: string;
  expires_in: Integer;
  scope: string;
  token_type: string;
  client_id: string;
  i: Integer;
  count_i: Integer;

begin
  success := False;

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

  cert := TCert.Create;
  success := cert.LoadFromFile('qa_data/certs_and_keys/ING/example_client_tls.cer');
  if (success = False) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;

  bdPrivKey := TBinData.Create;
  success := bdPrivKey.LoadFile('qa_data/certs_and_keys/ING/example_client_tls.key');
  if (success = False) then
    begin
      WriteLn('Failed to load example_client_tls.key');
      Exit;
    end;

  //  The OAuth 2.0 client_id for these certificates is e77d776b-90af-4684-bebc-521e5b2614dd. 
  //  Please note down this client_id since you will need it in the next steps to call the API.

  privKey := TPrivateKey.Create;
  success := privKey.LoadAnyFormat(bdPrivKey,'');
  if (success = False) then
    begin
      WriteLn(privKey.LastErrorText);
      Exit;
    end;

  //  Associate the private key with the certificate.
  success := cert.SetPrivateKey(privKey);
  if (success = False) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;

  http := THttp.Create;

  success := http.SetSslClientCert(cert);
  if (success = False) then
    begin
      WriteLn(http.LastErrorText);
      Exit;
    end;

  //  Calculate the Digest and add the "Digest" header.  Do the equivalent of this:
  //  payload="grant_type=client_credentials"
  //  payloadDigest=`echo -n "$payload" | openssl dgst -binary -sha256 | openssl base64`
  //  digest=SHA-256=$payloadDigest
  crypt := TCrypt2.Create;
  crypt.HashAlgorithm := 'SHA256';
  crypt.EncodingMode := 'base64';
  payload := 'grant_type=client_credentials';
  payloadDigest := crypt.HashStringENC(payload);

  //  Calculate the current date/time and add the Date header.  
  //  reqDate=$(LC_TIME=en_US.UTF-8 date -u "+%a, %d %b %Y %H:%M:%S GMT")  
  dt := TCkDateTime.Create;
  dt.SetFromCurrentSystemTime();
  //  The desire date/time format is the "RFC822" format.
  http.SetRequestHeader('Date',dt.GetAsRfc822(False));

  //  Calculate signature for signing your request
  //  Duplicate the following code:

  //  	httpMethod="post"
  //  	reqPath="/oauth2/token"
  //  	signingString="(request-target): $httpMethod $reqPath
  //  	date: $reqDate
  //  	digest: $digest"
  //  	signature=`printf "$signingString" | openssl dgst -sha256 -sign "${certPath}example_client_signing.key" -passin "pass:changeit" | openssl base64 -A`

  httpMethod := 'POST';
  reqPath := '/oauth2/token';

  sbStringToSign := TStringBuilder.Create;
  sbStringToSign.Append('(request-target): ');
  sbStringToSign.Append(httpMethod);
  sbStringToSign.ToLowercase();
  sbStringToSign.Append(' ');
  sbStringToSign.AppendLine(reqPath,False);

  sbStringToSign.Append('date: ');
  sbStringToSign.AppendLine(dt.GetAsRfc822(False),False);

  sbStringToSign.Append('digest: SHA-256=');
  sbStringToSign.Append(payloadDigest);

  signingPrivKey := TPrivateKey.Create;
  success := signingPrivKey.LoadPemFile('qa_data/certs_and_keys/ING/example_client_signing.key');
  if (success = False) then
    begin
      WriteLn(signingPrivKey.LastErrorText);
      Exit;
    end;

  rsa := TRsa.Create;
  success := rsa.UsePrivateKey(signingPrivKey);
  if (success = False) then
    begin
      WriteLn(rsa.LastErrorText);
      Exit;
    end;

  rsa.EncodingMode := 'base64';
  b64Signature := rsa.SignStringENC(sbStringToSign.GetAsString(),'SHA256');

  sbAuthHdrVal := TStringBuilder.Create;
  sbAuthHdrVal.Append('Signature keyId="e77d776b-90af-4684-bebc-521e5b2614dd",');
  sbAuthHdrVal.Append('algorithm="rsa-sha256",');
  sbAuthHdrVal.Append('headers="(request-target) date digest",');
  sbAuthHdrVal.Append('signature="');
  sbAuthHdrVal.Append(b64Signature);
  sbAuthHdrVal.Append('"');

  sbDigestHdrVal := TStringBuilder.Create;
  sbDigestHdrVal.Append('SHA-256=');
  sbDigestHdrVal.Append(payloadDigest);

  //  Do the following CURL statement:

  //  	curl -i -X POST "${httpHost}${reqPath}" \
  //  	-H 'Accept: application/json' \
  //  	-H 'Content-Type: application/x-www-form-urlencoded' \
  //  	-H "Digest: ${digest}" \
  //  	-H "Date: ${reqDate}" \
  //  	-H "authorization: Signature keyId=\"$keyId\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"$signature\"" \
  //  	-d "${payload}" \
  //  	--cert "${certPath}tlsCert.crt" \
  //  	--key "${certPath}tlsCert.key"

  req := THttpRequest.Create;
  req.AddParam('grant_type','client_credentials');
  req.AddHeader('Accept','application/json');
  req.AddHeader('Date',dt.GetAsRfc822(False));
  req.AddHeader('Digest',sbDigestHdrVal.GetAsString());
  req.AddHeader('Authorization',sbAuthHdrVal.GetAsString());

  req.HttpVerb := 'POST';
  req.ContentType := 'application/x-www-form-urlencoded';

  resp := THttpResponse.Create;
  success := http.HttpReq('https://api.sandbox.ing.com/oauth2/token',req,resp);
  if (success = False) then
    begin
      WriteLn(http.LastErrorText);
      Exit;
    end;

  //  If successful, the status code = 200
  WriteLn('Response Status Code: ' + resp.StatusCode);
  WriteLn(resp.BodyStr);

  json := TJsonObject.Create;
  json.Load(resp.BodyStr);

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

  //  A successful response contains an access token such as:
  //  {
  //    "access_token": "eyJhbGc ... bxI_SoPOBH9xmoM",
  //    "expires_in": 905,
  //    "scope": "payment-requests:view payment-requests:create payment-requests:close greetings:view virtual-ledger-accounts:fund-reservation:create virtual-ledger-accounts:fund-reservation:delete virtual-ledger-accounts:balance:view",
  //    "token_type": "Bearer",
  //    "keys": [
  //      {
  //        "kty": "RSA",
  //        "n": "3l3rdz4...04VPkdV",
  //        "e": "AQAB",
  //        "use": "sig",
  //        "alg": "RS256",
  //        "x5t": "3c396700fc8cd709cf9cb5452a22bcde76985851"
  //      }
  //    ],
  //    "client_id": "e77d776b-90af-4684-bebc-521e5b2614dd"
  //  }

  //  Use this online tool to generate parsing code from sample JSON: 
  //  Generate Parsing Code from JSON

  access_token := json.StringOf('access_token');
  expires_in := json.IntOf('expires_in');
  scope := json.StringOf('scope');
  token_type := json.StringOf('token_type');
  client_id := json.StringOf('client_id');
  i := 0;
  count_i := json.SizeOfArray('keys');
  while i < count_i do
    begin
      json.I := i;
      kty := json.StringOf('keys[i].kty');
      n := json.StringOf('keys[i].n');
      e := json.StringOf('keys[i].e');
      use := json.StringOf('keys[i].use');
      alg := json.StringOf('keys[i].alg');
      x5t := json.StringOf('keys[i].x5t');
      i := i + 1;
    end;

  //  This example will save the JSON containing the access key to a file so that
  //  a subsequent example can load it and then use the access key for a request, such as to create a payment request.
  json.WriteFile('qa_data/tokens/ing_access_token.json');


  cert.Free;
  bdPrivKey.Free;
  privKey.Free;
  http.Free;
  crypt.Free;
  dt.Free;
  sbStringToSign.Free;
  signingPrivKey.Free;
  rsa.Free;
  sbAuthHdrVal.Free;
  sbDigestHdrVal.Free;
  req.Free;
  resp.Free;
  json.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.