Simple Phone Verification with Twilio, PHP, MySQL and jQuery

May 04, 2010
Written by
John Sheehan
Contributor
Opinions expressed by Twilio contributors are their own

Twilio Bug Logo
PHP

jQuery

MySQL

See the most updated version of these instructions and sample code here or read the tutorial on how to build phone verification in a Rails app

As more and more applications integrate with phones there is an increasing need to verify phone numbers to help prevent spam, fraud and other dubious activities. In these cases it’s common to use an automated phone verification system to present the user a verification code in their web browser while a call is initiated to their phone. When the call is answered they are prompted to enter the code, allowing them to confirm that they are the owner of that number.

In this post I’m going to cover how to build a simple phone number verification system using PHP, MySQL and jQuery.

This is a long example so I’m only going to highlight the most important parts in this post. You can download the complete example here. To run this example on your own server, update the database settings in database.php and your Twilio account settings in call.php. This example also makes use of our Twilio PHP Helper library which you can find on GitHub.

Basic steps

  1. User visits verification web page and enters phone number.
  2. Random verification code is generated and user is called and prompted to enter code.
  3. If code is entered incorrectly, re-prompt to enter code.
  4. If code is entered correctly, update database.
  5. Update web page with status message.

Step One: The verification web page

We’ll start with the HTML the user will see. Create a file called index.php and add the following code to the :

<form id="enter_number">Enter your phone number:<input id="phone_number" name="phone_number" type="text" /> <input name="submit" type="submit" value="Verify" /></form>
 

<div id="verify_code" style="display: none;">Calling you now. When prompted, enter the verification code: 

<h1 id="verification_code"></h1>

<strong id="status">Waiting...</strong>
</div>

When the user visits the page they’ll be presented with the form asking them for their phone number. Once entered, we’ll hide the form and show them their verification code. Here’s the jQuery needed to make that transition:

$(document).ready(function(){
  $("#enter_number").submit(function(e) {
    e.preventDefault();
    initiateCall();
  });
});

function initiateCall() {
  $.post("call.php", { phone_number : $("#phone_number").val() },
  function(data) { showCodeForm(data.verification_code); }, "json");
  checkStatus();
}

function showCodeForm(code) {
  $("#verification_code").text(code);
  $("#verify_code").fadeIn();
  $("#enter_number").fadeOut();
}

Our initiateCall() function kicks off an AJAX request to generate the random code and initiate the phone call, which I’ll discuss in more detail in Step Two later. Once we’ve got the code, we’ll update the UI to show it to the user and then start polling our database for status updates. The code to poll the server looks like this:

function checkStatus() {
  $.post("status.php", { phone_number : $("#phone_number").val() },
  function(data) { updateStatus(data.status); }, "json");
}

function updateStatus(current) {
  if (current === "unverified") {
    $("#status").append(".");
    setTimeout(checkStatus, 3000);
  }
  else {
    success();
  }
}

function success() {
  $("#status").text("Verified!");
}

Once we’ve got confirmation from the server that the number has been verified, we update the UI to let the user know.

Step Two: Generate and display random code

Step Two in our walkthrough overlaps with Step One since it is initiated when the user submits the form with their phone number. We’ll pick up in our initiateCall() function which makes the AJAX POST request to call.php. Inside call.php we generate the random 6-digit verification code and start the phone call by calling the Twilio REST API using the PHP Helper Library. Once we have the code, we’ll send it back as JSON for the browser to parse and display (as covered in Step One).

<!--?php require("Services/Twilio.php"); require("database.php"); // require POST request if ($_SERVER['REQUEST_METHOD'] != "POST") die; // generate "random" 6-digit verification code $code = rand(100000, 999999); // save verification code in DB with phone number // attempts to delete existing entries first $number = mysql_real_escape_string($_POST["phone_number"]); db(sprintf("DELETE FROM numbers WHERE phone_number='%s'", $number)); db(sprintf("INSERT INTO numbers (phone_number, verification_code) VALUES('%s', %d)", $number, $code)); mysql_close(); // initiate phone call via Twilio REST API // Set our AccountSid and AuthToken $AccountSid = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; $AuthToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Instantiate a new Twilio Rest Client $client = new Services_Twilio($AccountSid, $AuthToken); try { // make call $call = $client--->account->calls->create(
  '+18881234567', // Verified Outgoing Caller ID or Twilio number
  $number, // The phone number you wish to dial
  'http://example.com/twiml.php' // The URL of twiml.php on your server
);
} catch (Exception $e) {
  echo 'Error starting phone call: ' . $e->getMessage();
}
// return verification code as JSON
$json = array();
$json["verification_code"] = $code;
header('Content-type: application/json');
echo(json_encode($json));
?>

We’re storing the phone number along with the generated code in a MySQL database so that we can update the verified column from our TwiML script and then retrieve it later. For this example I’m using a simple table definition:

CREATE TABLE `numbers` (
   `phone_number` varchar(50) DEFAULT NULL,
   `verification_code` int(11) DEFAULT NULL,
   `verified` tinyint(4) NOT NULL DEFAULT 0
)

Steps Three and Four: Collect and verify code via phone call

When initiating the call we direct Twilio to use the twiml.php file which generates the necessary 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. If the code entered is incorrect, we’ll re-prompt them to enter it again. Once they’ve entered the correct code we update the database and thank them for calling.

<!--?php require("Services/Twilio.php"); require("database.php"); $response = new Services_Twilio_Twiml(); if (empty($_POST["Digits"])) { $gather = $response--->  gather(array('numDigits' => 6));
  $gather->say("Please enter your verification code.");
  }

  else {
    // grab db record and check for match
    $result = db(sprintf("select * from numbers where phone_number='%s'", $_POST["Called"]));
    if($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
    if ($_POST["Digits"] === $line["verification_code"]) {
    db(sprintf("UPDATE numbers SET verified = 1 WHERE phone_number = '%s'", $_POST["Called"]));
    $response->say("Thank you! Your phone number has been verified.");
  }

  else {
    // if incorrect, prompt again
    $gather = $response->gather(array('numDigits' => 6));
    $gather->say("Verification code incorrect, please try again.");
    }
  }

  mysql_close();
}
print $response;
?>

Step Five: Update the web page when the number is verified

Back in Step One we created the jQuery needed to begin polling the server for status updates. Our checkStatus() function makes a POST to status.php which looks up the phone number in the database and sends back some JSON containing the verification status.

<!--?php    
require("database.php");    

// require POST request    
if ($_SERVER['REQUEST_METHOD'] != "POST") die;    
$number = mysql_real_escape_string($_POST["phone_number"]);    
$result = db(sprintf("select * from numbers where phone_number='%s'", $number));    
$json = array();    
$json["status"] = "unverified";    
if($line = mysql_fetch_array($result, MYSQL_ASSOC)) {       
  if ($line["verified"] == "1") {          
    $json["status"] = "verified";       
  }    
}    
mysql_close();    
header('Content-type: application/json');    
echo(json_encode($json)); 
?-->

Coming soon: Verification via SMS

In an upcoming post I’ll be using this example as a starting point for creating a similar system to verify phones but using SMS instead of voice. Let me know in the comments below if there’s anything you’d like to see covered in that post.

Download the complete example

Download twilio-phone-verification.zip