How to integrate the Twizo Verification widget

Integration the Twizo verification widget to add 2FA to your website is really simple. In this tutorial we will explain step-by-step how you can do it.

Integrating the Twizo verification widget is done in 3 simple steps:

  1. Create a verification session.
  2. Open the verification widget.
  3. Verify if the verification session was successful.

Let’s explain the steps in more detail.

Twizo Logo

Step 1: Create a verification session

You start by creating a verification session. When doing that you can set certain parameters like which verification types you want to support, the phone number of the user, token length and type, etc. When the session is created you get a sessionToken. The sessionToken is needed to open the widget.

Example how to create a verification session:

            curl -X POST https://api-<?php echo $region; ?>-01.twizo.com/v1/widget/session \
            -H "Accept: application/json" \
            -H "Content-Type: application/json; charset=utf8" \
            -u "twizo:&lt;API_KEY>" \
            -d '{
                "allowedTypes" : ["sms","call"],
                "recipient" : "601234500000"
            }'

            $widgetSession = $twizo->createWidgetSession(array('sms','call'));
            $widgetSession->setRecipient('601234500000');
            $widgetSession->create();



Check our API documentation to see all options you can set when creating a verification session.

You will get a response like this:

{
"sessionToken": "<?php echo $region; ?>-01_1161130_wid59003566562fe8.59122114e17b",
"applicationTag": "Default application",
"bodyTemplate": "Your verification token is %token%",
"createdDateTime": "2017-04-26T05:51:34+00:00",
"dcs": null,
"issuer": null,
"language": null,
"recipient": "601234500000",
"sender": "Twizo",
"senderNpi": null,
"senderTon": null,
"tag": null,
"tokenLength": 6,
"tokenType": "numeric",
"requestedTypes": [
    "sms",
    "call"
],
"allowedTypes": {
    "1": "sms",
    "2": "call"
},
"validity": null,
"status": "no status",
"statusCode": 0,
"backupCodeIdentifier": null,
"verificationIds": [],
"verification": null,
"_links": {
    "self": {
        "href": "https:\/\/api-<?php echo $region; ?>-01.twizo.com\/v1\/widget\/verification\/session\/<?php echo $region; ?>-01_1161130_wid59003566562fe8.59122114e17b"
        }
    }
}

You will need to use the sessionToken you can find in the response and pass it to the widget, see step 2.

Step 2: Open the widget

Now let’s open the widget. You need to include widget.js into your html page and open the widget to show it to the user. Apart from the session token you can do some additional settings like the logo you want to show and the recipient number where the token is sent to.

If malicious people were able to capture the sessionToken, the privacy of the user is still protected. Only if they have the sessionToken and the API key, they are able to collect e.g. the phone number of the user. So always make sure you keep your API key in a safe place.

The URL of the widget.js is:

https://cdn.twizo.com/widget.js

Javascript code to open the widget:

const handler = TwizoWidget.configure({
    sessionToken: sessionToken
});

handler.open(function (sessionToken, isError, errorCode, returnData) {
    if (isError) {
        //verification failed, user should not be logged in
        alert('error: ' + errorCode);
    } else {
        //verification success, user can continue to login
        alert('success for sessionToken: ' + sessionToken);
    }
});

The options you can set for the widget are:

ParameterDescription
sessionTokenThis is a mandatory parameter. The sessionToken of the verification session you created.
logoUrlThis is an optional parameter. If you want to personalise the widget, you can set a URL to your logo here. We will reduce the size of the logo to 200 pixels wide and 90 pixels high.

Please note, as the widget is using HTTPS, the link to the logo must be HTTPS as well. See HTTPS for more information.

recipientThis is an optional parameter. If you set it, the widget will show it to the user to indicate where the token will be sent to. For privacy reasons we recommend not to specify the full number but e.g. only the last 4 digits. So instead of showing ‘61123456789’ show ‘***6789’.
askTrustedThis is an optional parameter. Possible values are true or false. When it is set to true, the widget will show a checkbox, by default selected, with the text ‘Trust this device for x days’. The x will be replaced with the number you fill in for ‘trustedDays’. When the widget is closed, the return data contains a property isTrusted indicating if the checkbox was selected or not.
trustedDaysThis is a mandatory parameter when askTrusted is set to true. You can specify the number to be shown in the sentence ‘Trust this device for x days’.

For security reasons we have set a maximum number of retries for the verification and a maximum time of the session. This to prevent users will perform unlimited unsuccessful verifications. The maximum retries is 5 and the maximum session time is 10 minutes.

When the user completed the verification flow, either by entering the correct token, cancelling, reaching maximum number of retries or reaching the maximum session time, the widget will be closed and you will get the sessionToken, isError (true or false), an errorCode (when isError == true) and returnData returned. The returnData will contain the isTrusted property when askTrusted is set to true.

The errorCodes property can be one of the following error codes:

errorCodeDescription
When isError is true and the errorCode is empty (”) the user aborted the widget.
101Verification already verified.
104Verification failed, please contact your administrator
200Verification already used
201Verification timeout
202Max attempts reached
301Invalid request
310Verification failed, unable to start new verification
311Verification failed, unable to start new verification as the session is already verified or failed
312Verification failed, unable to start new verification as the session has been expired
313Verification failed, unable to start new verification as the max attempts has been reached

Step 3: Verify if the verification session was successful

When the widget returned the isError == false the user entered the correct token. However to make sure the verification was indeed successful, you can get the status of the verification session. It is not mandatory to get the status of the session after the widget is closed, but we highly recommend this. Even though we have implemented the widget is a secure way, there are always ways for malicious people to, for example, influence the DOM.

Example how to get the status of the verification session:

            curl https://api-<?php echo $region; ?>-01.twizo.com/v1/widget/session/&lt;SESSION_TOKEN>?recipient=&lt;RECIPIENT> \
            -H "Accept: application/json" \
            -H "Content-Type: application/json; charset=utf8" \
            -u "twizo:&lt;API_KEY>"

            $result = $twizo->getWidgetSession($widgetSession->getSessionToken(), $widgetSession->getRecipient());



Note: to get the status of a session, you need to specify the sessionToken and the recipient number. You need to specify both as the API will check the combination so that malicious people cannot return a successful sessionToken of a different user.

You will get a response like this:

{
"sessionToken": "<?php echo $region; ?>-01_1161130_wid59003566562fe8.59122114e17b",
"applicationTag": "Default application",
"bodyTemplate": "Your verification token is %token%",
"createdDateTime": "2017-04-26T05:51:34+00:00",
"dcs": null,
"issuer": null,
"language": null,
"recipient": "601234500000",
"sender": "Twizo",
"senderNpi": null,
"senderTon": null,
"tag": null,
"tokenLength": 6,
"tokenType": "numeric",
"requestedTypes": [
    "sms",
    "call"
],
"allowedTypes": {
    "1": "sms",
    "2": "call"
},
"validity": null,
"status": "success",
"statusCode": 0,
"backupCodeIdentifier": null,
"verificationIds": [
    "<?php echo $region; ?>-01-1.17172.ver583d6255ae66f2.27354409",
    "<?php echo $region; ?>-01-1.18352.ver529c5e45ae72a2.83645283"
],
"verification": {
        "applicationTag": "Default application",
        "bodyTemplate": null,
        "createdDateTime": "2017-04-26T05:51:34+00:00",
        "dcs": null,
        "issuer": null,
        "language": null,
        "messageId": "<?php echo $region; ?>-01-1.18352.ver529c5e45ae72a2.83645283",
        "reasonCode": null,
        "recipient": "601234500000",
        "salesPrice": 0.07,
        "salesPriceCurrencyCode": "eur",
        "sender": null,
        "senderNpi": null,
        "senderTon": null,
        "sessionId": "<?php echo $region; ?>-01_1161130_wid59003566562fe8.59122114e17b",
        "status": "success",
        "statusCode": 1,
        "tag": null,
        "tokenLength": null,
        "tokenType": null,
        "type": "sms",
        "validity": null,
        "validUntilDateTime": null,
        "webHook": null,
        "_links": {
            "self": {
                "href": "https:\/\/api-<?php echo $region; ?>-01.twizo.com\/v1\/verification\/submit\/<?php echo $region; ?>-01-1.18352.ver529c5e45ae72a2.83645283"
            }
        },
"_links": {
    "self": {
        "href": "https:\/\/api-<?php echo $region; ?>-01.twizo.com\/v1\/widget\/verification\/session\/<?php echo $region; ?>-01_1161130_wid59003566562fe8.59122114e17b"
        }
    }
}

The status field will show the status, in this case ‘success’. When it is success you can continue to login the user, otherwise you can logout the user so he needs to login and do the verification again. For more information on the possible status codes, please check the API documentation.

That’s it! These are all the steps you need to do to integrate our verification service into your application to enable 2FA.