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:
Certificate | Alt Name | Use |
---|---|---|
QWAC | MTLS cert/key | Transport Layer Security: Mutually authenticated TLS |
QSEALC | Signing cert/key | Digital 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 name | Explanation |
---|---|
c | Country as ISO 3166-1 Alpha 2 (e.g. FI). |
cn | Common name of the TPP company (e.g. "Brinklyfy.io"). |
roles | An 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:
Field | Explanation | Note |
---|---|---|
privateJwks | Private JWKs for your app | Contains 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. |
publicJwksUrl | JWKS available to sandbox services | This 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). |
tppId | This 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"
}
Field | Type | Description |
---|---|---|
alg | string | The signing algorithm used. ES256 or RS256. |
typ | string | Type of the token. Always JWT. |
kid | string | Hints at the key pair used with this signature. Helps the consumer fetch the right public key for validation. |
iat | number / integer | The time at which the JWT was issued. In epoch seconds. |
exp | number / integer | Request expiration time. In epoch seconds. |
aud | string | Request audience (The ASPSP). Use value https://op.fi/. |
jti | string | JWT ID: a unique identifier for the ID. MUST be unique to prevent replay attacks. |
redirect_uris | array / string | Array of whitelisted redirection URI strings for use in redirect-based flows (i.e. authorization code). |
grant_types | array | Array identifying the different grant types the TPP will use. |
software_statement | jwt | SSA 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"
}
]
}
Field | Type | Description |
---|---|---|
iss | string | TPP ID. |
iat | number / integer | The time at which the JWT was issued. In epoch seconds. |
exp | number / integer | SSA expiration time. In epoch seconds. |
jti | string | JWT ID, e.g. 5e63fcae-0c46-4be3-bbf8-eb6eb9bb14a1. |
software_client_id | string | Unique Client ID of the software client. Format must be UUID, e.g. 2dc3102d-8f49-4c57-8de8-a63ccade3766 |
software_client_name | string | Human-readable name of the software client. |
software_client_uri | string / URI | Website or resource root URI. |
software_jwks_endpoint | string / URI | Endpoint 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_endpoint | string / URI | Endpoint that contains all revoked JWKs for the software. Same format as software_jwks_endpoint. |
software_redirect_uris | array / string | Contains all redirect URIs for the software client. |
software_roles | array / string | PSD2 roles this software is authorized to perform. |
org_id | string | Production: 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_name | string | Legal Entity Identifier or other known organisation name. |
org_contacts | array / object | Mandatory 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 Name | Type | Description |
---|---|---|
client_id | string | Client ID of the TPP application. |
client_id_issued_at | Date / timestamp | Time of issuance of the client credentials. Seconds since Epoch. |
client_secret | string | Client secret of the TPP application. |
api_key | string | API Key of the TPP application. In sandbox, this is a replayed value as the API key has already been received from OP Developer. |
redirect_uris | array -> string / URI | Redirect URIs registered to the application. |
grant_types | array -> string | Grant types allowed to the application. |
software_id | string | Your registered application Software ID. |
scope | string | Space-delimited list of scopes allowed to the application. Possible values: openid, accounts, payments, fundsconfirmations. |
jwks_endpoint | string / URI | JWKS endpoint registered to the application. |
software_roles | array -> string | License-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.