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.
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;
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.
In the config.php
file, the API and database configuration variables are defined.
SMS Gateway API Settings:
Database Settings:
<?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.
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.
<?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;
}
}
}
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 } ?>
After the submission, the phone number and OTP are verified via SMS gateway using PHP.
When the mobile number is submitted by the user (or resend OTP request), the following happens.
When the OTP is submitted by the user, the following happens.
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($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$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(100000, 999999);
// 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';
?>
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
Pls I need a link get a SMS gateway api
Hi,
Your script is very good. Liked it very much. I just have one issue, my form is there at the bottom of the page. When you enter your mobile number and send OTP, it will refresh the page and comes to the beginning of the page. Users will not know that at the bottom of the page the OTP input field is opened. How can the page go to that form section when it refreshes.? Please help.
Good
Hello. Thanks for the code, its working great!
But the resend button don’t work 🙁 can you please help me to solve this? I searched about that thing for hours and hours but i didn’t found anything except ajax.
Thanks
Regards from Turkey
Hi your script is awesome. After member verification can show verified badge and hide verification input field . If not not verified only show verfication mobile number input
Is the DB.class a controller?
Am using codeigniter
Hi.
For the User id and API we should register in gateway sms ??
or user id is different ?
Yes, the user ID and API Key will be provided by your SMS Gateway API provider.
very good
Great!