Example - Phone OTP

This is a walkthrough of how to use phone as an authentication method for SCA including setting it up for your end customers.

Wise provides three methods for delivering one-time password (OTP) codes to your end-user devices.

  1. SMS
  2. WhatsApp
  3. Voice

Please note that you will be responsible for managing the lifecycle of the phone number, so that Wise can send one-time password (OTP) codes to your end customers when necessary.

LifecycleDescription
CreateAfter successfully onboarding a customer and verifying their phone number through your application, you should the respective phone number on Wise.
UpdateIf customer updated their phone number, update the respective phone number on Wise.
DeleteIf customer has removed or lose access to the phone number, delete the respective phone number on Wise.

Once an end customer's phone number is set up. It can now be used as an authentication factor to clear an SCA challenge.

Image below illustrates the interaction between Partner and Wise.

Phone Based OTP Verification Flow

Steps

  1. Partner makes an HTTP call to get balance account statement which is a SCA protected endpoint.
Get Balance Account Statement - Request
curl -X GET https://api.sandbox.transferwise.tech/v1/profiles/{{profileId}}/balance-statements/{{balanceId}}/statement.json \
?currency=EUR \
&intervalStart=2023-01-01T00:00:00.000Z \
&intervalEnd=2023-01-15T23:59:59.999Z \
&type=COMPACT \
-H 'Authorization: Bearer <your api token>'
  1. Wise rejects the request with status 403 Forbidden. Please see the example response on the right.
Get Balance Account Statement - Response
HTTP/1.1 403 Forbidden
Date: Wed, 06 Dec 2023 08:57:34 GMT
x-2fa-approval: bb676aeb-7c4d-4930-bb55-ab949fd3fd87
x-2fa-approval-result: REJECTED
...other headers
  1. Partner gets status of a one time token to get all required challenges to clear this OTT.
Get Status of One Time Token - Request
curl -X GET https://api.sandbox.transferwise.tech/v1/identity/one-time-token/status \
-H 'Authorization: Bearer <your api token>' \
-H 'One-Time-Token: bb676aeb-7c4d-4930-bb55-ab949fd3fd87'
  1. Wise returns one time token that describes all required challenges.

    For the complete list of challenges available please refer to ChallengeType.

The 'alternatives' field suggests that the end user has the option to select a trigger channel to receive the OTP code, rather than receiving it via the default channel.

Get Status of One Time Token - Response
{
"oneTimeTokenProperties": {
"oneTimeToken": "bb676aeb-7c4d-4930-bb55-ab949fd3fd87",
"challenges": [
{
"primaryChallenge": {
"type": "SMS",
"viewData": {
"attributes": {
"userId": 6146956
}
}
},
"alternatives": [
{
"type": "WHATSAPP",
"viewData": {
"attributes": {
"userId": 6146956
}
}
},
{
"type": "VOICE",
"viewData": {
"attributes": {
"userId": 6146956
}
}
}
],
"required": true,
"passed": false
}
],
"validity": 3600,
"actionType": "BALANCE__GET_STATEMENT",
"userId": 6146956
}
}
  1. Partner verify otp by passing OTT acquired in step 2.
Verify SMS - Request
curl -X POST https://api.sandbox.transferwise.tech/v1/one-time-token/sms/verify \
-H 'Authorization: Bearer <your api token>'
-H 'One-Time-Token: <one time token>'
-d '{
"otpCode": "111111"
}'
  1. Wise returns one time token properties after a successful OTP code verification.
    • Assuming that the challenges array field is empty, indicating that the OTT is now usable.

    • If you are unsure, you can always get status of a one time token again.

    • It is possible that the challenges array returns type of challenge. In that case, please perform the verification flow as written in our guides.

Verify SMS - Response
{
"oneTimeTokenProperties": {
"oneTimeToken": "9f5f5812-2609-4e48-8418-b64437c0c7cd",
"challenges": [],
"validity": 3600
}
}
  1. Partner calls Get Balance Statement with the approved OTT.
Get Balance Account Statement - Request
curl -X GET https://api.sandbox.transferwise.tech/v1/profiles/{{profileId}}/balance-statements/{{balanceId}}/statement.json \
?currency=EUR \
&intervalStart=2023-01-01T00:00:00.000Z \
&intervalEnd=2023-01-15T23:59:59.999Z \
&type=COMPACT \
-H 'Authorization: Bearer <your api token>' \
-H 'x-2fa-approval: bb676aeb-7c4d-4930-bb55-ab949fd3fd87'
  1. Wise returns Balance Account Statement.
Get Balance Account Statement - Response
{
"accountHolder": {
"type": "PERSONAL",
"address": {
"addressFirstLine": "Veerenni 24",
"city": "Tallinn",
"postCode": "12112",
"stateCode": "",
"countryName": "Estonia"
},
"firstName": "Oliver",
"lastName": "Wilson"
},
"otherFields": "..."
}