To avoid fraud & spam registrations, phone verification is best way. So here we are going to create an demo application for phone verification system. To create this application we will use PHP 7, MySQL 5.x , jQuery & Twilio Voice API. You can download this demo application here and get started. You need to install Twilio PHP SDK to run this demo application. You can install Twilio PHP SDK using composer and without composer as well. If you find any issue to install it, just comment here or contact direct on [email protected]. Also you need to update database settings in db.php and your Twilio credentials in twilio-helper.php.
Steps in this demo application
- Create database to store user & verification info
- Create web page to where user can enter his phone number to and process verification
- Generate verification code & store in db.
- User is called & prompted to enter code.
- Verify code with db code.
- If entered code is wrong then re-prompt to enter code.
- If entered code is correct, update database.
- Show verification status message.
Create Database
Create database table using below code:
CREATE TABLE IF NOT EXISTS `user_phones` ( `id` int(11) NOT NULL AUTO_INCREMENT, `phone` varchar(50) DEFAULT NULL, `verification_code` int(11) DEFAULT NULL, `verified` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Now create db.php and put below code on it
<?php function setupDatabase() { // put your database information mentioned above here $username = 'root'; $password = 'root'; $host = 'localhost'; $dbname = 'verify'; try { $pdo = new PDO("mysql:host=$host;dbname=$dbname",$username,$password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { return 'ERROR: ' . $e->getMessage(); } return $pdo; } // attempts to delete existing entries and // save verification code in DB with phone number function updateDatabase($phoneNumber, $code) { $pdo = setupDatabase(); if (!is_a($pdo, 'PDO')) { echo 'PDO is false'; return $pdo; } // Assuming US country code for example $params = [ 'phoneNumber' => '1' . $phoneNumber ]; try { $stmt = $pdo->prepare("DELETE FROM numbers WHERE phone_number=:phoneNumber"); $stmt->execute($params); $params['code'] = $code; $stmt = $pdo->prepare("INSERT INTO numbers (phone_number, verification_code) VALUES(:phoneNumber, :code)"); $stmt->execute($params); } catch(PDOException $e) { return 'ERROR: ' . $e->getMessage(); } return $code; } function matchVerificationCode($phoneNumber, $code) { $pdo = setupDatabase(); if (!is_a($pdo, PDO::class)) { echo 'ERROR: PDO is false'; return 'ERROR: PDO is false '.$pdo; } $params = [ 'phoneNumber' => $phoneNumber ]; try { $stmt = $pdo->prepare("SELECT * FROM numbers WHERE phone_number=:phoneNumber"); $stmt->execute($params); $result = $stmt->fetch(); $response = 'unverified'; if ($result['verification_code'] == $code) { $stmt = $pdo->prepare("UPDATE numbers SET verified = 1 WHERE phone_number=:phoneNumber"); $stmt->execute($params); $response = 'verified'; } return $response; } catch(PDOException $e) { return 'ERROR: ' . $e->getMessage(); } } function statusIs($phoneNumber) { $pdo = setupDatabase(); if (!is_a($pdo, 'PDO')) { echo 'PDO is false'; return $pdo; } $params = [ 'phoneNumber' => $phoneNumber ]; try { $stmt = $pdo->prepare("SELECT * FROM numbers WHERE phone_number=:phoneNumber"); $stmt->execute($params); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result['verified'] == 1) { return 'verified'; } return 'unverified'; } catch(PDOException $e) { return 'ERROR: ' . $e->getMessage(); } }
Create Web Page
Create verification web page index.php and put below code on it.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Phone Verification using PHP, MySQL, jQuery & Twilio</title> <link type="text/css" rel="stylesheet" href="css/style.css" /> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script type="text/javascript" src="js/script.js"></script> </head> <body> <div class="main-wrap"> <div id="errors"></div> <form id="enter_number"> <p>Enter your phone number:</p> <p><input type="text" name="phone_number" id="phone_number" /></p> <p><input type="submit" name="submit" value="Verify" /></p> </form> <div id="verify_code" style="display: none;"> <p>Calling you now.</p> <p>When prompted, enter the verification code:</p> <h1 id="verification_code"></h1> <p><strong id="status">Waiting...</strong></p> </div> </div> </body> </html>
In above page there is a js file script.js added. Create script.js and puth below code on it.
jQuery(document).ready(function(){ jQuery("#verification-form").submit(function(e) { e.preventDefault(); initiateCall(); }); }); function initiateCall() { jQuery.post("twilio-helper.php", { phone_number : $("#phone_number").val() }, null, "json") .fail( function(data) { showErrors(data.errors); }) .done( function(data) { showCodeForm(data.verification_code); }) ; checkStatus(); } function showErrors(errors) { jQuery("#errors").text(code); } function showCodeForm(code) { jQuery("#verification_code").text(code); jQuery("#verify_code").fadeIn(); jQuery("#verification-form").fadeOut(); } function checkStatus() { jQuery.post("check-status.php", { phone_number : $("#phone_number").val() }, function(data) { updateStatus(data.status); }, "json"); } function updateStatus(current) { if (current === "unverified") { jQuery("#status").append("."); setTimeout(checkStatus, 3000); } else { success(); } } function success() { jQuery("#status").text("Verified!"); }
In this above code you can see when verification form submitted, there is a ajax request goes to twilio-helper.php .
Create twilio-helper.php and put below code on it.
<?php require __DIR__ . '/vendor/autoload.php'; require("db.php"); use Twilio\Rest\Client; function returnError($error){ $json = array(); $json["error"] = $error; header('Content-type: application/json'); http_response_code(500); echo(json_encode($json)); } function makeCall($submittedNumber, $code){ // put your project information here $accountSid = "YOUR_ACOCUNT_SID"; $authToken = "YOUR_AUTH_TOKEN"; $outgoingNumber = 'YOUR_TWILIO_NUMBER'; $endPoint = "YOUR_URL/twiml.php"; // Instantiate a new Twilio Rest Client $client = new Client($accountSid, $authToken); try { // initiate phone call via Twilio REST API $client->account->calls->create( $submittedNumber, // The phone number you wish to dial $outgoingNumber, // Verified Outgoing Caller ID or Twilio number [ "url" => $endPoint ] // The URL of twiml.php on your server ); } catch (Exception $e) { returnError($e->getMessage()); } // return verification code as JSON $json = array(); $json["verification_code"] = $code; header('Content-type: application/json'); echo(json_encode($json)); } // require POST request if ($_SERVER['REQUEST_METHOD'] != "POST") die; // save a verification code in DB with phone number // attempts to delete existing entries first $submittedNumber = $_POST["phone_number"]; $code = rand(100000, 999999); $updateError = updateDatabase($submittedNumber, $code); if (strpos($updateError, 'ERROR:') !== false) { returnError($updateError); } else { makeCall($submittedNumber, $code); }
This above code generate random verification code and store to database. But first you need to set twilio credentials like $accountSid , $authToken , $outgoingNumber , and $endPoint . Endpoint will be the path of file twilio-twiml.php that will create in next step.
Make Call, collect user input and verify
When initiating the call we direct Twilio to use the twilio-twiml.php file which generates the necessary <Gather> TwiML to prompt the caller to enter their code. The first time this file is requested we’ll ask the caller to enter their code. Once they’ve entered 6 digits, Twilio will make another post to the same URL with the Digits POST parameter now included. With this information we look up the caller’s phone number in the database and check for a match.
Create twilio-twiml.php and put below code on it.
<?php require __DIR__ . '/vendor/autoload.php'; require("database.php"); use Twilio\Twiml; $response = new Twiml; if (empty($_POST["Digits"])) { $gather = $response->gather([ 'input' => 'dtmf', 'timeout' => 10, 'numDigits' => 6 ]); $gather->say("Please enter your verification code."); } else { // grab caller phone number and caller entered code $submittedNumber = ltrim($_POST["Called"], '+'); $submittedCode = $_POST["Digits"]; // verify code and phone number against db record $match = matchVerificationCode($submittedNumber, $submittedCode); if ($match == 'verified') { $response->say("Thank you! Your phone number has been verified."); } else { $gather->say("Verification code incorrect, please try again."); } } header('Content-Type: text/xml'); echo $response ?>
In above code if user input code is matched with db verification code, then verification status is updated in db.
Check verification and show in web page
In script.js you can see there is checkStatus() function that continue hit check-status.php to check database for verification status.
Create check-status.php file and put below code on it
<?php require("database.php"); // require POST request if ($_SERVER['REQUEST_METHOD'] != "POST") die; // assuming US country code for example $json["status"] = statusIs('1' . $_POST["phone_number"]); header('Content-type: application/json'); echo(json_encode($json)); ?>
Above code return verification status and if status is verified then verification message is display in web page.
I hope this tutorial helps you. If you stuck on any step you can comment here or contact direct on [email protected]