TPP Setup for PSD2 APIs

In order to access PSD2 APIs in sandbox or in production, the TPP must ensure that they are in possession of valid certificates prior to registering using the TPP registry.

The TPP needs:

  • Valid eIDAS certs (QWAC), or generated certs from OP for TLS MA
  • Keypair for signing JWTs (QSEALC)
  • A signed Software Statement Assertion (SSA)
  • A signed registration JWT with the SSA as one of its fields.

Note: This document assumes cURL version 7.65.0 or higher.

Java helper app

Certificate management and TPP registration are complicated operations. To help you get started, we have provided a Java application which you can use to complete these steps in the sandbox environment, and which you may find helpful when building your production application.


Certificates

The TPP must either possess valid eIDAS certificates or use our TPP certificate generation API for generating certificates for use in our PSD2 sandbox environment.

Note that while some certificate vendors offer test certificates, OP's PSD2 sandbox only supports real certificates and certificates from our sandbox certificate API. In other words, 3rd party test certificates are not supported.

Two types of certificates are required:

CertificateAlt NameUse
QWACMTLS cert/keyTransport Layer Security: Mutually authenticated TLS
QSEALCSigning cert/keyDigital Signatures, i.e. signing JWTs.

If the TPP is in possession of valid certificates, they may choose to ignore this step and move on to TPP registration (below).

Certificates can be purchased from Qualified Trust Dervice Providers (QTSPs). The European Union maintains a list of Trust Services. Search the list by Type of Service and select "Qualified certificate for electronic seal" and "Qualified certificate for website authentication", and select the countries you are interested in.

More information on certificates at e.g. Open Banking Europe's FAQ.

QTSPs that have been onboarded

Below is a list QTSPs that we have onboarded so far. We onboard QTSPs on an as-needed basis. If your QTSP is not on the list, please contact us prior to registration at tpp-support@op.fi so we can add them to our list.

  • Actalis (IT)
  • Buypass (NO)
  • D-Trust (DE)
  • I.CA (CZ)
  • InfoCert (IT)
  • Krajowa Izba Rozliczeniowa / COPE SZAFIR - Kwalifikowany (PL)
  • LuxTrust (LU)
  • Microsec (HU)
  • MULTICERT (PT)
  • Quovadis Trustlink (NL)

Generating certificates for sandbox

The certificate generation service provides two certificates: one for emulating QWAC (for establishing mTLS), and another for emulating QSEALC (JWT signing).

Once the certificates have been generated and delivered to the TPP, the generation service makes the public keys available to services in our sandbox environment. This means that the TPP does not need to publish a JWKS endpoint for their app, unless they want to use keypairs they have obtained from another authority.

Call the certificate generation API as follows:

curl -X POST -v 'https://sandbox.apis.op-palvelut.fi/psd2-sandbox-tpp-generator/sandbox-tpp?c=<COUNTRY>&cn=<TPP_NAME>&roles=AIS,PIS,CBPII' \
-H 'x-api-key: <APP_API_KEY>' \
-H 'Content-Length: 0' \
-H 'Accept: application/json' \
-d ''

Query parameters

Parameter nameExplanation
cCountry as ISO 3166-1 Alpha 2 (e.g. FI).
cnCommon name of the TPP company (e.g. "Brinklyfy.io").
rolesAn optional comma separated list of PSD2 roles e.g. AIS, PIS and CBPII

Sample Response

HTTP/1.1 201 Created
Date: Tue, 05 Mar 2019 14:03:25 GMT
Content-Type: application/jwk-set+json; charset=UTF-8

{
  "privateJwks": {
    "keys": [
      {
        "d": "Je7W5zLu8bO-pJZg1gx0aB7nn-3csejjup4hvS5wc6L4Fk4eJnM6ouViOmf7sw3peenwlLeaVHDBTImY0ohCYDSWNIRcuRjq1vjutx0bh3U4OKaba7ruWGj9j0fxzrue6flOeb3wEXhyLIGGrZZFGcKbuqJw-UnIgt_GV5GeTxH4G-pDnShjFZy_Sbei-JHKxn65SVMcOoxv9UborQdfIWF5qvFDUU-w9iM5x2aGG0Y-7JJI8KpQ_F1nLVnz68r3cpm5A6b2HEDnJkoFifVrhtrs590vKMHPsggCScVGvcHwxKdfUVG8Re3ECZP0q9Db1EyATKpkN1I1XOl7qDw2XB-LXLzLjLqVkBoyRh3Zj1mK0c3LRN1-ENAD9A5WGVAU4xMWMb89Qkqc_MzB_KEOULKR_r7vUjKXMLFGqosW1FHWoyG89Z13O0t2SRyWE1gi5r-VOiite2TybRi9em2O1AdK9TPqAPM4BfqtccFOKvTCJrXPvLYhipEehplMNKthJ7ALgb9V7yMEydtcdTb22qQY4ZqBVrDSjOG0y0QTOUe50F2x7kOhftotFsSK4sxjRuluUmp1fhJ1JA0dBIlzzv5yYLCa7QF9xKTu01m6GxpGbzPskp6DmzYY0_86ZiO97PKc4l4F5g9d68FtsrCVzeuX2WJjOwmIYJNS5x7MpiU",
        "e": "AQAB",
        "use": "sig",
        "kid": "qwac-E4ZXGQ",
        "x5c": [
          "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"
        ],
        "dp": "tjCRF7hA_H3g4VtKe7SlX3gFFujwMca5mVdeSpk52nvdSoixMNWt8vQ5Xa_Uway6SGMT0KTEo2j80UXebxyIFNp8QPWgKsBGjspB9iwq_MOtzDFyLasJVSfqWDPleN3gihRshb1ezCBde5UuPt2HfzNaBb_upVackXRzX0XjhizcCQHr06_5czQ2B3zWRX_PbScQ_-SZ4zT3k_qgxPWtuJcMCLBUU3vHL71PmKO-muKlR9WEDRyqFI0uBZRWPZWSrhortWT_yLRTKZVxs6AGW34K2rJhO34DFBdwp-uDrJUXXsCp7fC5XXgmx03FFz29SnhWdrrfTwl_qXjazXO9rQ",
        "dq": "bOJ5fP4fH-C2sK3FoswD-12EzKe8pU_aUDSJXuCCH1_ACWj4LWyTV8HVyolYr1GVxzyxPPuif2xB9zS96mRVocoRXcbeYCsKQ9qclXnKkubkq7xlsEuQXOsz4VctJorYhwp9UheIPfVRgQO3fZvimxBvA60M8097R6Qe8OXUnVuSAKKHReEPdtFuKZh7jSOB6NhQWzmfQzVvmPaRaqyVBkhxUnE85EJzuoT9DxbciMu8Ecees7Bjl3UPqy5HLR5qea5hSkWqA-ccsBfI2GAjP1gsZrIN920QKk6zZXn2fQce3gKQl6ss7oY_-OvjQj4brWbl3rw5pHY5SM5TDXqSSw",
        "n": "m4WH0u5eqK5ggwToSeHFXLtfIGPhLvcjTiKQ7MTRkt1KgZjGRmReEv5_H7J0_YLuZY7QVXWE2GFVx_Y4eJQOrVynR0q62sJjpMZbYeWeF9_WMuB_5rvjrMZ9Vn05ClIOJpmG8Xsi61U1z0cLqSZVvq-k_ZWfO6LSSaRA4eAINfFpxv4WMANVwqjopDuWPXpUBPTl6Y2lSRZRKNYOUQE0JBNUtckKZychCUaTqyAR9zKH0gY0vJS1t55NE4pXkObsoYOfCPvpkQAJ2jD4neQwj9qmLza1KTCtR6mWjbnUlXaJGRkH8EISSKUM2XvZHKSxVjbQHia9CWAmKmvarjWQUqHVh6fJoRgDUE7lsKJZompiWL8MS7weq4OcfbUhABRE2IngjGFNx4WErwukTbtV76vlUZIJu_aE0KJABEBGuuqJVvR6e9u_mGC6ONLq090gqKsBMFyPiDIP3ouMol7n7YN82uB6thCtxSV9l48yg8d4V3gzRdYajudHkzxCX-30wQ1dRU_LWk2URSeO0XqEyozke37UYo8z-t3NealQUtHVytmtvBEgH11nZ-QlDkARELGpJVNj7SVGLHpbU72ZHcHTXLNbW1HUQ-hZdzPO31rZJwDEJT5LoEQddKn7aDHH_27-aXr_1Mk0Y9yOWU-ZdO7LFtKZTWMswlgJgVZvDjE",
        "p": "2yA3XSarM98GlUm2bEJXpgJyFXhyKHR9zAGAbWhFn-dOQOscZKWhfuzJRqfiY-OHfURz0QWKV2R5j2O4f9cQ93iMnwfLdUa7QyPLMf0OFt03xBYN_wdL0ano1Fim3JUktfjCItTO38uTn662Zk4TK_Wh37R5nKGpWS8uq3MIQnOth1yaiawnSod7ASaBK-F3dWrfkZoY0uvDpKQ7Cz1viM2caulxxydCs5U33qPsQvHNl27nLZpsTnlHmk5wVNjUEjbAOc8R7TVEPCN-3QanBmHE8Feg-bXba8buTc0u70AI9pg0AsszCopQQovuK7Sp4ndHrevAVxaEQaAo7Aa0bw",
        "kty": "RSA",
        "q": "tbFKE0CGGq8owQSpmxIhzI46Fz9HsyratciRJGPWn0AaIdyd6TsDg_RUX4zicc76SfiPM5IZyuvShqSx1degdThlXn66CNW05AlPjfKwthmxFRsu9GY8HQrA7W_LvFd3pxy6UX7QB5jn043iOIIafvQ_kM0J6pw7DHPHbd5I9XLGFnBb7zzNr4hpWlbQ6sBRbUqHnQqbsp8FlrGpMxHTPTIC2QFvqLRsDREo1i-Dyb6nngsY1gzCAUTOawcMZmxk4Blp_ulClHpCE2NWCLOch6AugY67Z_2ZQce7xO2tYetjkm0kyIx08lAmekreWQHyyoJlrjyvtR5kdty-EVX3Xw",
        "qi": "rSSuouvaNir80vm-DVQc_UwXjq84SOhrjy5WAxuHh4vlowA1KrxNvNzfwl2VVCWRa-4Y3qe-jl93odvllPpT4yM9Q63qzCK6pYayEYls-rYI6dKQRA6bFICwRIfuNGsGcQ21KFedoMGALecUOrC6wOgmC5WsiARR0JYVPyqsnYqVl9wiBSYmyNLm8B0CEjJuURLWpXG5cbnxYL5CUcRJ3a11VsSOpj5r6MOeJwX50HUEMEYw5SiujEBRSGgweRIKptIu-G9rPeII6QbmrmTT31qzzEPlyeBIW7Ek74FRpa8lJN0iYEVM_re6uT3vmaO428jo-3Zd_kIB2yegAEqlbg",
        "alg": "RS256"
      },
      {
        "d": "RDEUmyAmTHZ4_ZjLuvZBIgrCsznOmj3nuMld5X7cRqb6GlIOZ-DInA7nqbqW6kYclSW0Fn2gZmit3ZkiagNUmsLHTWP7NwGtRAbjIdBrtFyKV8-t8nQKpd-RNrM0yVr7NC9XWXBi7ZG0U5ho6e-RhDnVPb0JOfpeNUbmZ7X_sbXvWFXeZeguszmvitjafmXnFjzZFAXy_Vx4u7rUam7luYw1EpKeD4kQUiIY9YiH8o_KhH_3s4068y47rE6tZQ2haqTAxXBlR_1PU6JXZTL7gWzNdTL20fUUqW4vnipoxlilGRf5gMi00VK753epDoBFRGPHy6GL4G5_NK1TAduJoiaCU2-aYIxGXfQviGCEIAUlluuIJt1I5KdBBr8bNK5x0WjO8lc6plCjBbUPT75G22rGfEfQDe-1PPw3qZWe6_CC5125hO2K6_Vorr6xa457p7GZM3vku3N7ae_rq6Daf0noZDrIuxvJN8j8i9_7E-nmJ-SM4gTpMSSHoTou9qqpdNSHpLhWuGm2BMzIj8FvrksJusjhmoACOWe80mHc4FsK-MGerNm3wSmZkLogY5LhB44jJHsUlHw8ryGhvrSctw8Rw4Bc5kUbI17-3ECH7f-3BvHSQrWBrgl6Z0RS4alFTzAVIE9_OS845veSUNkL-aPZkdAm2PXN0XPBbhjREYE",
        "e": "AQAB",
        "use": "sig",
        "kid": "qeseal-Jnb0Lw",
        "x5c": [
          "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"
        ],
        "dp": "wCkpHLQ_OAK1CmxtdGWyJZZWq2SJZSrgDIScDI_c0XwjhEng-6QH9tBEfv68vEusdWkeiYv6R8qnPjnu7m_Jc4dBhO65hXCzTiHij4DXVMpyea5C3skfWwxWvxPL0t910_PHw1PICkkbBWf4xNb5jaLJuJYYl4_gOVG3mW1shjOyLuy2ODwTqtxJh2G1NjwfIVPc7AGVrhjV63EcbXunmwuw7r92qiPjs8VOEANpw0cevSy6ZRZA94ogG1p-TD-fLiJ7LhXXchrsRHk3ZAkk6V5xKfrlc2u2lGGeM18Ji6JS33_7JB8baUuaNjLcRznoMyLZqqsMDxmjWa3X42y_AQ",
        "dq": "LB_uS2Dulp1B0pGv0vkSVO_LvwBKA5flTkbQGq2vUdEKrRY59QC7uYNIxTr_RCqgBhtP4baXoKjbopdjrsERFs2O_8KGFfb57Z7nJsdAxYkGN7hDElaoVIgk3m3JBXKR7Viaup2oU49BdZmSSi1XEjuagrkojJ9ALcZbQd20T9QwHoiqQGVPfLD3_a6i6u-foTJxWeHxmtEW2WJucYQccg3QiB02nHB_xmO63Gy0D6pWpa5i040LAb-b9KzNZ2JCzGtToWLxRxXLzWCx6RraT7etvs4eEaaekdqXr0O4HyRJ2yWqXTjPeRddDsgiVDCdZWn5_TmGTGpuDhoiwH-m0Q",
        "n": "i3ZwmGZU3I9craBKCbbW8ra9r2W8TbgBRItYc1T1bU3njHvU6HdzsSm5HN2MsnH9lNthodusmPo-BukISyPqGHToeXSZ0taxOG0GIgtnc-k0qCG6BPwiXfMZTXRWF2e9FFX0lRF5b9b8Hq7IQ-BcME-Ub5LE8njGkOCLskncABOxWEL3utaA0nWJb1vLLBvwyl7y8gD_qr1Vohi36VafmmX5O1SAkon2_4xIkSbcd3pXMRQwcKYnhAYYIWE-r4mP86aVxmDcjpJ-FhQLRsaGxhNvjBIF1tM6WJYRwPwd8quL23O0wHulnYbiVt3JzjVpOa3kmAVdUQyMJfeDbsCrRDrWdqZMSNec74dKLgDT_N_dCPJzePTwSochfw1vn81Y23-fj0s3W6sCRN_OG-FyM_MxMMfpYYXrC1-IIOk155Ccv01k7XA2MzfiAOZmNUoUXB96Q945dzUw9rm19P1e8HAaQ2b--WfIRk_JNk2p0pd3Fhs0jjhqbwsOVuDnhu_-RAJYnVRDLiy2JFxwfsch48rYJ01AKJWu5CO83leOJ90Rk95buYw7dBHrWgGsEXBszqrRtNgEw0lmk2ld6QcWU8lmcIMVZ9a6TEGcqD_r9E-o1CJr67M5bhWJwh1lPG2MiH7XEEsw9Gc4LIXSWxUCfuu8lh_Qwm5oyHX6rnjOyhk",
        "p": "4NJ8xdsgvdVbPjvG0ohUSb7ngxX1XljLPV7g2vtKOZaCA0dRaPPzi7NYxEYtdYuhPSfL4FAovwRiBiXKg1I5oqBhKWNdnXpyNg-UAVTtA5dSktUPx-Wq57QuQ-fF-L1Hh2SF6zaHHtzaQyO_kKJSy44JVqYQu_ZPc9WFNL5v0e8lq3dJEkp-GA6SQr0T7OvXxXFnd4wuuTYONIigtzUcHAVRzE35BjDDMpGFZhXDC_78SlglhRW-sSbvkpW5io5-aulyqGeQ5BQHKccXmxgZF6I7j00RZTTEQoFdU5DXLHB0ayMAPPUaSggPN7SfYPztHvsoymxTCjCjJne1M7fpsQ",
        "kty": "RSA",
        "q": "ns2QpjahNpJhViuAar4V2Lkgy4HT6WvWz9aXAZJRXKYQAAM_gRBm8AtHVq39y4-0qIU-WThWBpYIiiZ-x2mEysGw9IWUNWFA0RXbeOgCp24vTWIUyVZ-2ZJPNkYdV77fowbG8NnGYOIgZvLeOoh-oV6fSLuGuxV2zmkAT_oDggujtDWLcbmJ4gjIK4FCdhGGRHbpe7r-vtX9R4Sfa1s1iTY3eQJtnvxgQUeEg828E28e2A-jzi0FsM4BPbnoKO7Lmb4KIcafrGzLfrpKFX3edxKpaIG9z4l22tF9LBs1Q7z8BxQf3k4Pmm1Yyy-d4NUIREICS1hc-uvRq-9BLsqY6Q",
        "qi": "3g_JRVk9TBBIw5An6jSM3av2lU7S8K0yL2XxpmiRuZYl52l2PSnHvxV7QmQpA0XDr0p8ECNL0UCkfBN6mAoyJ7nOBWZbO4M-Cp2WYaYo7TiWA1kShcyNqRVUxm8MtOWCtOBCXUmwskZeEdehmt3zyFuG-gKZxf4sW4mNCUXH0zjiORv-mOITF-HboJgd4kgzHoYzqwPS_gQIjdhTuexfHmuUXBzngmz2CcZRYek5lOrPPR2hFoDc4GZTi-Q7gLKU7rP-QLgbjz26jEGIZDzmKelE47g-nWOwWUK2XZX0MyoFCBsKFcWqnPGT4tUtgKFVGUNn8flE1HnaARkeK9mLpQ",
        "alg": "RS256"
      }
    ]
  },
  "tppId": "OP-SANDBOX-TPP-bcdc4df8-4804",
  "publicJwksUrl": "https://example.generated.tpp/OP-SANDBOX-TPP-bcdc4df8-4804/public-jwks.json"
}

The response contains everything you need for using PSD2 sandbox. See JWKS for more info on JWKs.

Some notes on each item:

FieldExplanationNote
privateJwksPrivate JWKs for your appContains a private JWKS for the generated TPP. It contains both RSA and EC keys and for both key types separate key for QWAC and QSEALC.
publicJwksUrlJWKS available to sandbox servicesThis URL contains the above public keys for our sandbox services. In other words, TPP's are NOT required to set up a published JWKS endpoint for testing. If the TPP does not create their own JWKS endpoint, this value must be passed on in the registration call (field software_jwks_endpoint).
tppIdThis is the generated TPP that has requested roles (by default AIS, PIS and CBPII). Note that this is the field org_id in registration SSA. This is also the organization identifier in the certificate without the PSD prefix.

Save this json response and extract the private jwks as you'll need the information to register as well as to sign requests. Your QWAC is the first certificate of the JWK x5c array.

Using the JWKS

It's recommended that you use a library that supports JWKS natively such as Nimbus JOSE in Java and panva/jose in NodeJS which have been tested to work well.

Refer to our example registration app on how to register.


TPP Registration

To access PSD2 APIs, TPPs must register with the account/payment service provider. Registration serves a number of purposes:

  • Delivering an API Key & Client Credentials to the TPP (Provided by OP Developer in sandbox)
  • Keeping track of the TPPs using PSD2 APIs
  • Submitting important security information, e.g. JWKS endpoints.

In sandbox as well as in production, the TPP must take the following actions:

  • Publish a publicly available JWK Set in standard JWKS Set format. If using a sandbox test certificate, you may use the publicJwksUrl received in the sandbox TPP generation response. Note: If you update the contents of the JWK Set, it will take roughly two hours to propagate to our systems.
  • Build the SSA (Software Statement Assertion) and sign it with a QSEALC/emulated signing key
  • Build the registration JWT, include the signed SSA JWT in it, and sign the registration JWT with the same QSEALC/emulated signing key
  • POST the registration JWT to the API.

Registration call

To register, you must construct, sign and and POST a JSON Web Token (JWT) to our TPP registration endpoint. While doing this, you must present your QWAC or, in sandbox, the equivalent certificate received from the certificate generation API.

POST /tpp-registration/register HTTPS/1.1
Host: mtls-apis.psd2-sandbox.op.fi
Content-Type: application/jwt
Accept: application/json
x-api-key: <APP_API_KEY> (Only required in sandbox)

eyJraWQiOiJTYW9lMVEiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE1OTY2MTgxNTUsImV4cCI6NDc1MjMxMDc1NSwiYXVkIjoiaHR0cHM6Ly9vcC5maS8iLCJqdGkiOiJhYmQ2ODY5NS1iNzViLTQxZDMtOWQ1YS0zYzI3N2M4YWVmNTUiLCJyZWRpcmVjdF91cmlzIjpbImh0dHBzOi8vdGVzdHRwcC5yZWRpcmVjdC51cmwiLCJodHRwczovL3Rlc3R0cHAucmVkaXJlY3QyLnVybCIsImh0dHBzOi8vdGVzdHRwcC5yZWRpcmVjdDMudXJsIl0sImdyYW50X3R5cGVzIjpbImNsaWVudF9jcmVkZW50aWFscyIsImF1dGhvcml6YXRpb25fY29kZSIsInJlZnJlc2hfdG9rZW4iXSwic29mdHdhcmVfc3RhdGVtZW50IjoiZXlKcmFXUWlPaUpUWVc5bE1WRWlMQ0poYkdjaU9pSkZVekkxTmlKOS5leUpwYzNNaU9pSlBVQzFVUlZOVUxWUlFVQzFpT1dFeE5UaGpOQzAyT0RBNElpd2lhV0YwSWpveE5UazJOakU0TVRVMUxDSmxlSEFpT2pRM05USXpNVEEzTlRVc0ltcDBhU0k2SWpsbU9EUXdaV1V6TFRnNFpUWXRORGcxWlMxaFpHSXlMV1F5TVdOaE9ERmlORGMyWXlJc0luTnZablIzWVhKbFgyTnNhV1Z1ZEY5cFpDSTZJalUxTlRrNE9HRmlMVEl6TXpBdE5HUXlaUzFoWkRrMExUbG1Oek5sTkdabU9XTmlaaUlzSW5OdlpuUjNZWEpsWDNKdmJHVnpJanBiSWxCSlV5SXNJa0ZKVXlJc0lrTkNVRWxKSWwwc0luTnZablIzWVhKbFgycDNhM05mWlc1a2NHOXBiblFpT2lKb2RIUndPaTh2Ykc5allXeG9iM04wT2pnNE9Ua3ZMbmRsYkd3dGEyNXZkMjR2WldOa2MyRXZhbmRyY3k1cWMyOXVJaXdpYzI5bWRIZGhjbVZmYW5kcmMxOXlaWFp2YTJWa1gyVnVaSEJ2YVc1MElqb2lhSFIwY0RvdkwyeHZZMkZzYUc5emREbzRPRGs1THk1eVpYWnZhMlZrTDJWalpITmhMMnAzYTNNdWFuTnZiaUlzSW5OdlpuUjNZWEpsWDJOc2FXVnVkRjl1WVcxbElqb2lkR1Z6ZEMxamJHbGxiblFpTENKemIyWjBkMkZ5WlY5eVpXUnBjbVZqZEY5MWNtbHpJanBiSW1oMGRIQnpPaTh2ZEdWemRIUndjQzV5WldScGNtVmpkQzUxY213aUxDSm9kSFJ3Y3pvdkwzUmxjM1IwY0hBdWNtVmthWEpsWTNReUxuVnliQ0lzSW1oMGRIQnpPaTh2ZEdWemRIUndjQzV5WldScGNtVmpkRE11ZFhKc0lsMHNJbk52Wm5SM1lYSmxYMk5zYVdWdWRGOTFjbWtpT2lKb2RIUndjem92TDNSd2NDNWpiMjBpTENKdmNtZGZibUZ0WlNJNklsUmxjM1FnVkZCUUlpd2liM0puWDJsa0lqb2lUMUF0VkVWVFZDMVVVRkF0WWpsaE1UVTRZelF0Tmpnd09DSXNJbTl5WjE5amIyNTBZV04wY3lJNlczc2libUZ0WlNJNklsUlFVQ0JEYjI1MFlXTjBJaXdpWlcxaGFXd2lPaUpwYm1adlFIUndjQzV2Y21jaUxDSndhRzl1WlNJNklpc3pOVGd4TWpNME5UWWlMQ0owZVhCbElqb2lVM1Z3Y0c5eWRDSjlYWDAuRURKZXRLQWduamVySEF5OFhlYkwwR2hKZWhwWXVWeGJGa3hlRmFuWlJHYk9uUkNDLU4xSUw1QU5MemcxOFQxa0VRdWhjMUw4R19JeXlFOWRZOFU3VHcifQ.IU5bJKu2ig1Vh07dK25MamEuqWgF0ohx4WQq9XQtWKSgXdgCvB8_G79bbUnNi0FJuZWf5pLW0ynxurZ6CCG_xQ

Client Registration Request

The registration request and software statement are signed with ES256 or RS256, using your QSEALC or generated signing key (in sandbox only).

Structure

{
  "kid": "Saoe1Q",
  "typ": "JWT"
  "alg": "ES256"
}
{
  "iat": 1596618155,
  "exp": 4752310755,
  "aud": "https://op.fi/",
  "jti": "abd68695-b75b-41d3-9d5a-3c277c8aef55",
  "redirect_uris": [
    "https://testtpp.com/redirect-url1",
    "https://testtpp.com/redirect-url2",
    "https://testtpp.com/redirect-url3"
  ],
  "grant_types": [
    "client_credentials",
    "authorization_code",
    "refresh_token"
  ],
  "software_statement": "eyJraWQiOiJTYW9lMVEiLCJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJPUC1URVNULVRQUC1iOWExNThjNC02ODA4IiwiaWF0IjoxNTk2NjE4MTU1LCJleHAiOjQ3NTIzMTA3NTUsImp0aSI6IjlmODQwZWUzLTg4ZTYtNDg1ZS1hZGIyLWQyMWNhODFiNDc2YyIsInNvZnR3YXJlX2NsaWVudF9pZCI6IjU1NTk4OGFiLTIzMzAtNGQyZS1hZDk0LTlmNzNlNGZmOWNiZiIsInNvZnR3YXJlX3JvbGVzIjpbIlBJUyIsIkFJUyIsIkNCUElJIl0sInNvZnR3YXJlX2p3a3NfZW5kcG9pbnQiOiJodHRwOi8vbG9jYWxob3N0Ojg4OTkvLndlbGwta25vd24vZWNkc2Evandrcy5qc29uIiwic29mdHdhcmVfandrc19yZXZva2VkX2VuZHBvaW50IjoiaHR0cDovL2xvY2FsaG9zdDo4ODk5Ly5yZXZva2VkL2VjZHNhL2p3a3MuanNvbiIsInNvZnR3YXJlX2NsaWVudF9uYW1lIjoidGVzdC1jbGllbnQiLCJzb2Z0d2FyZV9yZWRpcmVjdF91cmlzIjpbImh0dHBzOi8vdGVzdHRwcC5yZWRpcmVjdC51cmwiLCJodHRwczovL3Rlc3R0cHAucmVkaXJlY3QyLnVybCIsImh0dHBzOi8vdGVzdHRwcC5yZWRpcmVjdDMudXJsIl0sInNvZnR3YXJlX2NsaWVudF91cmkiOiJodHRwczovL3RwcC5jb20iLCJvcmdfbmFtZSI6IlRlc3QgVFBQIiwib3JnX2lkIjoiT1AtVEVTVC1UUFAtYjlhMTU4YzQtNjgwOCIsIm9yZ19jb250YWN0cyI6W3sibmFtZSI6IlRQUCBDb250YWN0IiwiZW1haWwiOiJpbmZvQHRwcC5vcmciLCJwaG9uZSI6IiszNTgxMjM0NTYiLCJ0eXBlIjoiU3VwcG9ydCJ9XX0.EDJetKAgnjerHAy8XebL0GhJehpYuVxbFkxeFanZRGbOnRCC-N1IL5ANLzg18T1kEQuhc1L8G_IyyE9dY8U7Tw"
}
FieldTypeDescription
algstringThe signing algorithm used. ES256 or RS256.
typstringType of the token. Always JWT.
kidstringHints at the key pair used with this signature. Helps the consumer fetch the right public key for validation.
iatnumber / integerThe time at which the JWT was issued. In epoch seconds.
expnumber / integerRequest expiration time. In epoch seconds.
audstringRequest audience (The ASPSP). Use value https://op.fi/.
jtistringJWT ID: a unique identifier for the ID. MUST be unique to prevent replay attacks.
redirect_urisarray / stringArray of whitelisted redirection URI strings for use in redirect-based flows (i.e. authorization code).
grant_typesarrayArray identifying the different grant types the TPP will use.
software_statementjwtSSA JWT signed by TPP in compact serialized format.

Software Statement Assertion

The Software Statement Assertion is a JWT created and signed by the TPP. It is signed with the TPP's QSEALC or the associated signing key received from OP's certificate generation service (only in sandbox). The signature is created using ES256 or RS256 algorithm and must match the registration request.

If you have a generated certificate, you may use the "publicJwksUrl" in the software_jwks_endpoint field: you don't need to set up a public JWKS endpoint to get started in the sandbox.

{
  "iss": "OP-SANDBOX-TPP-b9a158c4-6808",
  "iat": 1596618155,
  "exp": 4752310755,
  "jti": "9f840ee3-88e6-485e-adb2-d21ca81b476c",
  "software_client_id": "555988ab-2330-4d2e-ad94-9f73e4ff9cbf",
  "software_roles": [
    "PIS",
    "AIS",
    "CBPII"
  ],
  "software_jwks_endpoint": "http://testtpp.com/.well-known/ecdsa/jwks.json",
  "software_jwks_revoked_endpoint": "http://testtpp.com/.revoked/ecdsa/jwks.json",
  "software_client_name": "My Awesome APP",
  "software_redirect_uris": [
    "https://testtpp.com/redirect-url1",
    "https://testtpp.com/redirect-url2",
    "https://testtpp.com/redirect-url3"
  ],
  "software_client_uri": "https://tpp.com",
  "org_name": "Test TPP",
  "org_id": "OP-SANDBOX-TPP-b9a158c4-6808",
  "org_contacts": [
    {
      "name": "TPP Contact",
      "email": "info@testtpp.com",
      "phone": "+358123456",
      "type": "Support"
    }
  ]
}
FieldTypeDescription
issstringTPP ID.
iatnumber / integerThe time at which the JWT was issued. In epoch seconds.
expnumber / integerSSA expiration time. In epoch seconds.
jtistringJWT ID, e.g. 5e63fcae-0c46-4be3-bbf8-eb6eb9bb14a1.
software_client_idstringUnique Client ID of the software client. Format must be UUID, e.g. 2dc3102d-8f49-4c57-8de8-a63ccade3766
software_client_namestringHuman-readable name of the software client.
software_client_uristring / URIWebsite or resource root URI.
software_jwks_endpointstring / URIEndpoint that exposes all active signing public keys and certificates for the software. When you implement your own JWKS endpoint, ensure that it contains at least the JWK for validating registration JWT and the JWK for validating authorization JWT. Both of these JWKs MUST contain x5c with the QSEALC certificate. The contents of this endpoint must be in JWK Set format. For Sandbox, this field may contain the URI received during certificate generation.
software_jwks_revoked_endpointstring / URIEndpoint that contains all revoked JWKs for the software. Same format as software_jwks_endpoint.
software_redirect_urisarray / stringContains all redirect URIs for the software client.
software_rolesarray / stringPSD2 roles this software is authorized to perform.
org_idstringProduction: Unique ID for the software creator as assigned by a national competent authority. Must match the organizationId in the certificate, excluding the PSD prefix. Sandbox: The TPP ID received from the certificate generation service.
org_namestringLegal Entity Identifier or other known organisation name.
org_contactsarray / objectMandatory JSON array of objects containing a triplet of name, email, and phone number. At least email attribute is required in each array object. That address is used to inform TPP's about updates and service breaks etc.

Registration Response

Once successfully registered, you will receive a JSON response containing your client information. Keep the response secure, as it contains the client credentials for accessing PSD2 APIs.

Sample response body

{
    "client_id": "4vPsWdBi5d6G2dezEmfvh",
    "client_id_issued_at": 1552553405,
    "client_secret": "jqGQqZ6s6AXahdiMVFj9N",
    "client_secret_expires_at": 0,
    "api_key": "cGY7jn9z8Y141GZWMu6pNlCT0tfYlD6PM",
    "client_name": "software-client-1",
    "redirect_uris": [
        "https://localhost:8181",
        "https://tpp-demo-app.demo/oauth/access_token"
    ],
    "grant_types": [
        "client_credentials",
        "authorization_code",
        "refresh_token"
    ],
    "software_id": "6fdd0ca8-33f1-4b84-932a-c92e2f179bc8",
    "scope": "openid accounts payments",
    "jwks_endpoint": "https://example.tpp/jwks.url",
    "software_roles": [
        "AIS",
        "PIS"
    ]
}
Field NameTypeDescription
client_idstringClient ID of the TPP application.
client_id_issued_atDate / timestampTime of issuance of the client credentials. Seconds since Epoch.
client_secretstringClient secret of the TPP application.
api_keystringAPI Key of the TPP application. In sandbox, this is a replayed value as the API key has already been received from OP Developer.
redirect_urisarray -> string / URIRedirect URIs registered to the application.
grant_typesarray -> stringGrant types allowed to the application.
software_idstringYour registered application Software ID.
scopestringSpace-delimited list of scopes allowed to the application. Possible values: openid, accounts, payments, fundsconfirmations.
jwks_endpointstring / URIJWKS endpoint registered to the application.
software_rolesarray -> stringLicense-based roles registered to the application. Possible values: AISP, PISP, CBPII.

Verifying your registration

After registering successfully, you can verify the validity of your certificates and API key with the following cURL call (assuming you have AIS access):

curl -v --key key.pem --cert client.crt https://mtls-apis.psd2-sandbox.op.fi/accounts-psd2/v1/accounts -H "x-api-key: <your-api-key>"

If the certificates and API key are valid, you will receive a 401 response:

HTTP/1.1 401 Invalid authorization
Date: Mon, 02 Sep 2022 08:48:30 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 90
Connection: keep-alive
Set-Cookie: TSxxx=xxx; Path=/

Although the response is an error, it indicates that TLS has been established successfully and the API key has been accepted. Any other type of error signals an issue with either the API key or certificate.

If you received a 401 response similar to the sample above, you are ready to start working on authorization. See our workflow documentation for Account Information, Payment Initiation and Confirmation of Funds services.