Multi-Factor Authentication Handling

🚧

SDKs handle MFAs automatically

If you are using one of our SDKs, the MFA logic is already in-built and won't require any additional handling from you.

What is MFA?

Dapi API might require user confirmation to complete an operation. In Dapi API this is referred to as user input.

There are 5 types of input that could be requested from the user:

  • otp - This is either the OTP sent to the end user's device by the bank or an in app token in the user's bank app
  • secret_question - A set of questions set by the end user on a bank account
  • captcha - A captcha shown by the bank during bank operation
  • pin - Some bank accounts have hardware based device used to generate tokens for some bank operations
  • confirmation - Usually the user needs to open his app on the device to confirm an operation
  • token - An in app token similar to top.
  • multiple_choice - A set of multiple-choice questions.

📘

Sandbox bank for MFA testing

The bank DAPIBANK_AE_DAPI1 requests all types of user inputs in a row upon calling the /data/identity/get endpoint.

When is MFA required?

Confirmation can be required by any API endpoint. In other words, no matter which operation you are performing, we might require confirmation to complete it.

If user input is the API response will have the status user_input_required.

{
    "operationID": "47204fa6-dca6-44a5-8111-6c6489a232a2",
    "success": true,
    "status": "user_input_required",
    "userInputs": [
      {
        "answer": "", 
        "id": "otp", //type of the MFA
        "index": 0, //index of the OTP, required to maintain order in the list of MFAs
        "queryType":'txt', //format of the MFA - txt or img 
        "query": "Please enter a Smart Pass Token from your ENBD mobile application" //message to the user
      }
    ]
}

📘

queryType handling

  • queryType: txt --> the query field contains a string message.

  • queryType: img --> the query field contains a base64 encoded image string.


Example: multiple simultaneous user inputs

Dapi might request specification of more than one type of user input in a single request. If this is the case, userInputs returned in the response will contain more than one object. See example below:

{
    "operationID": "47204fa6-dca6-44a5-8111-6c6489a232a2",
    "success": true,
    "status": "user_input_required",
    "userInputs": [
    {
      "answer": "",
      "id": "otp",
      "index": 0,
      "queryType":'txt',
      "query": "Please enter a Smart Pass Token from your ENBD mobile application"
    },
     {
      "answer": "",
      "id": "pin",
      "index": 1,
      "queryType":'txt',
      "query": "Please enter your pin"
    }
    ]
}

Example: multiple choice (US only)

In the case of a multiple_choice MFA type, the response includes an additional queryOptionsList. This list contains all the options for the multiple-choice question. Every option has its content, type (img or txt), and index.

{
  "operationID": "DAPIBANK_US_CHASE:47204fa6-dca6-44a5-8111-6c6489a232a2",
  "success": true,
  "status": "user_input_required",
  "userInputs": [
    {
      "answer": "",
      "id": "multiple_choice",
      "index": 0,
      "query": "XXX-base64-string-for-picture-XXX",
      "queryType": "img", 
      "queryOptionsList": [
        {"content": "Red","type":"txt","index":0}, //Option 0
        {"content": "Yellow","type":"txt","index":1}, //Option 1
        {"content": "Green","type":"txt","index":2}, //Option 2 
       ]
    }
  ]
}

🚧

Different formats

Notice that the query and queryOptions can have different formats.

How to provide MFA answer?

The user input answer needs to be sent via replicating the original request.

If request to Get Balance responded with status user_input_required then follow-up request with the user input must be sent to Get Balance endpoint to continue the operation.

Here is an example for the same scenario:

Requesting Get Balance:

{
    "appSecret": "5e6a5c184cb15c5bbdca720da21a9dc1586d89789d44a77bb468efb095f1190c",
    "userSecret": "Tj56n40ZqoPepDpySGroisPRNpj/OO/ZI1QT90w/JKxVJtGgKiN05sEQRR/EMVTSlgH2ULt0SdrZcVQqPRheLZEgti6UHoy4aE/DvJ5QXiByLNE3Sx3Fohk4FPXJ5dew37saEUD7O3XdRZU2ZYDLJ5NZl+po92DJ4FQoxDj/MX2ttCnA7W5r358f0tbII/jE0j1kPdr7EEBadV8NAnIRzKp60/ASJeLtEvPCFRc1lpkYIT+Gm5GuXFUUWj9BWT1lvpAd3BYa1MCtOv3Bv6OvSNqAp7M24ZQBrkz6ItkHYRtus9UMqtaEqiPyiJiUAgwqpQmepuy/hKbdgNw7uEt7botiUrhEE+HzcISkh0Tlf/WpCU9x8vyWJLhtQTjJ7NQ1VTTob1weogni1koE5TwiaXlJTjghEQdCLg2xu/SMeWlgyiHMLjrLHhIUnKb7z8Et6U0gtpYds6Qb1TaUtU1Zwj8s+kl/q3z2qmAQc0qO0jD0uNJ0HX8jSl+lpjlMo0cGsb24sX6Hnhbqko5pNn2gnZtxXYVWXLg10IxKJYeGYWUh1iLIan6cVA7d1sfNLiMbKkvT9nP3+201tFJn6MTUTwvA453Q4z+Zba0UQkFkstfn9203N5rjSMrcx3LNv5uZT1CEHotRKZ9Xzagm7s+eKkRY9GCPxXkUZMqVMywNt8U=",
    "accountID": "yUZ3k5H6YRasdq1gf94fMrrMsOsnTDrB2uHm0JqEtq7Et2KbUO6ajpNN54E7KzGCcdBFcC4xYO8EbJGjIV7CWIlw==",
}

Get Balance response requiring userInput:

{
    "operationID": "47204fa6-dca6-44a5-8111-6c6489a232a2",
    "success": true,
    "status": "user_input_required",
    "userInputs": [
    {
      "answer": "",
      "id": "otp",
      "index": 0,
      "queryType":'txt',
      "query": "Please enter a Smart Pass Token from your ENBD mobile application"
    }
    ]
}

Sending the second request to Get Balance will need to include:

  • the standard Get Balance request body including appSecret, userSecret and accountID
  • userInputs list from the previous response with the answer field filled out
  • operationID from the previous response
{
    "appSecret": "5e6a5c184cb15c5bbdca720da21a9dc1586d89789d44a77bb468efb095f1190c",
    "userSecret": "Tj56n40ZqoPepDpySGroisPRNpj/OO/ZI1QT90w/JKxVJtGgKiN05sEQRR/EMVTSlgH2ULt0SdrZcVQqPRheLZEgti6UHoy4aE/DvJ5QXiByLNE3Sx3Fohk4FPXJ5dew37saEUD7O3XdRZU2ZYDLJ5NZl+po92DJ4FQoxDj/MX2ttCnA7W5r358f0tbII/jE0j1kPdr7EEBadV8NAnIRzKp60/ASJeLtEvPCFRc1lpkYIT+Gm5GuXFUUWj9BWT1lvpAd3BYa1MCtOv3Bv6OvSNqAp7M24ZQBrkz6ItkHYRtus9UMqtaEqiPyiJiUAgwqpQmepuy/hKbdgNw7uEt7botiUrhEE+HzcISkh0Tlf/WpCU9x8vyWJLhtQTjJ7NQ1VTTob1weogni1koE5TwiaXlJTjghEQdCLg2xu/SMeWlgyiHMLjrLHhIUnKb7z8Et6U0gtpYds6Qb1TaUtU1Zwj8s+kl/q3z2qmAQc0qO0jD0uNJ0HX8jSl+lpjlMo0cGsb24sX6Hnhbqko5pNn2gnZtxXYVWXLg10IxKJYeGYWUh1iLIan6cVA7d1sfNLiMbKkvT9nP3+201tFJn6MTUTwvA453Q4z+Zba0UQkFkstfn9203N5rjSMrcx3LNv5uZT1CEHotRKZ9Xzagm7s+eKkRY9GCPxXkUZMqVMywNt8U=",
    "accountID": "yUZ3k5H6YRasdq1gf94fMrrMsOsnTDrB2uHm0JqEtq7Et2KbUO6ajpNN54E7KzGCcdBFcC4xYO8EbJGjIV7CWIlw==",
    "operationID": "47204fa6-dca6-44a5-8111-6c6489a232a2",
    "userInputs": [
        {
            "answer": "123456",
            "id": "otp",
            "index": 0,
            "queryType":'txt',
            "query": "Please enter a Smart Pass Token from your ENBD mobile application"
        }
    ]
}

If user input was valid, API will return success response of the endpoint that requested confirmation. Meaning, after specifying user input for GetBalance endpoint, if successful you will receive user balance information in the response.

📘

Note

API might request user input several times in a row. In other words, once you submit the user input, API might follow up with new type of input to be specified again before performing the operation.

How to format the MFA answer?

For otp, secret_question, captcha, pin, confirmation and token you simply need to populate the answer field with the value that is given to you by the user.

For multiple_choice type the answer has to be the index number of the item that was chosen from the queryOptionsList.