Tutorials

Verification

In this tutorial we will show you in 2 steps how you can integrate our verification API into your website to enable 2FA.

When somebody creates a user for your website, you ask in most cases for his name and email. For integrating our verification service you will need to ask for his mobile number as well. Now when the user logs in to your website, you ask for his username and password. If the entered credentials are correct our verification service will start to kick in.

With the following code you will send a verification token to the users’ mobile and you will show a simple form where he can enter the received token.

<?php

require_once(__DIR__ . '/../vendor/twizo/api/autoload.php');

$phoneNumber = '1234567890'; //Dummy phone number, replace it with the number of the user
$apiKey = '<Your API-key>'; //Put your API key here
$apiHost = 'api-asia-01.twizo.com'; //Choose the API location you prefer
//$apiHost = 'api-eu-01.twizo.com';

//Create twizo object
$twizo = Twizo\Api\Twizo::getInstance($apiKey, $apiHost);

//Config verification
$verification = $twizo->createVerification($phoneNumber);

try {
    //Request verification
    $verification->send();

    //Form for requesting the sent token
?>
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="form-style">
    <h1>Verification</h1>
    <form name="form-verification" method="POST" action="post-verification.php">
        <input type="hidden" name="message-id" value="<?= $verification->getMessageId();?>" />
        <input type="text" name="token" required="required" placeholder="Your received token" />
        <input type="submit" value="Verify token" />
    </form>
    </div>
</body>
<?php
} catch (\Exception $ex) {
    print 'The verification request has failed, Error: ' . $ex->getMessage();
}

The form will look like this:

Now the user can enter the token and submits the form. It will call the following script which will verify the entered token and shows the result to the user.

<?php

require_once(__DIR__ . '/../vendor/twizo/api/autoload.php');

$apiKey = '<Your API-key>'; //Put your API key here
$apiHost = 'api-asia-01.twizo.com';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['message-id']) && isset($_POST['token']) && strlen($_POST['message-id']) > 0 && strlen($_POST['token']) > 0) {
        //Create twizo object
        $twizo = Twizo\Api\Twizo::getInstance($apiKey, $apiHost);

        //Check if token is valid
        $isTokenValid = $twizo->verifyToken($_POST['message-id'], $_POST['token']); //Boolean
?>
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="result-style">
<?php
        if ($isTokenValid) {
            echo '<h1>Verification successful!</h1>';
        } else {
            echo '<h1>Verification failed!</h1>';
        }
?>
    </div>
</body>
<?php
    }
}

When the token is correct you will see this:

That’s it! Now you have verified the user and the user can continue to your website. You can find these sample files on GitHub.

Phone number structure

When you want to send a verification, SMS or Number Lookup, you have to specify a phone number. The phone number must be in E.164 number format but without leading +. This format is the internationally-standardised format for all phone numbers.

So when you are located in Singapore and you want to send a verification to a Singaporean number, you will have to include the country prefix to the number. Example: when the Singaporean number is 081234567, you will have to prepend the country prefix of Singapore, +65, to the mobile number, but without the leading +. So 6581234567. For a good reference on the country prefixes, check Wiki here .

Unicode

For normal SMS messages the body is in GSM-7 alphabet and can contain the characters as specified in the GSM 0.038 specification . If you want to send other characters you will need to send the SMS as Unicode. You will need to set the DCS to 8. For normal messages the DCS is 0. The maximum length for Unicode messages is not 160 characters as for normal messages but 70 characters. If you want to send longer Unicode messages you will need to use the concatenated SMS functionality. See Concatenated/long messages for more details. For our Advanced SMS API you will need to consider the maximum body length and set the DCS to 8 for Unicode messages. However our Simple SMS API can do that for you. It will automatically detect if the message is Unicode, set the DCS to 8 and split up into maximum 9 concatenated parts.

Concatenated/long messages

The maximum length for normal SMS messages is 160 characters and for Unicode 70 characters. If you want to send longer messages, you will need to split up the body of the message by sending each body part of the message separately and adding a UDH (See also GSM specification for more information). The maximum length for normal messages will then be 154 characters per body part and for Unicode 67 characters per body part. You can set all these settings in our Advanced SMS API. However our Simple SMS API can do that for you. It will automatically detect if the message is Unicode and split up into maximum 9 concatenated parts. Example of a long message using our Simple SMS API:
$data = array(
    'recipients' => array(
        '1234567890',
    ),
    'body' => 'This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message.',
    'sender' => '1234567890',
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api-asia-01.twizo.com/v1/sms/submitsimple");
curl_setopt($ch, CURLOPT_USERPWD, 'twizo' . ':' . '<api-key>');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen(json_encode($data)))
);

$response = curl_exec($ch);

curl_close($ch);

//show the output in a pretty format
$json = json_decode($response);
echo json_encode($json, JSON_PRETTY_PRINT);
$data = array(
    'recipients' => array(
        '1234567890',
    ),
    'body' => 'This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message.',
    'sender' => '1234567890',
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api-eu-01.twizo.com/v1/sms/submitsimple");
curl_setopt($ch, CURLOPT_USERPWD, 'twizo' . ':' . '<api-key>');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen(json_encode($data)))
);

$response = curl_exec($ch);

curl_close($ch);

//show the output in a pretty format
$json = json_decode($response);
echo json_encode($json, JSON_PRETTY_PRINT);
Will result in:
{
    "_links": {
        "self": {
            "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submitsimple"
        }
    },
    "_embedded": {
        "items": [
            {
                "applicationTag": "Default application",
                "body": "This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a",
                "callbackUrl": null,
                "createdDateTime": "2016-11-30T06:35:35+00:00",
                "dcs": 0,
                "messageId": "asia-01-1.23690.sms583e73377e8a15.07921055",
                "networkCode": null,
                "pid": null,
                "reasonCode": null,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "scheduledDelivery": null,
                "sender": "1234567890",
                "senderNpi": 1,
                "senderTon": 1,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "timestamp": null,
                "udh": "050003870200",
                "validity": 259200,
                "validUntilDateTime": "2016-12-03T06:35:35+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01.twizo.com\/v1\/sms\/submitsimple\/asia-01-1.23690.sms583e73377e8a15.07921055"
                    }
                }
            },
            {
                "applicationTag": "Default application",
                "body": " long message.",
                "callbackUrl": null,
                "createdDateTime": "2016-11-30T06:35:35+00:00",
                "dcs": 0,
                "messageId": "asia-01-1.23690.sms583e73377fec89.66143881",
                "networkCode": null,
                "pid": null,
                "reasonCode": null,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "scheduledDelivery": null,
                "sender": "1234567890",
                "senderNpi": 1,
                "senderTon": 1,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "timestamp": null,
                "udh": "050003870201",
                "validity": 259200,
                "validUntilDateTime": "2016-12-03T06:35:35+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-asia-01-twizo.com\/v1\/sms\/submitsimple\/asia-01-1.23690.sms583e73377fec89.66143881"
                    }
                }
            }
        ]
    },
    "total_items": 2
}
{
    "_links": {
        "self": {
            "href": "https:\/\/api-eu-01.twizo.com\/v1\/sms\/submitsimple"
        }
    },
    "_embedded": {
        "items": [
            {
                "applicationTag": "Default application",
                "body": "This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a long message, This is a",
                "callbackUrl": null,
                "createdDateTime": "2016-11-30T06:35:35+00:00",
                "dcs": 0,
                "messageId": "eu-01-1.23690.sms583e73377e8a15.07921055",
                "networkCode": null,
                "pid": null,
                "reasonCode": null,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "scheduledDelivery": null,
                "sender": "1234567890",
                "senderNpi": 1,
                "senderTon": 1,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "timestamp": null,
                "udh": "050003870200",
                "validity": 259200,
                "validUntilDateTime": "2016-12-03T06:35:35+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-eu-01.twizo.com\/v1\/sms\/submitsimple\/eu-01-1.23690.sms583e73377e8a15.07921055"
                    }
                }
            },
            {
                "applicationTag": "Default application",
                "body": " long message.",
                "callbackUrl": null,
                "createdDateTime": "2016-11-30T06:35:35+00:00",
                "dcs": 0,
                "messageId": "eu-01-1.23690.sms583e73377fec89.66143881",
                "networkCode": null,
                "pid": null,
                "reasonCode": null,
                "recipient": "1234567890",
                "resultType": 0,
                "salesPrice": null,
                "salesPriceCurrencyCode": null,
                "scheduledDelivery": null,
                "sender": "1234567890",
                "senderNpi": 1,
                "senderTon": 1,
                "status": "no status",
                "statusCode": 0,
                "tag": null,
                "timestamp": null,
                "udh": "050003870201",
                "validity": 259200,
                "validUntilDateTime": "2016-12-03T06:35:35+00:00",
                "_links": {
                    "self": {
                        "href": "https:\/\/api-eu-01-twizo.com\/v1\/sms\/submitsimple\/eu-01-1.23690.sms583e73377fec89.66143881"
                    }
                }
            }
        ]
    },
    "total_items": 2
}

Sender

With the sender ID you can set where the SMS comes from. So you can set for example your mobile number or your company name as the sender. There are two types of sender IDs:
  • Numeric
  • Alphanumeric
Our API can automatically detect the type of sender ID and sets the parameters senderTon and senderNpi automatically. However if you want you can set them yourselves as that is possible as well. When you do not set the senderTon and senderNpi, or set it to ‘null’, the API will automatically detect the sender. The auto detection rules are:
  • if the sender doesn’t contain only digits -> Alphanumeric (senderTon = 5, senderNpi = 0)
  • else if the sender starts with one 0 -> Numeric national (senderTon = 2, senderNpi = 1)
  • else if the sender length <= 6 digits -> Numeric national (senderTon = 2, senderNpi = 1)
  • else Numeric international (senderTon = 1, senderNpi = 1)
Example:
$data = array(
    'recipients' => array(
        '1234567890',
    ),
    'body' => 'Body of the SMS',
    'sender' => '1234567890',
);
Will result in:
"sender": "1234567890",
"senderTon": 1,
"senderNpi": 1,
When you set the senderTon and senderNpi the API will use those settings.
$data = array(
    'recipients' => array(
        '1234567890',
    ),
    'body' => 'Body of the SMS',
    'sender' => '1234567890',
    'senderTon' => 2,
    'senderNpi' => 1,
);
Will result in:
"sender": "1234567890",
"senderTon": 2,
"senderNpi": 1,
For both types of sender IDs there can be requirements from the operator or country to pre-register it. Please contact us for pre-registration should that be a requirement of yours. If the sender ID is not pre-registered the message might not get delivered or can be overwritten with a default one.

Numeric sender

The maximum length of a numeric sender ID is 17. Only the digits 0-9 are allowed. The two most important options for numeric senders are:
  • International (senderTon = 1, senderNpi = 1)
  • National (senderTon 2, senderNpi = 1)
Only with international sender IDs can the receiver reply to the message. However you would need to use our SMS MO service to achieve a full reply path. Through our MO service we will provide you with a number where the receiver can reply to and you will then receive the message from us. Please contact us for our MO services should that be a requirement of yours.

Alphanumeric sender

The maximum length of an alphanumeric sender ID is 11. The characters A-Z and digits 0-9 are supported. Uppercase, lowercase characters and whitespaces are allowed.

For alphanumeric sender IDs the senderTon should be 5 and the senderNpi should be 0. If you leave the senderTon and senderNPI empty our API will automatically set it as described above. Or you can set it yourself to be sure it is marked as an alphanumeric sender.

With an alphanumeric sender ID the receiver will not be able to reply to the message. If you want the receiver to be able to reply to messages you have to use our service SMS MO. Please contact us for our MO services should that be a requirement of yours.
Sign up and Get Started for Free

sign up for free
Monthly 100 free verification credits
and no credit card required at sign up!