Authorisation

🚧

Single Payment

There are a few different payments that you can make with the Moneyhub API. In this guide we are keeping it simple and doing a single immediate payment. If you wish to make other types of payments see this section of our documentation: Payments

To make a payment we must create an Authorisation Request. This is quite an involved step that requires these actions:

  1. Construction of an Authorisation URL which is then given to your user.
  2. Users give their consent to this process and sign in to whichever financial institution we are connecting to.
  3. A code is generated and must be exchanged to finalise the process

Lets walk through these steps now with an example.

Authorisation Requests

You are going to be making a request to the identity server (https://identity.moneyhub.co.uk) and
POST /oidc/request

πŸ“˜

Pushed Authorisation Request

What you are about to make is called a PAR or pushed authorisation request. You have a number of ways to make an authorisation request, but find that this is the most straightforward for all languages. More information can be found here: PAR

Assertion

To authenticate ourselves when you make this request, the body of the request takes two parameters:

client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion=<JWT Explained Below>

For client_assertion above you will need to generate a JWT signed by your private JWKS. As mentioned in creating a client guide, your JWT library should allow all this functionality. Your JWT needs to have these properties:

{
  "iss": "your client id",
  "sub": "your client id",
  "jti": "A unique identifier for the token, which can be used to prevent reuse",
  "aud": "our token endpoint, i.e.(https://identity.moneyhub.co.uk/oidc/token)",
  "iat": "the time at which the token was issued",
  "exp": "the time at which the token will expire"
}

You may find that your JWT library handles values like jti, iat, exp for you automatically.

Claims

When creating an authorisation URL, you need to specify a set of claims that gives extra information on how the payment will be made.

🚧

Basic Claims

This guide aims to cover the basics, and because of this wont go into detail about the large amount of claims you can pass into an auth request. If you want more information and a deeper dive visit this section of our docs: Payment Claims

A claim request is simply a JSON object that describes what information you wish to request. All our claims we support currently belong to the id_token. Here are the claims you will use:

{
  "id_token": {
    "mh:con_id": { // This states you want the connection ID returned in the resulting ID Token
      "essential": true
    },
			"mh:payment": {
				"essential": true,
				"value": {
					"payee": { // You can specify payee details here
						"accountNumber": "12345678",
						"sortCode": "123456",
						"name": "Mr Payee"
					},
					"payeeType": "api-payee",
					"amount": 150,
					"payeeRef": "Payee reference",
					"payerRef": "Payer reference"
				}
			}
  }
}

This is all that is needed for our basic PIS auth request.

πŸ“˜

Creating a Payee

We offer 2 ways to make a payee for payments. The simplest of which is demonstrated above, you pass in payee details in a payee claim.

You could instead use our POST /payee endpoint and create a payee this way, passing in a payeeIdto the claims. Documentation on payees can be found here: Payees

Scopes

The final important area of the auth request body is the scopes. We use scopes to both describe the access the user is granting and the way in which you would like the user to identify themselves.

πŸ“˜

All The Scopes

You will only use basic scopes for this guide, but if you want to see a list of all the scopes you can provide visit this documentation: Scopes

For this request you want to simply have the user connect to a test bank:

scope=payment openid id:test

This asks for 3 scopes payment, openid and id:test.

payment scope is required for payments, and describes this auth request as a payments request.

openid scope is a required scope that simply states you will be using the OpenID Connect interface.

id:testscope is the financial institution you want to connect to. In this case id:test indicates you would like to display a list of test banks for the user who is consenting to choose from. You could instead pass id:{bank_id}with a specific bank id to skip this choice.

πŸ“˜

Choose A Specific Bank

In our example above you are passing in id:test for the bank you want to connect to. If you wanted to choose a specific bank you would need to pass in a bankId.

Bank Ids are a way for us to differentiate between the different financial institutions you can connect to. These can be found here: Connections

For more information on bank connections see this documentation page: Banks

Creating The Auth Request

Lastly you need to also provide some identity and security information.

  • client_id - This is your clientId
  • redirect_uri - This is one of your previously defined redirect URIs from the client configuration. This is where the consent journey will end once the user has consented, passing the code to be exchanged.
  • response_type - This is the previously defined response type from the client configuration. In your case thats: code id_token
  • state - This is a security value that can prevent attacks such as CRSF. In this example it will need to contain something for payments API to work.
  • nonce - This is a security value that can prevent replay attacks. In this example it can be blank

Let's put this all together now in the final combined request to the Authorisation Request endpoint:

curl --location --request POST 'https://identity.moneyhub.co.uk/oidc/request' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={}' \
--data-urlencode 'redirect_uri={}' \
--data-urlencode 'response_type={}' \
--data-urlencode 'state=test' \
--data-urlencode 'scope=openid id:test' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion={Your JWT}' \
--data-urlencode 'claims={
    "id_token": {
      "mh:con_id": {
        "essential": true
      },
			"mh:payment": {
				"essential": true,
				"value": {
					"payee": {
						"accountNumber": "12345678",
						"sortCode": "123456",
						"name": "Mr Payee"
					},
					"payeeType": "api-payee",
					"amount": 150,
					"payeeRef": "Payee reference",
					"payerRef": "Payer reference"
				}
			}
    }
	}'

You should get a successful response that looks something like this:

{
	"request_uri": "urn:ietf:params:oauth:request_uri:m4enL-UeWzej6eEqT-NeC",
	"expires_in": 1691571826
}

This value can be used to construct the auth URL:

https://identity.moneyhub.co.uk/oidc/auth?request_uri=urn:ietf:params:oauth:request_uri:m4enL-UeWzej6eEqT-NeC

What’s Next

Lets finalise the payment next.