Sample code for 30+ languages & platforms
Dart Requires Chilkat v11.0.0+

Rabobank GET /v3/accounts

See more Rabobank Examples

Demonstrates a call to a Rabobank API. Specifically this makes a call to the "Accounts AIS sb" API to deliver all the consented payments accounts for a specific Rabobank customer.

(This includes source code to for signing requests for PSD2 APIs)

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This example assumes the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  final http = CkHttp();

  // Implements the following CURL command:

  // curl --request GET \
  //   --url https://api-sandbox.rabobank.nl/openapi/sandbox/payments/account-information/ais/v3/accounts \
  //   --header 'accept: application/json' \
  //   --header 'authorization: Bearer REPLACE_BEARER_TOKEN' \
  //   --header 'date: REPLACE_THIS_VALUE' \
  //   --header 'digest: REPLACE_THIS_VALUE' \
  //   --header 'psu-ip-address: OPTIONAL' \
  //   --header 'signature: REPLACE_THIS_VALUE' \
  //   --header 'tpp-signature-certificate: MIIDkDCCAnigA ... cwE6gUl0rMA==' \
  //   --header 'x-ibm-client-id: Client ID' \
  //   --header 'x-request-id: REPLACE_THIS_VALUE'

  // Load the previously fetched OAuth2 access token.
  final jsonToken = CkJsonObject();
  try {
    jsonToken.loadFile('qa_data/tokens/rabobank.json');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // This adds the "authorization: Bearer REPLACE_BEARER_TOKEN" header.
  http.authToken = jsonToken.stringOf('access_token');

  // This is the TTP Signature certificate: The certificate used for signing the request.
  final sbTppCert = CkStringBuilder();
  sbTppCert.append('MIIDkDCCAnigAwIBAgIEWs3AJDANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMC');
  sbTppCert.append('TkwxEDAOBgNVBAgMB1V0cmVjaHQxEDAOBgNVBAcMB1V0cmVjaHQxETAPBgNVBAoM');
  sbTppCert.append('CFJhYm9iYW5rMRwwGgYDVQQLDBNPbmxpbmUgVHJhbnNhY3Rpb25zMSUwIwYDVQQD');
  sbTppCert.append('DBxQU0QyIEFQSSBQSSBTZXJ2aWNlcyBTYW5kYm94MB4XDTE4MDQxMTA3NTgyOFoX');
  sbTppCert.append('DTIzMDQxMTA3NTgyOFowgYkxCzAJBgNVBAYTAk5MMRAwDgYDVQQIDAdVdHJlY2h0');
  sbTppCert.append('MRAwDgYDVQQHDAdVdHJlY2h0MREwDwYDVQQKDAhSYWJvYmFuazEcMBoGA1UECwwT');
  sbTppCert.append('T25saW5lIFRyYW5zYWN0aW9uczElMCMGA1UEAwwcUFNEMiBBUEkgUEkgU2Vydmlj');
  sbTppCert.append('ZXMgU2FuZGJveDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANoAjqGW');
  sbTppCert.append('UgCIm2F+0sBSEwLal+T3u+uldLikpxHCB8iL1GD7FrRjcA+MVsxhvHly7vRsHK+t');
  sbTppCert.append('QyMSaeK782RHpY33qxPLc8LmoQLb2EuiQxXj9POYkYBQ74qkrZnvKVlR3WoyQWeD');
  sbTppCert.append('OXnSY2wbNFfkP8ET4ElwyuIIEriwYhab0OIrnnrO8X82/SPZxHwEd3aQjQ6uhiw8');
  sbTppCert.append('paDspJbS5WjEfuwY16KVVUYlhbtAwGjvc6aK0NBm+LH9fMLpAE6gfGZNy0gzMDor');
  sbTppCert.append('VNbkQK1IoAGD8p9ZHdB0F3FwkILEjUiQW6nK+/fKDNJ0TBbpgZUpY8bR460qzxKd');
  sbTppCert.append('eZ1yPDqX2Cjh6fkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYL4iD6noMJAt63kD');
  sbTppCert.append('ED4RB2mII/lssvHhcxuDpOm3Ims9urubFWEpvV5TgIBAxy9PBinOdjhO1kGJJnYi');
  sbTppCert.append('7F1jv1qnZwTV1JhYbvxv3+vk0jaiu7Ew7G3ASlzruXyMhN6t6jk9MpaWGl5Uw1T+');
  sbTppCert.append('gNRUcWQRR44g3ahQRIS/UHkaV+vcpOa8j186/1X0ULHfbcVQk4LMmJeXqNs8sBAU');
  sbTppCert.append('dKU/c6ssvj8jfJ4SfrurcBhY5UBTOdQOXTPY85aU3iFloerx7Oi9EHewxInOrU5X');
  sbTppCert.append('zqqTz2AQPXezexVeAQxP27lzqCmYC7CFiam6QBr06VebkmnPLfs76n8CDc1cwE6g');
  sbTppCert.append('Ul0rMA==');
  http.setRequestHeader('tpp-signature-certificate', sbTppCert.getAsString());

  // ----------------------------------------------------------------
  // We're not going to add the psu-ip-address header in this example.

  // ----------------------------------------------------------------
  // X-Request-ID header...
  // Generate a UUID v4.
  final crypt = CkCrypt2();
  final xRequestId = crypt.generateUuid();
  http.setRequestHeader('x-request-id', xRequestId);

  // ----------------------------------------------------------------
  // Date header...
  final dt = CkDateTime();
  dt.setFromCurrentSystemTime();
  final dateHdrVal = dt.getAsRfc822(false);
  // The desire date/time format is the "RFC822" format.
  http.setRequestHeader('Date', dateHdrVal);

  // ----------------------------------------------------------------
  // Digest header...
  crypt.hashAlgorithm = 'SHA256';
  crypt.encodingMode = 'base64';
  // A GET request has no HTTP request body.  Therefore the payload is the empty string.
  final payload = '';
  final payloadDigest = crypt.hashStringENC(payload);
  final sbDigestHdrVal = CkStringBuilder();
  sbDigestHdrVal.append('SHA-256=');
  sbDigestHdrVal.append(payloadDigest);
  http.setRequestHeader('digest', sbDigestHdrVal.getAsString());

  // ----------------------------------------------------------------
  // The HTTP request needs to be signed for PSD2 API's...
  // Create the signing string (to use in signing the HTTP request).
  // See https://developer.rabobank.nl/signing-requests-psd2-apis
  // 
  // For "account information" HTTP requests, we must use the following headers in the signing string.
  //    date
  //    digest
  //    x-request-id

  final sbStringToSign = CkStringBuilder();
  sbStringToSign.append('date: ');
  sbStringToSign.appendLine(dateHdrVal, false);
  sbStringToSign.append('digest: ');
  sbStringToSign.appendLine(sbDigestHdrVal.getAsString(), false);
  sbStringToSign.append('x-request-id: ');
  sbStringToSign.append(xRequestId);

  // ----------------------------------------------------------------
  // Sign with our private key...
  final sbPrivKey = CkStringBuilder();
  sbPrivKey.append('MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDaAI6hllIAiJth');
  sbPrivKey.append('ftLAUhMC2pfk97vrpXS4pKcRwgfIi9Rg+xa0Y3APjFbMYbx5cu70bByvrUMjEmni');
  sbPrivKey.append('u/NkR6WN96sTy3PC5qEC29hLokMV4/TzmJGAUO+KpK2Z7ylZUd1qMkFngzl50mNs');
  sbPrivKey.append('GzRX5D/BE+BJcMriCBK4sGIWm9DiK556zvF/Nv0j2cR8BHd2kI0OroYsPKWg7KSW');
  sbPrivKey.append('0uVoxH7sGNeilVVGJYW7QMBo73OmitDQZvix/XzC6QBOoHxmTctIMzA6K1TW5ECt');
  sbPrivKey.append('SKABg/KfWR3QdBdxcJCCxI1IkFupyvv3ygzSdEwW6YGVKWPG0eOtKs8SnXmdcjw6');
  sbPrivKey.append('l9go4en5AgMBAAECggEAB8nsTqalwGIhFw8mbXuhNUFlGuek/arYLD6pv28swwQH');
  sbPrivKey.append('7v0ZlxFUcCHF+iBl0PsDwZTZQ4ePtgGS6ehoLkWHCzb1lEv5E1YVG5qKNE2UUwRl');
  sbPrivKey.append('fIyPakO6AzyV/UF3uzq7C+/GuXGNTKZxKewg5yD/DCFvKoCOpxu9u36FyqP/hw0S');
  sbPrivKey.append('ADVlmp35/zoPDPZzu1j4FiCo0pJ9LwJcHxeJHopNAKDw9k6I4z/grskdgupsGzK2');
  sbPrivKey.append('BiGiQ/+wmmO68/6Xa6KWfpr1PQ6ODJHgzZsdGCVi6Ebaqlj6BbsYWxP6h3lrsGt+');
  sbPrivKey.append('LmHBaN2jCD6cDp+lihqFgnm8hfdv0lmbPilp71EDfwKBgQD6U8PBzZtN8yXm5WuS');
  sbPrivKey.append('NL+/8q5GjNmeTJBSo1gM6Y8vOT4QAE147LbVuVBDwyHPoSrNejePae6Q14PswjBy');
  sbPrivKey.append('T7B8DZ0OeQyGa3trrFg/ib7Vv4ZMvJqX9+WzBrzZsxTg7oCKHzmCR4vIRItKHH3z');
  sbPrivKey.append('Wnnhqlo8ic2AZ2O43cdJosbO1wKBgQDe8UODOLu0vnHohOKeUqF3w/ZOB2+83/js');
  sbPrivKey.append('YyUbSkzsGvHIwTjObuMUFTQvdMZ6IkIyJdfnDZIbvlBSD8tzL5iKFTNCK2nL1i4G');
  sbPrivKey.append('iFr0CYLaHAlhJ5GEbTrTMDoJeBPerZq83HPrSa/Wb0xO18QTWsoVQPFfPFbbcQyI');
  sbPrivKey.append('9ryJ2iIDrwKBgQC6kuAefG46ZPVk6K2KZUJdgDUgZC52a75NuW0RAqszmUiGiJM1');
  sbPrivKey.append('g8ip9tq6BqAWrprGV0c93shusBKlzf5p1LdHXqYmeVY6gbWVhPipMrNHgN5KJ3BZ');
  sbPrivKey.append('v+w1yNnMsErpcxne2HL2hPjMJTpj3GSLkm2xIlTrNhIyl9ydlr7IRUhENQKBgQCv');
  sbPrivKey.append('i6HxbXa/90WSJTCcIcxqla8X+dsOCf3jhJ3vQy4Wq5C+1wZ35fCAG8Ifq/+so9Uj');
  sbPrivKey.append('z5CVqqXlmpF8TFuSs2OVNuRJsg14J4nOMwgLKIIUZAcurQ10DN5I9Kx+UEK1EFXL');
  sbPrivKey.append('aHsORdNjMfgQDO2jn9WHrr9gkg6CdB2+qyoCEfS+mQKBgBW08lcy9V5RzRWb/v/j');
  sbPrivKey.append('xsc7ovmgAhCJhDeV7dPbx4HbFeoQJlbA8g1thdcFlcatSGyNDbvNE1GPSd4NhkpR');
  sbPrivKey.append('Y6Hfv53kdEzjVkEtU8lUdL7HNVJqX7bU7oZlfbYcwxWQ1Gg8C1oLIAyEt71slQtd');
  sbPrivKey.append('RiNYBRZTQe2F0wxbXnuUqLAw');

  final privKey = CkPrivateKey();
  try {
    privKey.loadPem(sbPrivKey.getAsString());
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  final rsa = CkRsa();
  try {
    rsa.usePrivateKey(privKey);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  rsa.encodingMode = 'base64';
  final b64Signature = rsa.signStringENC(sbStringToSign.getAsString(), 'SHA256');

  // ----------------------------------------------------------------
  // Add the "signature" header.
  // 
  // The signature header will look like this:
  // signature: keyId="1523433508",algorithm="rsa-sha512",headers="date digest x-request-id",signature="y5o7gKxmfA6AT6...blE1A9Q=="
  // 
  // The keyId is the serial number of the certificate as defined in 'TPP-Signing-Certificate' header, the format should be Integer not hex. 
  final cert = CkCert();
  try {
    cert.setFromEncoded(sbTppCert.getAsString());
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  final sbSigHdrVal = CkStringBuilder();
  sbSigHdrVal.append('keyId="');
  sbSigHdrVal.append(cert.serialDecimal);
  sbSigHdrVal.append('",');
  sbSigHdrVal.append('algorithm="rsa-sha256",');
  sbSigHdrVal.append('headers="date digest x-request-id",');
  sbSigHdrVal.append('signature="');
  sbSigHdrVal.append(b64Signature);
  sbSigHdrVal.append('"');

  http.setRequestHeader('signature', sbSigHdrVal.getAsString());

  // ----------------------------------------------------------------
  // Add remaining headers...

  http.setRequestHeader('x-ibm-client-id', 'YOUR_APP_CLIENT_ID');
  http.setRequestHeader('accept', 'application/json');

  // ----------------------------------------------------------------
  // Add our certificate and key for mutual TLS 
  // (provide a registered X509 client certificate during TLS handhake)

  final tlsCert = CkCert();
  try {
    tlsCert.loadFromFile('qa_data/certs_and_keys/ING/example_client_tls.cer');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  final bdPrivKey = CkBinData();
  try {
    bdPrivKey.loadFile('qa_data/certs_and_keys/ING/example_client_tls.key');
  } on ChilkatException {
    print('Failed to load example_client_tls.key');
    return;
  }

  // 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.

  final tlsPrivKey = CkPrivateKey();
  try {
    tlsPrivKey.loadAnyFormat(bdPrivKey, '');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // Associate the private key with the certificate.
  try {
    tlsCert.setPrivateKey(tlsPrivKey);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  try {
    http.setSslClientCert(tlsCert);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // ----------------------------------------------------------------
  // Finally, send the request...

  final sbResponseBody = CkStringBuilder();
  try {
    http.quickGetSb('https://api-sandbox.rabobank.nl/openapi/sandbox/payments/account-information/ais/v3/accounts', sbResponseBody);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    print(sbResponseBody.getAsString());
    return;
  }

  final jResp = CkJsonObject();
  jResp.loadSb(sbResponseBody);
  jResp.emitCompact = false;

  print('Response Body:');
  print(jResp.emit());

  final respStatusCode = http.lastStatus;
  print('Response Status Code = $respStatusCode');
  if (respStatusCode >= 400) {
    print('Response Header:');
    print(http.lastHeader);
    print('Failed.');
    return;
  }

  // Sample JSON response:
  // (Sample code for parsing the JSON response is shown below)

  // {
  //   "accounts": [
  //     {
  //       "_links": {
  //         "account": "/v3/accounts/dW9od2VIVUhGVypIZHVpaGRhdWR3OGRoY",
  //         "balances": "/v3/accounts/dW9od2VIVUhGVypIZHVpaGRhdWR3OGRoY/balances",
  //         "transactions": "/v3/accounts/dW9od2VIVUhGVypIZHVpaGRhdWR3OGRoY/transactions"
  //       },
  //       "currency": "EUR",
  //       "iban": "NL05RABO0812836782",
  //       "name": "Rosie Roy",
  //       "resourceId": "dW9od2VIVUhGVypIZHVpaGRhdWR3OGRoY",
  //       "status": "enabled"
  //     }
  //   ]
  // }

  // Sample code for parsing the JSON response...
  // Use the following online tool to generate parsing code from sample JSON:
  // Generate Parsing Code from JSON

  var vLinksAccount = '';
  var vLinksBalances = '';
  var vLinksTransactions = '';
  var currency = '';
  var iban = '';
  var name = '';
  var resourceId = '';
  var status = '';

  var i = 0;
  final countI = jResp.sizeOfArray('accounts');
  while (i < countI) {
    jResp.i = i;
    vLinksAccount = jResp.stringOf('accounts[i]._links.account');
    vLinksBalances = jResp.stringOf('accounts[i]._links.balances');
    vLinksTransactions = jResp.stringOf('accounts[i]._links.transactions');
    currency = jResp.stringOf('accounts[i].currency');
    iban = jResp.stringOf('accounts[i].iban');
    name = jResp.stringOf('accounts[i].name');
    resourceId = jResp.stringOf('accounts[i].resourceId');
    status = jResp.stringOf('accounts[i].status');
    i++;
  }
}