PureBasic
PureBasic
Ibanity XS2A List Financial Institutions
See more Ibanity Examples
Demonstrates how to send a request to get a list of financial institutions.Chilkat PureBasic Downloads
IncludeFile "CkJsonObject.pb"
IncludeFile "CkDateTime.pb"
IncludeFile "CkPrivateKey.pb"
IncludeFile "CkHttp.pb"
IncludeFile "CkCrypt2.pb"
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkRsa.pb"
IncludeFile "CkCert.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; Send the following request:
; $ curl -X GET https://api.ibanity.com/xs2a/financial-institutions \
; --cert certificate.pem \
; --key private_key.pem \
; -H 'Signature: keyId="75b5d796-de5c-400a-81ce-e72371b01cbc",created=1599659223,algorithm="hs2019",headers="(request-target) digest (created) host",signature="BASE64(RSA-SHA256(SIGNING_STRING))"' \
; -H 'Digest: SHA-512=beDaRguyEb8fhh5wnl37bOTDtvhuYZyZNkTZ9LiC9Wc='
; Ibanity provides the certificate + private key in PFX format. This example will use the .pfx instead of the pair of PEM files.
; (It is also possible to implement using Chilkat with the PEM files, but PFX is easier.)
cert.i = CkCert::ckCreate()
If cert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadPfxFile(cert,"qa_data/pfx/my_ibanity_certificate.pfx","my_pfx_password")
If success = 0
Debug CkCert::ckLastErrorText(cert)
CkCert::ckDispose(cert)
ProcedureReturn
EndIf
; We need to calculate the Digest and Signature header fields.
; For a detailed explanation, see Calculate Ibanity HTTP Signature Example
; We'll just write the code here as briefly as possible.
dtNow.i = CkDateTime::ckCreate()
If dtNow.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkDateTime::ckSetFromCurrentSystemTime(dtNow)
created.s = CkDateTime::ckGetAsUnixTimeStr(dtNow,0)
crypt2.i = CkCrypt2::ckCreate()
If crypt2.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCrypt2::setCkHashAlgorithm(crypt2, "sha512")
CkCrypt2::setCkEncodingMode(crypt2, "base64")
sbDigestHdrValue.i = CkStringBuilder::ckCreate()
If sbDigestHdrValue.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStringBuilder::ckAppend(sbDigestHdrValue,"SHA-512=")
; GET requests have empty payloads. The SHA-512 hash of the empty string is the same for all GET requests.
; Therefore all GET requests will use "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=="
; You can eliminate the explicit hash computation (for GET requests) and simply use the above literal string.
CkStringBuilder::ckAppend(sbDigestHdrValue,CkCrypt2::ckHashStringENC(crypt2,""))
Debug "Generated Digest"
Debug CkStringBuilder::ckGetAsString(sbDigestHdrValue)
request_target.s = "get /xs2a/financial-institutions"
sbSigningString.i = CkStringBuilder::ckCreate()
If sbSigningString.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStringBuilder::ckAppend(sbSigningString,"(request-target): ")
CkStringBuilder::ckAppendLine(sbSigningString,request_target,0)
CkStringBuilder::ckAppend(sbSigningString,"host: ")
CkStringBuilder::ckAppendLine(sbSigningString,"api.ibanity.com",0)
CkStringBuilder::ckAppend(sbSigningString,"digest: ")
CkStringBuilder::ckAppendLine(sbSigningString,CkStringBuilder::ckGetAsString(sbDigestHdrValue),0)
CkStringBuilder::ckAppend(sbSigningString,"(created): ")
CkStringBuilder::ckAppend(sbSigningString,created)
; ibanity-idempotency-key is not used with GET requests.
Debug "Signing String:"
Debug CkStringBuilder::ckGetAsString(sbSigningString)
signed_headers_list.s = "(request-target) host digest (created)"
privKey.i = CkPrivateKey::ckCreate()
If privKey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPrivateKey::ckLoadEncryptedPemFile(privKey,"my_ibanity_signature_private_key.pem","pem_password")
If success = 0
Debug CkPrivateKey::ckLastErrorText(privKey)
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
ProcedureReturn
EndIf
rsa.i = CkRsa::ckCreate()
If rsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkRsa::setCkPssSaltLen(rsa, 32)
CkRsa::setCkEncodingMode(rsa, "base64")
; Use the RSASSA-PSS signature algorithm
CkRsa::setCkPkcsPadding(rsa, 0)
success = CkRsa::ckUsePrivateKey(rsa,privKey)
If success = 0
Debug CkRsa::ckLastErrorText(rsa)
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
; Sign the signing string.
sigBase64.s = CkRsa::ckSignStringENC(rsa,CkStringBuilder::ckGetAsString(sbSigningString),"sha-256")
If CkRsa::ckLastMethodSuccess(rsa) = 0
Debug CkRsa::ckLastErrorText(rsa)
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
Debug "Signature:"
Debug sigBase64
; Build the signature header value.
sbSigHeaderValue.i = CkStringBuilder::ckCreate()
If sbSigHeaderValue.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStringBuilder::ckAppend(sbSigHeaderValue,"keyId=" + Chr(34))
; Use your identifier for the application's signature certificate, obtained from the Developer Portal
CkStringBuilder::ckAppend(sbSigHeaderValue,"a0ce296d-84c8-4bd5-8eb4-de0339950cfa")
CkStringBuilder::ckAppend(sbSigHeaderValue,Chr(34) + ",created=")
CkStringBuilder::ckAppend(sbSigHeaderValue,created)
CkStringBuilder::ckAppend(sbSigHeaderValue,",algorithm=" + Chr(34) + "hs2019" + Chr(34) + ",headers=" + Chr(34))
CkStringBuilder::ckAppend(sbSigHeaderValue,signed_headers_list)
CkStringBuilder::ckAppend(sbSigHeaderValue,Chr(34) + ",signature=" + Chr(34))
CkStringBuilder::ckAppend(sbSigHeaderValue,sigBase64)
CkStringBuilder::ckAppend(sbSigHeaderValue,Chr(34))
; Send the GET request..
http.i = CkHttp::ckCreate()
If http.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkHttp::ckSetSslClientCert(http,cert)
If success = 0
Debug CkHttp::ckLastErrorText(http)
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
CkStringBuilder::ckDispose(sbSigHeaderValue)
CkHttp::ckDispose(http)
ProcedureReturn
EndIf
CkHttp::ckSetRequestHeader(http,"Signature",CkStringBuilder::ckGetAsString(sbSigHeaderValue))
CkHttp::ckSetRequestHeader(http,"Digest",CkStringBuilder::ckGetAsString(sbDigestHdrValue))
sbResponseBody.i = CkStringBuilder::ckCreate()
If sbResponseBody.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkHttp::ckQuickGetSb(http,"https://api.ibanity.com/xs2a/financial-institutions",sbResponseBody)
If success = 0
Debug CkHttp::ckLastErrorText(http)
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
CkStringBuilder::ckDispose(sbSigHeaderValue)
CkHttp::ckDispose(http)
CkStringBuilder::ckDispose(sbResponseBody)
ProcedureReturn
EndIf
jResp.i = CkJsonObject::ckCreate()
If jResp.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckLoadSb(jResp,sbResponseBody)
CkJsonObject::setCkEmitCompact(jResp, 0)
Debug "Response Body:"
Debug CkJsonObject::ckEmit(jResp)
respStatusCode.i = CkHttp::ckLastStatus(http)
Debug "Response Status Code = " + Str(respStatusCode)
If respStatusCode >= 400
Debug "Response Header:"
Debug CkHttp::ckLastHeader(http)
Debug "Failed."
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
CkStringBuilder::ckDispose(sbSigHeaderValue)
CkHttp::ckDispose(http)
CkStringBuilder::ckDispose(sbResponseBody)
CkJsonObject::ckDispose(jResp)
ProcedureReturn
EndIf
; Sample output:
; (Sample code for parsing the JSON response is shown below)
; {
; "data": [
; {
; "attributes": {
; "authorizationModels": [
; "detailed",
; "financialInstitutionOffered"
; ],
; "bic": "NBBEBEBB203",
; "bulkPaymentsEnabled": true,
; "bulkPaymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "country": null,
; "financialInstitutionCustomerReferenceRequired": false,
; "futureDatedPaymentsAllowed": true,
; "logoUrl": "https://s3.eu-central-1.amazonaws.com/ibanity-production-financial-institution-assets/sandbox.png",
; "maintenanceFrom": null,
; "maintenanceTo": null,
; "maintenanceType": null,
; "maxRequestedAccountReferences": null,
; "minRequestedAccountReferences": 0,
; "name": "Bogus Financial",
; "paymentsEnabled": true,
; "paymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "periodicPaymentsEnabled": true,
; "periodicPaymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "primaryColor": "#7d39ff",
; "requiresCredentialStorage": false,
; "requiresCustomerIpAddress": false,
; "sandbox": true,
; "secondaryColor": "#3DF2C2",
; "sharedBrandName": null,
; "sharedBrandReference": null,
; "status": "beta"
; },
; "id": "2d3d70a4-cb3c-477c-97e1-cbe495b82841",
; "links": {
; "self": "https://api.ibanity.com/xs2a/financial-institutions/2d3d70a4-cb3c-477c-97e1-cbe495b82841"
; },
; "type": "financialInstitution"
; },
; {
; "attributes": {
; "authorizationModels": [
; "detailed",
; "financialInstitutionOffered"
; ],
; "bic": "NBBEBEBB203",
; "bulkPaymentsEnabled": true,
; "bulkPaymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "country": null,
; "financialInstitutionCustomerReferenceRequired": false,
; "futureDatedPaymentsAllowed": true,
; "logoUrl": "https://s3.eu-central-1.amazonaws.com/ibanity-production-financial-institution-assets/sandbox.png",
; "maintenanceFrom": null,
; "maintenanceTo": null,
; "maintenanceType": null,
; "maxRequestedAccountReferences": null,
; "minRequestedAccountReferences": 0,
; "name": "XYZ Trust",
; "paymentsEnabled": true,
; "paymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "periodicPaymentsEnabled": true,
; "periodicPaymentsProductTypes": [
; "sepaCreditTransfer"
; ],
; "primaryColor": "#7d39ff",
; "requiresCredentialStorage": false,
; "requiresCustomerIpAddress": false,
; "sandbox": true,
; "secondaryColor": "#3DF2C2",
; "sharedBrandName": null,
; "sharedBrandReference": null,
; "status": "beta"
; },
; "id": "d4100f28-936b-4379-a3f8-86314a2014fb",
; "links": {
; "self": "https://api.ibanity.com/xs2a/financial-institutions/d4100f28-936b-4379-a3f8-86314a2014fb"
; },
; "type": "financialInstitution"
; }
; ],
; "links": {
; "first": "https://api.ibanity.com/xs2a/financial-institutions"
; },
; "meta": {
; "paging": {
; "limit": 10
; }
; }
; }
; Sample code for parsing the JSON response...
; Use the following online tool to generate parsing code from sample JSON:
; Generate Parsing Code from JSON
attributesBic.s
attributesBulkPaymentsEnabled.i
attributesCountry.s
attributesFinancialInstitutionCustomerReferenceRequired.i
attributesFutureDatedPaymentsAllowed.i
attributesLogoUrl.s
attributesMaintenanceFrom.s
attributesMaintenanceTo.s
attributesMaintenanceType.s
attributesMaxRequestedAccountReferences.s
attributesMinRequestedAccountReferences.i
attributesName.s
attributesPaymentsEnabled.i
attributesPeriodicPaymentsEnabled.i
attributesPrimaryColor.s
attributesRequiresCredentialStorage.i
attributesRequiresCustomerIpAddress.i
attributesSandbox.i
attributesSecondaryColor.s
attributesSharedBrandName.s
attributesSharedBrandReference.s
attributesStatus.s
id.s
linksSelf.s
v_type.s
j.i
count_j.i
strVal.s
linksFirst.s = CkJsonObject::ckStringOf(jResp,"links.first")
metaPagingLimit.i = CkJsonObject::ckIntOf(jResp,"meta.paging.limit")
i.i = 0
count_i.i = CkJsonObject::ckSizeOfArray(jResp,"data")
While i < count_i
CkJsonObject::setCkI(jResp, i)
attributesBic = CkJsonObject::ckStringOf(jResp,"data[i].attributes.bic")
attributesBulkPaymentsEnabled = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.bulkPaymentsEnabled")
attributesCountry = CkJsonObject::ckStringOf(jResp,"data[i].attributes.country")
attributesFinancialInstitutionCustomerReferenceRequired = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.financialInstitutionCustomerReferenceRequired")
attributesFutureDatedPaymentsAllowed = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.futureDatedPaymentsAllowed")
attributesLogoUrl = CkJsonObject::ckStringOf(jResp,"data[i].attributes.logoUrl")
attributesMaintenanceFrom = CkJsonObject::ckStringOf(jResp,"data[i].attributes.maintenanceFrom")
attributesMaintenanceTo = CkJsonObject::ckStringOf(jResp,"data[i].attributes.maintenanceTo")
attributesMaintenanceType = CkJsonObject::ckStringOf(jResp,"data[i].attributes.maintenanceType")
attributesMaxRequestedAccountReferences = CkJsonObject::ckStringOf(jResp,"data[i].attributes.maxRequestedAccountReferences")
attributesMinRequestedAccountReferences = CkJsonObject::ckIntOf(jResp,"data[i].attributes.minRequestedAccountReferences")
attributesName = CkJsonObject::ckStringOf(jResp,"data[i].attributes.name")
attributesPaymentsEnabled = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.paymentsEnabled")
attributesPeriodicPaymentsEnabled = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.periodicPaymentsEnabled")
attributesPrimaryColor = CkJsonObject::ckStringOf(jResp,"data[i].attributes.primaryColor")
attributesRequiresCredentialStorage = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.requiresCredentialStorage")
attributesRequiresCustomerIpAddress = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.requiresCustomerIpAddress")
attributesSandbox = CkJsonObject::ckBoolOf(jResp,"data[i].attributes.sandbox")
attributesSecondaryColor = CkJsonObject::ckStringOf(jResp,"data[i].attributes.secondaryColor")
attributesSharedBrandName = CkJsonObject::ckStringOf(jResp,"data[i].attributes.sharedBrandName")
attributesSharedBrandReference = CkJsonObject::ckStringOf(jResp,"data[i].attributes.sharedBrandReference")
attributesStatus = CkJsonObject::ckStringOf(jResp,"data[i].attributes.status")
id = CkJsonObject::ckStringOf(jResp,"data[i].id")
linksSelf = CkJsonObject::ckStringOf(jResp,"data[i].links.self")
v_type = CkJsonObject::ckStringOf(jResp,"data[i].type")
j = 0
count_j = CkJsonObject::ckSizeOfArray(jResp,"data[i].attributes.authorizationModels")
While j < count_j
CkJsonObject::setCkJ(jResp, j)
strVal = CkJsonObject::ckStringOf(jResp,"data[i].attributes.authorizationModels[j]")
j = j + 1
Wend
j = 0
count_j = CkJsonObject::ckSizeOfArray(jResp,"data[i].attributes.bulkPaymentsProductTypes")
While j < count_j
CkJsonObject::setCkJ(jResp, j)
strVal = CkJsonObject::ckStringOf(jResp,"data[i].attributes.bulkPaymentsProductTypes[j]")
j = j + 1
Wend
j = 0
count_j = CkJsonObject::ckSizeOfArray(jResp,"data[i].attributes.paymentsProductTypes")
While j < count_j
CkJsonObject::setCkJ(jResp, j)
strVal = CkJsonObject::ckStringOf(jResp,"data[i].attributes.paymentsProductTypes[j]")
j = j + 1
Wend
j = 0
count_j = CkJsonObject::ckSizeOfArray(jResp,"data[i].attributes.periodicPaymentsProductTypes")
While j < count_j
CkJsonObject::setCkJ(jResp, j)
strVal = CkJsonObject::ckStringOf(jResp,"data[i].attributes.periodicPaymentsProductTypes[j]")
j = j + 1
Wend
i = i + 1
Wend
CkCert::ckDispose(cert)
CkDateTime::ckDispose(dtNow)
CkCrypt2::ckDispose(crypt2)
CkStringBuilder::ckDispose(sbDigestHdrValue)
CkStringBuilder::ckDispose(sbSigningString)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
CkStringBuilder::ckDispose(sbSigHeaderValue)
CkHttp::ckDispose(http)
CkStringBuilder::ckDispose(sbResponseBody)
CkJsonObject::ckDispose(jResp)
ProcedureReturn
EndProcedure