Integrating a TPP with the Model Bank provided by OBIE

Open Banking (OB) offers the capability for TPPs to integrate with model banks -  Bank1 and Bank2. This model bank supports Open Banking Read/Write Standard v3.1.

Postman Collection

This allows the various authentication and authorisation flow to be tested and some basic AISP and PISP functionality to be executed, as per the OB specifications.

Postman can be used to test the flows and APIs out prior to building a TPP client. 

The steps below will help TPPs validate their setup and help better understand the various security flows required to integrate their own applications within the Open Banking ecosystem.

Ozone Model Bank Collection Files


OpenID Connect endpoints


All Versions

Accounts endpoints



Payment endpoints



Variable Recurring Payments (VRP) endpoints



Payment Debtor Test Accounts


Debtor Account


Debtor Account


1 2 3 4 5 6 { "SchemeName" : "UK.OBIE.SortCodeAccountNumber", "Identification" : "70000170000001", "SecondaryIdentification" : "Roll No. 001", "Name" : "Mr. Roberto Rastapopoulos & Mr. Mitsuhirato" }


1 2 3 4 5 { "SchemeName" : "UK.OBIE.SortCodeAccountNumber", "Identification" : "70000170000002", "SecondaryIdentification" : "Roll No. 002" }


1 2 3 4 5 { "SchemeName" : "UK.OBIE.IBAN", "Identification" : "GB29OBI170000170000001", "Name" : "Mario Carpentry" }


1 2 3 4 5 { "SchemeName" : "UK.OBIE.SortCodeAccountNumber", "Identification" : "70000170000004", "Name" : "Capone Consulting" }


1 2 3 4 5 { "SchemeName" : "UK.OBIE.SortCodeAccountNumber", "Identification" : "70000170000005", "Name" : "Octon Inc" }


1 2 3 4 5 { "SchemeName" : "UK.OBIE.SortCodeAccountNumber", "Identification" : "70000170000006", "SecondaryIdentification" : "Roll No. 002" }

Financial ID




Android APK

TPPs that want to test their app-to-app or web-to-app redirects can use the Ozone Android App.

The APK file can be downloaded from here.

Step-by-step guide

Step 1: Pre-Requisites (TPP)

Ensure that the following pre-requisites are met before onboarding onto Ozone.

  1. The TPP has registered on the Directory Sandbox

  2. The TPP has at least one software statement created on the Directory Sandbox environment

  3. The TPP has at least one transport certificate created for each of its software statements.

  4. The TPP has at least one redirect URI for each of its software statements.

  1. The TPP has a copy of the OB root and issuing certificate attached.

Step 2: Test TPP Transport Certificates (TPP)

Testing the well know endpoint below returns a json file which contains a list of endpoints.


One of these json endpoints is the token endpoint which you can use to validate your certificates. 

The TPP should run the following check to ensure that it has a valid certificate:

1 2 3 4 curl -cacert ca.pem -key {tpp-key-file} -cert {tpp-pem-file}

Here, tpp-key-file is the file that contains the TPPs private key and tpp-cert-file contains the transport certificate (downloaded from Sandbox).

This will return an error response but proves that your certificates are valid against the MATLS endpoint.
Here, the ca.pem file contains the Open Banking issuing and root certificate chained together into a single file.


Step 3: Setup TPP On Model Bank (TPP/Open Banking)

Ozone banks allow TPP to onboard via dynamic client registration

3.1 Dynamic Client Registration (TPP)


Claims required in dynamic client registration for Ozone Banks

Field Name

Example Values


Field Name

Example Values




Signature algorithm used JWK.


authorization_code, client_credentials



subject_type requested for responses to this client_id.



Kind of the application. The default if not specified is web. The defined values are native or web.


software statement id

The issuer must be your software ID. This is important as it's used verify it matches the SSA software ID claim.


All redirect Uris should be added in the claims



Requested authentication method for the Token Endpoint.



The audience must match the AS issuer ID. Modelo bank's issuer ID is:



‘openid and accounts' or 'accounts’

‘openid and payments' or 'payments’

‘openid,accounts and payments' or 'accounts and payments’

The scopes will depend on your role from the FCA (AISP and/or PISP):

  • AISP: openid and accounts

  • PISP: openid and payments

  • AISP and PISP: openid, accounts and payments

Refer to examples. Openid is optional










code, code id_token

JSON array containing a list of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code response type. See:



JWS alg algorithm


Since the SSA is essentially a JWT, you can decode it (for example, using

3.1.1 Example Registration Request JWT (Python)

This code is compatible with python 3.8 and requires the jwcrypto and requests modules (pip install jwcrypto requests)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import time, uuid from jwcrypto import jwt from jwcrypto import jwk # The software statement ID (software_id) of the software statement created in software statements (MIT). SOFTWARE_STATEMENT_ID = "" # Value of the kid parameter associated with the signing certificate generated in Generate a # transport/signing certificate pair (please note that you need to use the signing certificate kid). KID = "" # Your private signing key. You will use this to sign your JWT. PRIVATE_RSA_KEY = """ -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- """ # Software statement assertion (SSA), generated through DFI or Directory API SOFTWARE_STATEMENT = "" def make_registration_jwt(software_statement_id: str, kid: str, software_statement: str) -> str: jwt_iat = int(time.time()) jwt_exp = jwt_iat + 3600 header = dict(alg='PS256', kid=kid, typ='JWT') claims = dict( token_endpoint_auth_signing_alg="PS256", grant_types=["authorization_code", "client_credentials"], subject_type="public", application_type="web", iss=software_statement_id, redirect_uris=[""], # as registered in the software statement token_endpoint_auth_method="client_secret_basic", aud="0015800001041RHAAY", scope= "openid accounts payments", #accounts for AISP or payments for PISP or both request_object_signing_alg="none", exp=jwt_exp, iat=jwt_iat, jti=str(uuid.uuid4()), response_types=["code", "code id_token"], id_token_signed_response_alg="PS256", software_statement=software_statement ) token = jwt.JWT(header=header, claims=claims) key_obj = jwk.JWK.from_pem(PRIVATE_RSA_KEY.encode('latin-1')) token.make_signed_token(key_obj) signed_token = token.serialize() print(signed_token) return signed_token make_registration_jwt(SOFTWARE_STATEMENT_ID, KID, SOFTWARE_STATEMENT)

3.1.2 Request Registration Endpoint Example (Python): 

1 2 3 4 5 6 7 8 9 10 11 import requests headers = {'Content-Type': 'application/jwt'} client = ('./transport.pem', './transports.key') response ="", registration_request, headers=headers, verify=False, cert=client ) print(response.content)

The response you get from this registration is exactly the same as the one described by the OIDC dynamic registration.

You should now have successfully onboarded your TPP with the Modelo ASPSP and received a client ID; you will need this client ID for future interactions with the ASPSP.

3.1.3 Basic token acquisition (optional)

At this stage you should be able to acquire an access token using curl, where values for $CLIENT_ID and $CLIENT_SECRET are provided in the response from the DCR request.

1 2 3 4 5 6 curl --cacert ca.pem \ --request POST '' \ -u "$CLIENT_ID:$CLIENT_SECRET" \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=accounts openid' \ --key transport.key --cert transport.pem

Expected result:

1 {"access_token":"70123bf6-1111-4181-8353-4de543268d2b","token_type":"Bearer","expires_in":300}

3.1.4 Environment File download

Once a TPP successfully registers to Ozone, they can download the environment file for their client via an ozone helper api



Authorization: Basic <token>

The token is the base64 encoded string of clientId: clientsecret


On successful response, the TPP can then save the environment file to their local system.

You can accomplish the above using the following curl command:

1 2 3 4 5 CLIENT_ID='client_id' CLIENT_SECRET='client_secret' curl --cacert ca.pem --request GET '' \ -u "$CLIENT_ID:$CLIENT_SECRET" \ --key transport.key --cert transport.pem > $CLIENT_ID.postman_environment

Step 4: Import Environment Files and Collections To Postman (TPP)

4.1. Import Environment Files and Collections into Postman (TPP)


4.2) Check URLs and Environments are loaded successfully (TPP)

4.3) Add Client Certificates

Add the following Modelo and Referenco bank endpoints into Postman;

The CRT should be set to the transport certificate downloaded from the open banking directory. The Key value should be set to the private key for the transport certificate.

4.4) SSL Certificate Verification (TPP)

In Postman settings ensure SSL Certificate Verification is set to off.

Step 5: PSU Authenticate and Authorise(Open Banking and TPP)

  1. Client Credentials Grant (TPP)

  1. Account Access Consent(TPP)

  1. PSU Consent Flow(Open Banking and TPP)

TPPs can generate the consent flow URL by the postman

Once the URL is constructed, open the URL to initiate the PSU consent flow

Steps in  PSU Consent

a) Authenticate the user (Open Banking)

b) Select accounts (Open Banking)

  1. Once the PSU consent is successful, Ozone bank will redirect back to the redirect URI.

a) Copy the Authcode from the URL (Open Banking)

b) Generate the access token (TPP)

Step 5: Retrieve Account and Transaction Data (TPP)

  1. Retrieve Account Data

  1. Retrieve Transaction Data