Open Banking
The Wise Open Banking API is aimed for Financially Regulated Third Party Providers who can prove their regulatory status either by being a member of the Open Banking Directory or possessing an eIDAS Certificate. Third Parties or individuals who do not meet these requirements are welcome to check out our Public API.
The Wise Open Banking API is a collection of RESTful APIs that enable Third Party Providers (TPPs) to access account information, initiate payments and confirm availability of funds on behalf of Wise customers. The API implementation follows the Open Banking UK standard, and Wise is a registered member of the Open Banking Directory.
Through this API you can either query account information, if you're an Account Information Service Provider (AISP), initiate payments, if you're a Payment Initiation Service Provider (PISP), or confirm the availability of funds, if you're a Card Based Payment Instrument Issuer (CBPII). We are currently supporting version 3.1.1 of the Open Banking API.
https://openbanking.sandbox.transferwise.tech
https://openbanking.transferwise.com
We offer our bespoke Connected Applications API as a secondary API, acting as a contingency mechanism. The Connected Applications API provide the same set of functionality for both AISPs and PISPs as our Open Banking API does. In order to avoid any delays in switching over to the contingency mechanism during a major outage of the Open Banking API, we encourage TPPs to preemptively seek out registration to our contingency mechanism by reaching out to openbanking@wise.com and specifically requesting access to the contingency mechanism.
There's a couple of things you should be aware of in order to connect to the Wise Open Banking API:
- Being a registered TPP under the Open Banking Directory will ease the integration process.
- We are using mutualTLS as the means for authentication. Moreover, the
CN
of your client certificate is expected to match theclientId
under which you are registered. - You need to register your client, before you'll be able to call any of the APIs. Check out the Sandbox Access first.
For a detailed description of requirements and supported algorithms please check out the Well-Known Open Banking URL.
https://sandbox.transferwise.tech/openbanking/.well-known/openid-configuration
https://wise.com/openbanking/.well-known/openid-configuration
If you're a registered TPP at the Open Banking Directory you can simply use our Dynamic Client Registration endpoint to self-onboard your organization using the Software Statement Assertion issued by the Open Banking Directory.
Confirmation of Payee clients
In case you're looking to onboard a Confirmation of Payee (CoP) client please make sure to include the cop
scope into the list of requests scopes. The list of requested scopes should be:
"scope": "openid openbanking payments cop"
https://openbanking.sandbox.transferwise.tech/open-banking/v3.3/register
https://openbanking.transferwise.com/open-banking/v3.3/register
We highly recommend that you get started with connecting to our sandbox first, before moving on to production. To get started with the registration process drop us an email to openbanking@wise.com.
Open Banking Directory
If you're a registered TPP in the Open Banking Directory you will probably be using a Signing and a Transport certificates issued by Open Banking. The accepted Open Banking certificates are the eIDAS-like OBWAC and OBSeal certificates.
Legacy Open Banking Transport and Signing certificates are no longer supported after 30 June 2021.
You can easily onboard by providing a Software Statement Assertion (SSA) generated in the Open Banking Directory.
Please make sure to have your list of Redirect Uri-s correctly configured in your Software Statement, otherwise you'll not be able to go through the whole flow.
eIDAS Certificates
In case you're using an eIDAS certificates instead of the ones issued by the Open Banking Directory just contact us at openbanking@wise.com to see how we can move forward.
You can sign up for a test user account here https://sandbox.transferwise.tech/register. The 2FA code used for any subsequent logins to the sandbox will alway be 111111
.
You'll be asked to set up a developer account by filling in your profile information. Once this is done, you'll see that your newly created profile comes with a couple of test accounts opened and some test funds in them.
You do NOT need to create an API Token via the web interface in case your intention is to use this test user for the Open Banking flow.
After you've successfully applied for the Sandbox Access and you've set up a Sandbox Test User you are ready to test the Open Banking flow. For the purpose of this test flow let's assume that your TPP is an AISP and it's registered with the following details
Client ID | Redirect URI | Authorized Scopes |
---|---|---|
ob-dummy-tpp | https://ob-dummy-tpp/redirect | accounts |
As a first step you'll need to request an access token from the Token Endpoint.
Request
POST https://openbanking.sandbox.transferwise.tech/open-banking/auth/token
Field | Description | Format |
---|---|---|
grant_type | OAuth Grant Type | client_credentials |
scope | The requested scopes | Space separated list |
client_id | The client ID in accordance with RFC8705 | Text |
You must include the requested scope in your token request. As an AISP your requested scope will be accounts
.
Response
Field | Description | Format |
---|---|---|
access_token | The access token | Text |
expires_in | Expiration time in seconds | Long |
scope | The scopes you have been given access to | Text |
curl -X POST \https://openbanking.sandbox.transferwise.tech/open-banking/auth/token \--cacert CA.pem --cert client.pem --key client.key \-H 'Content-Type: application/x-www-form-urlencoded' \-d 'grant_type=client_credentials&scope=accounts&client_id=ob-dummy-tpp'
{"access_token": "abcd1234-abcd-1234-abcd-abcdef123456","token_type": "bearer","expires_in": 6000,"scope": "accounts openbanking"}
POST https://openbanking.sandbox.transferwise.tech/open-banking/v3.1/aisp/account-access-consents
Using the access-token
returned from Creating an Access Token you can create a new consent object. Use the authorization header:
Authorization: Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
The payload of this request will look different depending on whether you're an AISP, PISP or CBPII. For an AISP you'll need to specify a set of permissions describing the access that you wish to gain on behalf of the end user.
Permissions
For AISPs the list of supported permissions is:
- ReadAccountsBasic
- ReadAccountsDetail
- ReadBalances
- ReadTransactionsBasic
- ReadTransactionsCredits
- ReadTransactionsDebits
- ReadTransactionsDetail
- ReadDirectDebits
Response
The response will be JSON data reflecting the newly created consent object. There are two important return values to highlight here.
Data.Status
will containAwaitingAuthorisation
because this consent has not been authorized by the user yet.Data.ConsentId
will contain the unique identifier assigned to your consent object. Save this, as you'll need it later.
curl -X POST \https://openbanking.sandbox.transferwise.tech/open-banking/v3.1/aisp/account-access-consents \--cacert CA.pem --cert client.pem --key client.key \-H 'Authorization: Bearer abcd1234-abcd-1234-abcd-abcdef123456' \-H 'Content-Type: application/json' \-d '{"Data": {"Permissions": ["ReadAccountsBasic", "ReadTransactionsBasic", "ReadTransactionsDebits"]}}'
{"Data": {"Status": "AwaitingAuthorisation","ConsentId": "123"}}
At the moment we are only supporting the browser redirect flow (Hybrid Flow) for authorizing the created consent.
The customer journey will start from the TPPs website from where a user action will trigger a redirect to the Wise Open Banking Authorization Endpoint
GET https://sandbox.transferwise.tech/openbanking/authorize
Parameter | Required | Description |
---|---|---|
response_type | Mandatory | code id_token |
redirect_uri | Mandatory | One of the pre-registered redirect URIs |
scope | Mandatory | Must include openid plus any requested scope |
client_id | Mandatory | Pre-registered clientId of the TPP |
request | Mandatory | JWT Request Object |
state | Optional | If present, it must also be present in the JWT |
nonce | Optional | If present, it must also be present in the JWT |
You can take a look at the example JWT request object on the right. Please note that:
- Every request parameter sent in the URL must also be present in the signed JWT.
- The
aud
claim should be correctly filled ashttps://openbanking.sandbox.transferwise.tech
- The
openbanking_intent_id
must be filled with a validConsentId
issued to the TPP. - The JWT must be signed with a valid signing certificate.
Once the TPP redirects the user browser to the Authorization Endpoint the following things will happen in order:
- User Login (use the username and password from the Test User Registration)
- Pass 2FA challenge (User the code
111111
in sandbox) - Select profile you wish to give access to (Business or Personal)
- Review and Authorize Consent
- Redirect back to TPP
As part of the last step, the user browser is redirected to the TPP with the following parameters
Parameter | Required | Description |
---|---|---|
code | Mandatory | The authorization_code issued as the request of the request |
id_token | Mandatory | Signed JWT containing details about the authorization |
state | Optional | In case it was provided with the request |
Note that in case the authorization request fails either because of a validation error on the request, or because the enduser drops off, we still redirect the user browser to the TPP with an error response of the following format:
Field | Description | Format |
---|---|---|
error | Error code according to RFC6749 | Text |
error_description | Detailed explanation of error | Text |
https://sandbox.transferwise.tech/openbanking/authorize?response_type=code%20id_token&redirect_uri=https://ob-dummy-tpp/redirect&scope=openid%20accounts&client_id=ob-dummy-tpp&state=state123&nonce=nonce123&request=eyJ0...sYjmjJg
{"kid": "er84c2cYa6dAe57BV3278Pf","alg": "PS256","typ": "JWT"},{"scope" : "openid accounts","response_type" : "code id_token","sub" : "user_id","claims" : {"id_token" : {"openbanking_intent_id" : {"essential" : true,"value" : "123"},"acr" : {"values" : ["urn:openbanking:psd2:sca","urn:openbanking:psd2:ca"],"essential" : true}},"userinfo" : {"openbanking_intent_id" : {"value" : "123","essential" : true}}},"iss" : "ob-dummy-tpp","client_id" : "ob-dummy-tpp","aud" : "https://openbanking.sandbox.transferwise.tech","exp" : 2499287201,"iat" : 2499283601,"max_age" : 86400,"redirect_uri" : "https://ob-dummy-tpp/redirect"}
Once you get the authorization code
after the browser redirect, you'll have to call the Token Endpoint to exchange this for a valid access token.
Request
POST https://openbanking.sandbox.transferwise.tech/open-banking/auth/token
Field | Description | Format |
---|---|---|
grant_type | OAuth Grant Type | authorization_code |
redirect_uri | Pre-registered redirect Uri | URI |
code | Authorization Code | Text |
client_id | The client ID in accordance with RFC8705 | Text |
Response
Field | Description | Format |
---|---|---|
access_token | The access token | Text |
expires_in | Expiration time in seconds | Long |
scope | The scopes you have been given access to | Text |
refresh_token | Refresh Token for refreshing access token | Text |
curl -X POST \https://openbanking.sandbox.transferwise.tech/open-banking/auth/token \--cacert CA.pem --cert client.pem --key client.key \-H 'Content-Type: application/x-www-form-urlencoded' \-d 'grant_type=authorization_code&redirect_uri=https%3A%2F%2Fob-dummy-tpp%2Fredirect&code=abcdauthcode&client_id=ob-dummy-tpp'
{"access_token": "zzzzzzzz-1111-2222-3333-zzzzzzzzzzzz","token_type": "bearer","refresh_token": "refreshr-efre-shre-fres-hrefreshrefr","expires_in": 6000,"scope": "accounts consent-id:123 openbanking openid"}
With the access-token
from Authorization Code Flow used in the Authorization header, you'll be able to query the data endpoints.
Authorization: Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
curl -X GET \https://openbanking.sandbox.transferwise.tech/open-banking/v3.1/aisp/accounts \--cacert CA.pem --cert client.pem --key client.key \-H 'Authorization: Bearer zzzzzzzz-1111-2222-3333-zzzzzzzzzzzz' \
{"Data": {"Account": [{"AccountId": "504","Currency": "GBP","AccountType": "Personal","AccountSubType": "EMoney","Account": [{"SchemeName": "UK.OBIE.SortCodeAccountNumber","Identification": "230xxx1000xxxx","Name": "John Smith (GBP)"}],"Servicer": {"SchemeName": "UK.OBIE.BICFI","Identification": "TRWIGB22"}}]}}
POST /open-banking/auth/token
The Token Endpoint supports the grant types: client_credentials
, authorization_code
and refresh_token
. Every request made to the Token Endpoint should include the client_id
request parameter as described by RFC6749, this helps us bind the client certificate used for the request with your client_id.
Accounts
Querying the accounts endpoint will return all open currency accounts of the consented user.
GET /open-banking/v3.1/aisp/accounts
GET /open-banking/v3.1/aisp/accounts/{id}
Note: Not every multi-currency account opened in Wise has a unique set of local bank details attached to it. Therefore, it's expected that some of the currency accounts returned will have an empty OBReadAccount3/Data/Account/Account
. We encourage AISPs to instead use the unique ID OBReadAccount3/Data/Account/AccountId
for identifying different accounts. There's nothing inherently different between accounts with and without bank details, you can call the Balances and Transactions endpoints for either of them. Note: These endpoints are also available for v3.1.11 (simply replace v3.1 with v3.1.11 in the URL).
Balances
Querying the balances endpoint will return the current balance of each supported currency.
GET /open-banking/v3.1/aisp/accounts/{id}/balances
Note: This endpoint is also available for v3.1.11 (simply replace v3.1 with v3.1.11 in the URL).
Transactions
Querying the transactions endpoint will return a list of transactions from within the consented time window. If the consent associated with the request is recent (less than 90 days old), we will allow requests to fetch transactions as old as you like. If however the consent is older than 90 days, we will only allow requests to fetch transactions up to 90 days old no matter what the requested/consented time frames are. Results are paginated, with a link to the next page being available inside the Links
object.
GET /open-banking/v3.1/aisp/accounts/{id}/transactions
We are fully transparent about our transaction charges, so you will find fees attached to transactions in either of the following ways:
- Embedded [DEFAULT]: Using the
OBReadTransaction5/Data/Transaction/ChargeAmount
object. Fees represented this way will be embedded into the transactions amount. This might make sense for most AISPs. - Fee Split : Showing fees as separate DEBIT transactions with an attached reference to the original transaction. Fees represented this way will not be embedded in the original transaction amount. This might make sense for some AISPs, like account software providers.
Note: This endpoint is also available for v3.1.11 (simply replace v3.1 with v3.1.11 in the URL). The v3.1.11 version should return a list of transactions that is more in line with what the users see in their balance statements. Be aware of the fact that the IDs of the transactions returned by the v3.1.11 version are different from the ones returned by the v3.1 version. However, you should be able to reconcile the vast majority of the new and old transactions simply by matching the Ids contained in the supplementaryData
fields of each of them.
Direct Debits
Querying the direct debits endpoint will return the list of set up direct debits on a specific account
GET /open-banking/v3.1/aisp/accounts/{id}/direct-debits
Every consent object created for initiating payments will have a CutOffDateTime
attached which is set to be 30 minutes after the creation of the consent. After the 30 minutes have lapsed, the Payment Order creation will be rejected.
We are supporting both UK.OBIE.SortCodeAccountNumber
as well as UK.OBIE.IBAN
for account identification.
At the moment we are only able to pass on a single reference to the debtor, which is Initiation/RemittanceInformation/Reference
if present, or Initiation/EndToEndIdentification
otherwise. The accepted size of the reference field varies based on the currency of the transfer. For EUR transfers you'll be able to leverage the full length of 35 characters of this field, however for GBP transfers this field length is restricted to a maximum of 18 characters. The reason for this restriction is also detailed in OB Payment Message Format Mapping. In case of FPS, this field gets mapped to both ISO8583 Field 62 as well as Field 120.
Domestic Payments
POST /open-banking/v3.1/pisp/domestic-payments
GET /open-banking/v3.1/pisp/domestic-payments/{id}
The Domestic Payments endpoint can be used to initiate same currency transfers. You can initiate domestic payments in any of the supported currencies by Wise, assuming the consenting user already holds an open account in the requested currency.
International Payments
POST /open-banking/v3.1/pisp/international-payments
GET /open-banking/v3.1/pisp/international-payments/{id}
The International Payments endpoint can be used to initiate transfers where the source currency is different than the target currency. You can use it to initiate a payment with:
Fixed Source Amount :
OBInternational2/InstructedAmount/Currency
andOBInternational2/CurrencyOfTransfer
are different.- The source currency and amount are specified using
OBInternational2/InstructedAmount
. The currency can be any of the supported currencies by Wise, assuming the consenting user already holds an open account in the requested currency. - The target currency of the transfer is specified using
OBInternational2/CurrencyOfTransfer
. The instructed amount will be converted to the CurrencyOfTransfer and sent out to the specified CreditorAccount.
- The source currency and amount are specified using
Fixed Target Amount :
OBInternational2/InstructedAmount/Currency
andOBInternational2/CurrencyOfTransfer
are the same.- The source currency of the transfer can either be specified using
OBInternational2/ExchangeRateInformation/UnitCurrency
, or it can be left unspecified, allowing the Wise customer to choose one of his eligible currency accounts during the Authorization Flow. The customer's choice of source currency, the exchange rate used, and any additional charges are clearly communicated to the customer as well as reflected to the TPP via the Payment Resource. - The target currency and amount are specified using
OBInternational2/InstructedAmount
.
- The source currency of the transfer can either be specified using
We are only supporting INDICATIVE ExchangeRateInformation
during the creation of the International Payment Consent. The real exchange rate used, along with any fees will be clearly communicated to the customer during the consent authorization, as well as reflected to the PISP during the creation of the International Payment Resource.
POST /open-banking/v3.1/cbpii/funds-confirmations
The confirmation of funds endpoint can be used to check whether the consented user has a specific amount on any of its opened currency accounts.
As part of regular maintenance or other special cases client certificates need to be changed from time to time. Depending on your integration type you might be able to do this in an automated or a manual way.
Open Banking Directory Participants
- OBWAC/OBSeal certificates are automatically added to your JWKS resource endpoints and you should be able to use your new certificates automatically as soon as they get associated with your Software Statement in the Directory.
- eIDAS certificates are treated similarly to OBWAC/OBSeal certificates as long as the issuing and root certificates haven't changed. If any certificate in your eIDAS trust chain has changed, you'll need to reach out to openbanking@wise.com for a manual update.
Other Participants
In case you're not an Open Banking Directory Participant we will only be able to update your certificates manually. Please reach out to openbanking@wise.com well ahead of your previous certificate becoming invalid to allow for enough time for our support team to handle your request.
The latest version of our Open Banking performance and availability report can be found here.