Guides • Build Banking Apps
Initiate your first payment

Initiate your first payment

This tutorial walks you through the steps to initiate a domestic-payment.

Similar steps apply to all of our payments endpoints. Therefore, after you complete this tutorial, you will know how to use all the payments endpoints.

See the Open Banking API: Payment initiation for all the supported payments.

Before you begin, ensure that you have:

  • Registered your application with the payments scope in Developer Portal
  • Obtained a sandbox/production client_id from Developer Portal
  • Obtained sandbox/production transport.pem and signing.pem certificates, from Developer Portal or QTSP issuing body
  • Uploaded the jwks_url in Developer Portal that is specific to your transport.pem certificate. Ensure that the x5c claim is specified.

1. Generate a client credentials token

Get access token

curl --cert transport.pem --key private.key \
--location --request POST 'https://oba-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=payments' \
--data-urlencode 'client_id=<your client_id>'

Response:

{
"access_token": "<JWT client credentials>",
"token_type": "Bearer",
"expires_in": 2399
}

Request an access token for client credentials using the /token endpoint and the client_credentials grant type.

You use this token to:

x-jws-signature header:

{
"alg": "PS256",
"kid": "<insert kid>",
"crit": ["http://openbanking.org.uk/tan"],
"http://openbanking.org.uk/tan": <insert JWKs root domain>
}

Create a consent:

curl --location --request POST 'https://oba.revolut.com/domestic-payment-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert JWT client credentials from step 1.>' \
--header 'x-jws-signature: <insert JWS signature>' \
--data '
{
"Data": {
"Initiation": {
"InstructionIdentification": "ID412",
"EndToEndIdentification": "E2E123",
"InstructedAmount": {
"Amount": "55.00",
"Currency": "GBP"
},
"CreditorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "11223321325698",
"Name": "Receiver Co."
},
"RemittanceInformation": {
"Reference": "ReceiverRef",
"Unstructured": "Shipment fee"
}
}
},
"Risk": {
"PaymentContextCode": "EcommerceGoods",
"MerchantCategoryCode": "5967",
"MerchantCustomerIdentification": "1238808123123",
"DeliveryAddress": {
"AddressLine": ["7"],
"StreetName": "Apple Street",
"BuildingNumber": "1",
"PostCode": "E2 7AA",
"TownName": "London",
"Country": "UK"
}
}
}

Response:

{
"Data": {
"Status": "AwaitingAuthorisation",
"StatusUpdateDateTime": "2020-11-20T08:35:53.523806Z",
"CreationDateTime": "2020-11-20T08:35:53.523806Z",
"ConsentId": "6686e444-c103-4077-8085-8e094200c425",
"Initiation": {
"InstructionIdentification": "ID412",
"EndToEndIdentification": "E2E123",
"InstructedAmount": {
"Amount": "55.00",
"Currency": "GBP"
},
"CreditorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "11223321325698",
"Name": "ReceiverCo."
},
"RemittanceInformation": {
"Reference": "ReceiverRef",
"Unstructured": "Shipmentfee"
}
}
},
"Risk": {
"PaymentContextCode": "EcommerceGoods",
"MerchantCategoryCode": "5967",
"MerchantCustomerIdentification": "1238808123123",
"DeliveryAddress": {
"AddressLine": [
"7"
],
"StreetName": "AppleStreet",
"BuildingNumber": "1",
"PostCode": "E27AA",
"TownName": "London",
"Country": "UK"
}
},
"Links": {
"Self": "https://oba.revolut.com/domestic-payment-consents/6686e444-c103-4077-8085-8e094200c425"
},
"Meta": {
"TotalPages": 1
}
}

Create a consent to initiate a domestic payment on behalf of a Revolut customer.

When you create the consent, ensure that you

  • Use your client_credentials token from the previous step in the Authorization field.
  • Pass x-jws-signature header in the API request that contains a detached JWS signature of the body of the payload. The signature must be generated from the request body with the TPP signing key that is specified in the JWS header.
  • Pass the head and signature in <jws_head>..<jws_signature> format.
  • Specify the x-idempotency-key field so that when there is a network failure and you do not receive the ID from the response, you can retry the request.

3. Create a JWT URL parameter

After you create a consent, you need the users to authorize the consent so that you can initiate a payment on their behalf.

Header

{
"alg": "PS256",
"kid": "<insert kid>"
}

Body

{
"response_type": "code id_token",
"client_id": "<insert client_id>",
"redirect_uri": "<insert redirect_uri>",
"scope": "payments",
"claims": {
"id_token": {
"openbanking_intent_id": {
"value": "<insert ConsentId>"
}
}
}
}

Create a JWT request parameter with the header and body format on the right, signed by your signing certificate's private key. This signature is validated using the JWKs endpoint that you specified during the registration of your application.

caution

The values of client_id, redirect_uri, kid, and scope should correspond to those for your specific application and consent request.

The value of openbanking_intent_id is the value of the ConsentId field generated from the previous step.

Sample URL:

https://oba.revolut.com/ui/index.html?response_type=code%26id_token&scope=accounts&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT from step 3.>

Redirect the user to the authorization URL with the following parameters.

ParameterDescriptionRequired
response_typeAlways set to code&id_token.yes
client_idThe client ID for your application.yes
redirect_uriOne of the redirect URIs that you defined during the application creation.yes
scopeThe scope that you are requesting, for example, accounts or payments.yes
requestThe encoded JWT generated from the previous step.yes
response_modeIf set to fragment parameters will be passed in fragment section of redirect URI. Otherwise, parameters are passed in URI query. Passing parameters in fragment is considered to be more secure.no

Sample redirect after successful response

https://www.revolut_redirect.com/?code=oa_sand_sPoyVs-oMhyR36j5N-ZEVLfK9rQWPNssgIQqsOFZQ-c&id_token=<JWT id_token>&state=state

On successful completion of the authorization flow, you receive an authorization code (code) as a URL parameter in the redirect.

Check the response example on the right to see what the code looks like.

note

The code is valid only for two minutes.

5. Exchange authorization code for access token

Exchange for access token

curl  --key private.key --cert transport.pem \
--location --request POST 'https://oba-auth.revolut.com/token' \
--header 'Content-Type:application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode'code=<insert auth_code>'

Response

{
"access_token":"oa_sand_tP1Nofi1ixsRfBmVBtVPdIVN0J5x91imqmheQIWTS5s",
"token_type":"Bearer",
"expires_in":7775999,
"id_token":"<JWT id_token>"
}

After the user authorize your consent, you use the /token endpoint with grant_type=authorization_code to get the access token to use the /domestic-payments endpoint.

note

The value of auth_code is the authorization code (code) generated from the previous step.

6. Initiate a domestic payment

Create a domestic payment:

curl --location --request POST 'https://oba.revolut.com/domestic-payments' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert access_token from step 5.>' \
--header 'x-jws-signature: <insert JWS signature>' \
--data '
{
"Data": {
"ConsentId": "<insert ConsentId>"
"Initiation": {
"InstructionIdentification": "ID412",
"EndToEndIdentification": "E2E123",
"InstructedAmount": {
"Amount": "55.00",
"Currency": "GBP"
},
"CreditorAccount": {
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "11223321325698",
"Name": "Receiver Co."
},
"RemittanceInformation": {
"Reference": "ReceiverRef",
"Unstructured": "Shipment fee"
}
}
},
"Risk": {
"PaymentContextCode": "EcommerceGoods",
"MerchantCategoryCode": "5967",
"MerchantCustomerIdentification": "1238808123123",
"DeliveryAddress": {
"AddressLine": ["7"],
"StreetName": "Apple Street",
"BuildingNumber": "1",
"PostCode": "E2 7AA",
"TownName": "London",
"Country": "UK"
}
}
}

Response:

{
"Data": {
"DomesticPaymentId": "dd817a13-3198-48ca-a5dc-f22b09ee82c0",
"Status": "AcceptedSettlementInProcess",
"StatusUpdateDateTime": "2020-11-20T08:54:30.115047Z",
"CreationDateTime": "2020-11-20T08:54:30.115047Z",
"ConsentId": "6686e444-c103-4077-8085-8e094200c425",
"Initiation": {
"CreditorAccount": {
"Name": "ReceiverCo.",
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "11223321325698"
},
"InstructedAmount": {
"Amount": "55.00",
"Currency": "GBP"
},
"RemittanceInformation": {
"Reference": "ReceiverRef",
"Unstructured": "Shipmentfee"
},
"EndToEndIdentification": "E2E123",
"InstructionIdentification": "ID412"
}
},
"Links": {
"Self": "https://oba.revolut.com/domestic-payments/dd817a13-3198-48ca-a5dc-f22b09ee82c0"
},
"Meta": {
"TotalPages": 1
}
}


After you generate this access token, you can initiate a domestic payment on the user's behalf. Make a call to the /domestic-payments endpoint to initiate the payment.

Congratulations! You have successfully initiated your first payment.

What's next

Was this page helpful?