PSD2 banking api
Published: 2023-07-07 09:32:07

I try to use the PSD2-api from the ING bank: https://developer.ing.com/openbanking/resources/get-started/psd2#sandbox

I have used the following llink to an example script: https://developer.ing.com/openbanking/assets/data/psd2SandReqAppToken.txt
I asked ChatGPT to translate this to PHP-code. It comes up with de code below. Unfortunately I get this error: "Access token request failed. HTTP code: 400 Response: { "message" : "The supplied Authorization Signature header does not have the correct format" }"
Can anybody help me to get this to work?

This is the PHP-code I used:
<?php

$keyId = "SN=546212fb"; // Serial number of the downloaded certificate in hexadecimal code
$certPath = "./certificates/"; // Path of the downloaded certificates and keys
$httpHost = "https://api.sandbox.ing.com";

// HTTP method value must be in lowercase
$httpMethod = "post";
$reqPath = "/oauth2/token";

// You can also provide the scope parameter in the body, e.g., "grant_type=client_credentials&scope=greetings%3Aview"
// The scope is an optional parameter. If you don't provide a scope, the accessToken is returned for all available scopes
$payload = "grant_type=client_credentials";
$payloadDigest = base64_encode(hash("sha256", $payload, true));
$digest = "SHA-256=" . $payloadDigest;

$reqDate = gmdate("D, d M Y H:i:s T");

// Signing string must be declared exactly as shown below in separate lines
$signingString = "(request-target): $httpMethod $reqPath
date: $reqDate
digest: $digest";

$signature = base64_encode(openssl_sign($signingString, $signature, $certPath . "example_client_signing.key", OPENSSL_ALGO_SHA256));
$signature = "Signature keyId=\"$keyId\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"$signature\"";

$tokenUrl = $httpHost . $reqPath;

$ch = curl_init($tokenUrl);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Accept: application/json",
    "Content-Type: application/x-www-form-urlencoded",
    "Digest: " . $digest,
    "Date: " . $reqDate,
    "TPP-Signature-Certificate: -----BEGIN CERTIFICATE-----MIIEdjCCA16gAwIBAgIEVGIS+zANBgkqhkiG9w0BAQsFADByMR8wHQYDVQQDDBZBcHBDZXJ0aWZpY2F0ZU1lYW5zQVBJMQwwCgYDVQQLDANJbmcxDDAKBgNVBAoMA0luZzESMBAGA1UEBwwJQW1zdGVyZGFtMRIwEAYDVQQIDAlBbXN0ZXJkYW0xCzAJBgNVBAYTAk5MMB4XDTIzMDEyNTE2MzEwMFoXDTI2MDEyNjE2MzEwMFowPjEdMBsGA1UECwwUc2FuZGJveF9laWRhc19xc2VhbGMxHTAbBgNVBGEMFFBTRE5MLVNCWC0xMjM0NTEyMzQ1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgV7IDXg+9U7I7MlybwuIZ3xzZ8TazJ8mvTqKak5K3fwb9ny9jfJFtSaJbWHkpb1mc/WAS4iLC/ET6tvX404mD++Ed+epTxAGQgpPDKg+rQ4O9k/QLZGNPn2ujBU12YO+N+qkK0edTFP1s/CjO4yONLA1fgY1e+0K87PyPXw0OyNqFrKTL0pFgcGB4Jt+AVCoVP0a/zxhWOj6UFxdHsktOcMBRDiLz6QuSaNv+/DmZtnujzcByG62sg2H3WV0n9jXktxqvK5xToJQAYNQg9qcRafx2WUiA6iu8x6KC/MWp0t+ZBO1ahhXz75XdXrT0ZneXLlvLH21qH/xpwrtMmbufwIDAQABo4IBRjCCAUIwNwYDVR0fBDAwLjAsoCqgKIYmaHR0cHM6Ly93d3cuaW5nLm5sL3Rlc3QvZWlkYXMvdGVzdC5jcmwwPgYIKwYBBQUHAQEEMjAwMC4GCCsGAQUFBzABhiJodHRwOi8vbXkucmV2b2NhdGlvbi50ZXN0L3Rlc3RvY3NwMB8GA1UdIwQYMBaAFEJsCqHCMVi1pneOBeelHbYQtJ9TMB0GA1UdDgQWBBRUDFfAkj5oafpiTlt9f57TZtOVGTCBhgYIKwYBBQUHAQMEejB4MAoGBgQAjkYBAQwAMBMGBgQAjkYBBjAJBgcEAI5GAQYCMFUGBgQAgZgnAjBLMDkwEQYHBACBmCcBAwwGUFNQX0FJMBEGBwQAgZgnAQIMBlBTUF9QSTARBgcEAIGYJwEBDAZQU1BfQVMMBlgtV0lORwwGTkwtWFdHMA0GCSqGSIb3DQEBCwUAA4IBAQBWu2tqCoxDMt5JDweVcz4JFul6E+E7OENmTrUjwW7IwMn+LYVRpFMLoiYkfR0XR5SzJELjZVK5b8vnd8TTrUs2F+kb34uPDuE+34MvHa0CsKGFLOgeLBnlOrsweKOupNNz6mdXe4aylJlFMRun8yO2wQ2MfnXUomK5qKwfWJYoTTWgNiIoG8RSLQwismLyihbcxn9F8UQUfh6cEaZ9VujHwNHBEdQUnMbquyH1xWUKKYi1ApZcQplBnv822fabV/5vGo+UvKYvaaxge3hgmHL8NyXGf3CLfEKGrJGlapR9bKQOCJH0KZ/K9AuqpmCGBiqTPVbMK8AJHCrKGu3zBkI2-----END CERTIFICATE-----",
    "Authorization: " . $signature
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_SSLCERT, $certPath . "example_client_tls.cer");
curl_setopt($ch, CURLOPT_SSLKEY, $certPath . "example_client_tls.key");

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

// Check the response HTTP code to determine if the request was successful
if ($httpCode == 200) {
    echo "Access token request successful.\n";
    echo "Response:\n";
    echo $response;
} else {
    echo "Access token request failed.\n";
    echo "HTTP code: " . $httpCode . "\n";
    echo "Response:\n";
    echo $response;
}

?>