Mobile Number Verification via OTP SMS using PHP

OTP or one-time password is a fast and effective way to verify the mobile number of the user. This method is widely used for mobile number verification in the web application, mostly in banking and e-commerce sites. Generally, OTP is sent to the user’s mobile number via SMS. The user needs to submit the verification code to verify their mobile number. In this tutorial, we will show you how to implement the one-time password (OTP) verification process via SMS using PHP.

SMS Gateway provides an easy way to send text messages to mobile numbers from the script. Using SMS gateway API, you can easily send an OTP code to the user’s mobile number for verification. Most of the SMS gateway provider allows sending SMS from the PHP script. In the example code, we will use SMS gateway API to send OTP SMS using PHP.

In this example mobile number verification script, we will implement the following functionality to verify phone numbers via OTP SMS using PHP.

  • Generate a random 6 digits verification code with PHP.
  • Send OTP to the user’s mobile no via SMS gateway API and insert it in the database.
  • Verify the OTP code and update the status in the database.
  • Display the verification status to the user.

Create Database Table

To store the OTP code and verification status a table is required in the database. The following SQL creates a mobile_otps table with some basic columns in the MySQL database.

CREATE TABLE `mobile_otps` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mobile_number` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `verification_code` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `verified` tinyint(1) NOT NULL DEFAULT 0 COMMENT '1=Verified, 0=Not verified',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

SMS Gateway API

Before getting started, you need to select an SMS gateway service provider that is suitable for your target country. Once you purchase an SMS gateway API plan, the API details will be available from the respective provider.

Collect the API credentials to later use in the script.

  • API URL
  • API Key

Configuration File (config.php)

In the config.php file, the API and database configuration variables are defined.
SMS Gateway API Settings:

  • API_URL – API endpoint URL
  • API_KEY – API Key
  • SENDER_ID – Sender name or ID
  • COUNTRY_CODE – Country code of the recipient’s phone no.

Database Settings:

  • DB_HOST – Datebase hostname
  • DB_USERNAME – Datebase username
  • DB_PASSWORD – Database password
  • DB_NAME – Database name
<?php 
// SMS gateway API credentials
define('API_URL''https://api.example.com/sendsms');
define('API_KEY''Your_API_Key');
define('SENDER_ID''CODEXW');
define('COUNTRY_CODE'1); //1=United States

// Database configuration
define('DB_HOST''MySQL_Database_Host');
define('DB_USERNAME''MySQL_Database_Username');
define('DB_PASSWORD''MySQL_Database_Password');
define('DB_NAME''MySQL_Database_Name');

Note that: You will get the API credentials from the SMS gateway service provider.

Database Class (DB.class.php)

The DB class handles all the database related operations (fetch, insert, and update) using PHP and MySQL.

The following functions are used to fetch, insert and update OTP data in the database.

  • __construct() – Connect and select the database.
  • checkRow() – Check whether any record exists in the mobile_otps table based on the specific conditions. Returns TRUE if exists, otherwise FALSE.
  • insert() – Insert data in the mobile_otps table of the database.
  • update() – Update data based on the conditions in the mobile_otps table of the database.
<?php 
/*
 * DB Class
 * This class is used for database related (connect, insert, and update) operations
 * @author    CodexWorld.com
 * @url        http://www.codexworld.com
 * @license    http://www.codexworld.com/license
 */
require_once 'config.php';
class 
DB{
    private 
$dbHost     DB_HOST;
    private 
$dbUsername DB_USERNAME;
    private 
$dbPassword DB_PASSWORD;
    private 
$dbName     DB_NAME;
    private 
$tblName    "mobile_otps";
    
    public function 
__construct(){
        if(!isset(
$this->db)){
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUsername$this->dbPassword$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    
/*
     * Returns rows from the database based on the conditions
     * @param string name of the table
     * @param array select, where, order_by, limit and return_type conditions
     */
    
public function checkRow($conditions = array()){
        
$sql 'SELECT * FROM '.$this->tblName;
        if(!empty(
$conditions)&& is_array($conditions)){
            
$sql .= ' WHERE ';
            
$i 0;
            foreach(
$conditions as $key => $value){
                
$pre = ($i 0)?' AND ':'';
                
$sql .= $pre.$key." = '".$value."'";
                
$i++;
            }
        }

        
$result $this->db->query($sql);
        
        return !empty(
$result->num_rows 0)?true:false;
    }
    
    
/*
     * Insert data into the database
     * @param string name of the table
     * @param array the data for inserting into the table
     */
    
public function insert($data){
        if(!empty(
$data) && is_array($data)){
            
$columns '';
            
$values  '';
            
$i 0;
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$columns .= $pre.$key;
                
$values  .= $pre."'".$val."'";
                
$i++;
            }
            
$query "INSERT INTO ".$this->tblName." (".$columns.") VALUES (".$values.")";
            
$insert $this->db->query($query);
            return 
$insert?$this->db->insert_id:false;
        }else{
            return 
false;
        }
    }
    
    
/*
     * Update data into the database
     * @param string name of the table
     * @param array the data for updating into the table
     * @param array where condition on updating data
     */
    
public function update($data$conditions){
        if(!empty(
$data) && is_array($data)){
            
$colvalSet '';
            
$whereSql '';
            
$i 0;
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$colvalSet .= $pre.$key."='".$val."'";
                
$i++;
            }
            if(!empty(
$conditions)&& is_array($conditions)){
                
$whereSql .= ' WHERE ';
                
$i 0;
                foreach(
$conditions as $key => $value){
                    
$pre = ($i 0)?' AND ':'';
                    
$whereSql .= $pre.$key." = '".$value."'";
                    
$i++;
                }
            }
            
$query "UPDATE ".$this->tblName." SET ".$colvalSet.$whereSql;
            
$update $this->db->query($query);
            return 
$update?$this->db->affected_rows:false;
        }else{
            return 
false;
        }
    }
}

OTP Verification Form (index.php)

Initially, an HTML form is displayed to allow the user to submit their mobile number. After the phone number submission, the OTP input field is displayed to enter the verification code.

<!-- Display status message -->
<?php echo !empty($statusMsg)?'<p class="alert alert-'.$statusMsg['status'].'">'.$statusMsg['msg'].'</p>':''?>

<?php if($verified == 1){ ?>
    <p>Mobile No: <?php echo $recipient_no?></p>
    <p>Verification Status: <b>Verified</b></p>
<?php }else{ ?>
<!-- OTP Verification form -->
<form method="post">
    <div class="form-group">
        <label>Enter Mobile No</label>
        <input type="text" name="mobile_no" value="<?php echo !empty($recipient_no)?$recipient_no:''?>" <?php echo ($otpDisplay == 1)?'readonly':''?>>
    </div>
    <?php if($otpDisplay == 1){ ?>
        <div class="form-group">
            <label>Enter OTP</label>
            <input type="text" name="otp_code">
        </div>
        <input type="submit" name="resend_otp" class="resend" value="Resend OTP"/>
    <?php ?>

    <input type="submit" name="<?php echo ($otpDisplay == 1)?'submit_otp':'submit_mobile'?>" value="VERIFY"/>
</form>
<?php ?>

OTP Submission and Verification (verify.php)

After the submission, the phone number and OTP are verified via SMS gateway using PHP.

  • The sendSMS() is a custom helper function that is used to send SMS via SMS Gateway API using PHP.
  • The PHP cURL method is used to execute API requests.
  • Load and initialize database class to handle the database related operations.

When the mobile number is submitted by the user (or resend OTP request), the following happens.

  • Generate a random 6 digits verification code using the rand() function in PHP.
  • Use the checkRow() method of the DB class to check if any record exists in the database with the same mobile number.
  • If the mobile number exists, update only verification_code in the database using the update() method of the DB class.
  • If the mobile number does not exist, insert OTP data in the database using the insert() method of the DB class.
  • Send the OTP code to the user via SMS using the sendSMS() function.
  • If OTP SMS is sent successfully, OTP input will be enabled in the HTML form.

When the OTP is submitted by the user, the following happens.

  • Compare the OTP with the DB data to verify whether the user provides the correct verification code.
  • Update verification status in the database.

If OTP is verified successfully, the status message will be shown to the user.

<?php 
// Include configuration file
include_once 'config.php';

function 
sendSMS($mobile_no$message){
    
// Request parameters array 
    
$requestParams = array( 
        
'api_key' => API_KEY
        
'sender_id' => SENDER_ID
        
'receipient_no' => COUNTRY_CODE.$mobile_no,
        
'message' => $message
    
); 
    
    
// Append parameters to API URL 
    
$apiURL API_URL.'?'
    foreach(
$requestParams as $key => $val){ 
        
$apiURL .= $key.'='.urlencode($val).'&'
    } 
    
$apiURL rtrim($apiURL"&"); 
    
    
// Send the GET request with cURL 
    
$ch curl_init(); 
    
curl_setopt($chCURLOPT_URL$apiURL); 
    
curl_setopt($chCURLOPT_RETURNTRANSFER1); 
    
$response curl_exec($ch); 
    
curl_close($ch); 
    
    
// Return API response
    
return $response;
}

// Load and initialize database class
require_once 'DB.class.php';
$db = new DB();
        
$statusMsg $receipient_no '';
$otpDisplay $verified 0;

// If mobile number submitted by the user
if(isset($_POST['submit_mobile']) || isset($_POST['resend_otp'])){
    
// Recipient mobile number
    
$recipient_no $_POST['mobile_no'];

    if(!empty(
$recipient_no) && preg_match('/^[0-9]{10}+$/'$recipient_no)){
        
// Generate 6 digits random verification code
        
$rand_no rand(100000999999);
        
        
// Check previous entry
        
$conditions = array(
            
'mobile_number' => $recipient_no,
        );
        
$checkPrev $db->checkRow($conditions);
        
        
// Insert or update otp in the database
        
if($checkPrev){
            
$otpData = array(
                
'verification_code' => $rand_no
            
);
            
$insert $db->update($otpData$conditions);
        }else{
            
$otpData = array(
                
'mobile_number' => $recipient_no,
                
'verification_code' => $rand_no,
                
'verified' => 0
            
);
            
$insert $db->insert($otpData);
        }
        
        if(
$insert){
            
// Send otp to user via SMS
            
$message 'Dear User, OTP for mobile number verification is '.$rand_no.'. Thanks CODEXWORLD';
            
$send sendSMS($recipient_no$message);
            if($send){
                
$otpDisplay 1;
                
$statusMsg = array(
                    
'status' => 'success',
                    
'msg' => "OTP has been successfully sent to your mobile no."
                
);
            }else{
                
$statusMsg = array(
                    
'status' => 'error',
                    
'msg' => "We're facing some issues with sending SMS, please try again."
                
);
            }
        }else{
            
$statusMsg = array(
                
'status' => 'error',
                
'msg' => 'Something went wrong, please try again.'
            
);
        }
    }else{
        
$statusMsg = array(
            
'status' => 'error',
            
'msg' => 'Please enter a valid mobile number.'
        
);
    }
// If verification code submitted by the user
}elseif(isset($_POST['submit_otp']) && !empty($_POST['mobile_no'])){
    
$otpDisplay 1;
    
$recipient_no $_POST['mobile_no'];
    
$otp_code $_POST['otp_code'];

    if(!empty(
$otp_code)){
        
// Verify otp code
        
$conditions = array(
            
'mobile_number' => $recipient_no,
            
'verification_code' => $otp_code
        
);
        
$check $db->checkRow($conditions);
        
        if(
$check){
            
$otpData = array(
                
'verified' => 1
            
);
            
$update $db->update($otpData$conditions);
            
            
$statusMsg = array(
                
'status' => 'success',
                
'msg' => 'Thank you! Your phone number has been verified successfully.'
            
);
            
            
$verified 1;
        }else{
            
$statusMsg = array(
                
'status' => 'error',
                
'msg' => 'Given verification code is incorrect, please try again.'
            
);
        }
    }else{
        
$statusMsg = array(
            
'status' => 'error',
            
'msg' => 'Please enter the verification code.'
        
);
    }
}

Include this server-side verification script (verify.php) before the HTML form code.

<?php 
// Include the verification script
include_once 'verify.php';
?>

Conclusion

You can use this readymade script to integrate OTP SMS verification functionality in your website using PHP. The only thing you need to choose a perfect SMS gateway service provider and get the SMS API details to send SMS from the script. All the required features are integrated into this example script, such as OTP SMS, OTP verification, resend OTP, etc.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

10 Comments

  1. Anthony Said...
  2. Paresh Said...
  3. Bungyas Said...
  4. Irsad Said...
  5. Anil Said...
  6. Ruth Said...
  7. ABHILASH B Said...
    • CodexWorld Said...
  8. Hihi Said...
  9. Asas Said...

Leave a reply

keyboard_double_arrow_up