User Registration with SMS OTP verification in php

Hey Technoz! Hope you are doing great. Today in this article, we will see how to implement user registration with SMS OTP verification in php. Sometimes, we need user’s mobile number and have to verify it. Thus, we will see how to do it in this step by step tutorial of SMS OTP verification in php. In this tutorial, we will create a user registration system where the user will register with his/her username, password and mobile number. On submitting, the SMS will be sent to the user and he/she will be redirected to new window which requests an OTP which is sent by SMS. If user enters the correct OTP, then his/her account will be created.

Before we start, we obviously need any SMS provider which can send SMS on our behalf by receiving API calls. There are number of providers found from searches, but here in this tutorial, I am using a Textlocal which is fast, reliable and reasonable rates. Also, it gives 10 free SMS credits after sign up. Thus, you can test it before purchasing any bundle. It allows to use its API free of cost. Therefore, lets first see how to set up account and a unique API key from the panel.

Setting up account and getting API key

Firstly, go to Textlocal’s official website. Then create an account there, and login to your account. At starting, you will see 10 SMS credits available in your account (If not, then contact their support). Now go to Menu select Settings-> API Keys. API keys are required while we are sending API requests from our PHP code. These keys are unique and confidential because it verifies your identity without username and password. However, by default there are no keys available. As we are going to use API calls for SMS OTP verification in PHP files, thus we need to create a new key.

Click on Create New Key button. The optional parameters are asked while creating key. One is IP addresses and other is Notes. The IPs listed in first box, are only allowed to make an API request. You can leave empty if you want your call should be served from any system. In this case,we are leaving it empty. The another box is for adding any notes to understand the purpose of creating the key. Lets add a note as “PHP API for testing” and click on “Save New Key” button. Now you will be seeing the new key created, as shown in image below.

Textlocal Panel
Image Credits: Textlocal

Copy this key as we will need it in our code.

Building user registration system

Now, first create the database named newdb and table named users in it. Create 5 fields in the table as id, username, password, mobile and verified. You can use the SQL query below to create the table quickly.

DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `mobile` text NOT NULL,
  `verified` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
)

Obviously, we need to create a file to establish database connection. Thus, Create folder smsdemo in your localhost directory and create a new file config.php in it with the below code.

<?php
	$servername = "localhost";
	$username = "root";
	$password = "";
	$dbname = "newdb";
	
	// Create connection
	$conn = new mysqli($servername, $username, $password, $dbname);
?>

Building code to send API request

Now, we are going for the actual code which will mainly useful for sending SMS OTP verification in PHP code below. For that, create a file send-sms.php and write the below code in it.

<?php
//function to send API request to Textlocal
function sendSMS($numbers, $msg) {
	// Account details
	$apiKey = urlencode("Put your API key here");
	// Message details
	$sender = urlencode("TXTLCL");
	
	$message = rawurlencode($msg);
	
	$numbers = implode(',', $numbers);
	
	// Prepare data for POST request
	$data = array("apikey" => $apiKey, "numbers" => $numbers, "sender" => $sender, "message" => $message);
	// Send the POST request with cURL
	$ch = curl_init("https://api.textlocal.in/send/");
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($ch);
	curl_close($ch);
	// Process your response here
	return $response;
}
?>

The above code is also available on Textlocal’s link for API integration. However, we have slightly modified the above code according to our requirements. We are creating a new function sendSMS() which takes parameters as mobile number and message to send. Put the API key you get from Textlocal panel in the above code, as written above.we are encoding the values and creating an array. Finally, we are sending the request to server by curl function and returning the response received.

Note: If you want to try whether the sms is going successfully or not without consuming your sms credits, then you should put the parameter ‘test’ and its value as ‘true’ in the array above. To do that, replace the above array line with line below.

$data = array("apikey" => $apiKey, "numbers" => $numbers, "sender" => $sender, "message" => $message, "test" => true);

Notice the ‘test’ parameter added in the above line. This will turn on the test mode and your message will not be actually sent though it will pretend as sent and also, your sms credits will not be consumed. When you want to actually receive the message, just remove the last ‘test; parameter and your are good to go.

Creating registration form

We are now moving towards the creation of registration form. So, create a new php file index.php with the following code in it.

<?php
include "config.php";
include "send-sms.php";
?>
<html>
	<head>
		<title>Register user with OTP in SMS</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
		<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
	</head>
	<body>
		<div class="container">
			<p class="display-3 text-center">Register user with OTP in SMS</p>
			<form action="" method="post">
				<div class="form-group">
					<label for="username">Username:</label>
					<input type="text" class="form-control" placeholder="Enter Username" name="username" id="username" required>
				</div>
				<div class="form-group">
					<label for="password">Password:</label>
					<input type="password" class="form-control" placeholder="Enter Password" name="password" id="password" required>
				</div>
				<div class="form-group">
					<label for="mobile" class="form-inline">Mobile Number:</label>
					<input type="number" class="form-control" placeholder="Enter Mobile number" name="mobile" id="number" required>
				</div>
				<button type="submit" name="registerbtn" class="btn btn-primary">Register</button>
			</form>
			<?php
				if(isset($_POST['registerbtn'])){
					$username = $_POST['username'];
					$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
					$mobile = $_POST['mobile'];
					$otp = mt_rand(10,1000000);
					$msg = "The OTP for registering your account on Technopoints is ".$otp;
					$response = sendSMS(array($mobile),$msg);
					$obj = json_decode($response);
					if($obj->status == "success"){
						session_start();
						$_SESSION['otp'] = $otp;
						$saveUser = $conn->prepare("INSERT INTO users(username, password, mobile) VALUES(?,?,?)");
						$saveUser->bind_param("sss",$username, $password, $mobile);
						if($saveUser->execute()){
							header("Location: verify.php?username=".$username);
						}
					} else {
						$errorCode = $obj->code;
						if($errorCode == "7"){
							$errorMsg = "Insufficient Credits! Please recharge your account";
						} else if($errorCode == "32"){
							$errorMsg = "Invalid number format";
						} else if($errorCode == "51"){
							$errorMsg = "Invalid number or number is in DND registry";
						} else if($errorCode == "192"){
							$errorMsg = "Invalid time. Messages can be sent at only (9 AM to 9 PM)";
						} else if($errorCode == "4"){
							$errorMsg = "No number specified";
						} else {
							$errorMsg = "Message not sent. Try again later";
						}
						?>
						<div class="container">
							<div class="alert alert-danger alert-dismissible">
								<button type="button" class="close" data-dismiss="alert">&times;</button>
								<?php echo $errorCode; ?>
							</div>
						</div>
					<?php
					}
				}
			?>
			<p class="small text-center">A tutorial on <a href="https://technopoints.co.in" target="new">Technopoints</a></p>
		</div>
	</body>
</html>

This file creates a user registration form with following UI for SMS OTP verification in php as shown in below screen.

User Registration with SMS OTP verification using php

Let me explain what we are doing in the above code. We are adding the files config.php and send-sms.php in this file. We are creating the above input fields for user. After submitting the above form, we are generating a random number using mt_rand() function in php. Furthermore, we are calling the function sendSMS() with parameters as the number and message which contains the OTP. We are sending the number as a PHP array. If the message is successful, then we are storing the OTP generated, in session variable as we will need it later and simultaneously inserting the record in the database. After successful insertion, we are redirecting the user to further screen where the OTP is verified. So, Lets build the verification screen further.  Lets have a look at the message received in the phone.

User Registration with SMS OTP verification using php

If unfortunately the sms is not sent, then Textlocal API returns the specific error code and we are handling the different error codes with the appropriate messages. You can see the list of error codes and their explanations here on official documentation of Textlocal.

SMS OTP verification in php

After successful insertion of record, we will redirect user to this screen to verify the OTP. Lets create a file verify.php and paste the following code in it.

<?php
include "config.php";
?>
<html>
	<head>
		<title>Verify OTP</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
		<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
	</head>
	<body>
		<div class="container">
			<p class="display-3 text-center">Register user with OTP in SMS</p>
			<p class="display-3 text-center">Verify OTP</p>
			<p class="lead">Enter the OTP you received on your phone, in the box below.</p>
			<form action="" method="post">
				<div class="form-group">
					<label for="otp">One Time Password:</label>
					<input type="number" class="form-control" placeholder="Enter OTP" name="otp" id="otp" required>
				</div>
				<button type="submit" name="submitbtn" class="btn btn-primary">Submit</button>
			</form>
			<?php
			session_start();
			if(isset($_GET['username'])){
				$username = $_GET['username'];
			}
			//echo $_SESSION['otp'];
			if(isset($_POST['submitbtn'])){
				$otp = $_POST['otp'];
				if($otp == $_SESSION['otp']){
					$verifyUser = $conn->prepare("UPDATE users SET verified=true WHERE username=?");
					$verifyUser->bind_param("s",$username);
					if($verifyUser->execute()){?>
						<div class="container">
							<div class="alert alert-success alert-dismissible">
								<button type="button" class="close" data-dismiss="alert">&times;</button>
								You have been verified successfully
							</div>
						</div>
					<?php
					} else {?>
						<div class="container">
							<div class="alert alert-danger alert-dismissible">
								<button type="button" class="close" data-dismiss="alert">&times;</button>
								Failed to verify
							</div>
						</div>
					<?php
					}
				} else {?>
					<div class="container">
						<div class="alert alert-danger alert-dismissible">
							<button type="button" class="close" data-dismiss="alert">&times;</button>
							Wrong OTP. Please try again
						</div>
					</div>
				<?php
				}
			}
			?>
		</div>
	</body>
</html>

The above code creates a single textbox to enter the OTP received on the phone via SMS. After user submits the form, we will compare the received value with the one we have in session variable $_SESSION['otp']. If the comparison is successful, then we will change the value of ‘verified’ field to true an we will show the success message to user as follows.

User Registration with SMS OTP verification using php

Congratulations! You have made it. 🙂 Now you know how to register user with SMS OTP verification in PHP language. Lets try to use it in your project.

Note: If you are not receiving the sms, then you might have problem of deprecated certificates in browser and thus, the browser is failing to send request to server. Lets do following simple steps to get rid of this problem:

  1. Go to this link and download the file cacert.pem
  2. Put this file in the same folder where you have put another files of this project
  3. Open file send-sms.php and add the following line just above the curl_exec() function
    curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

Thus, the modified send-sms.php will be as follows:

<?php
//function to send API request to Textlocal
function sendSMS($numbers, $msg) {
	// Account details
	$apiKey = urlencode("Put your API key here");
	// Message details
	$sender = urlencode("TXTLCL");
	
	$message = rawurlencode($msg);
	
	$numbers = implode(',', $numbers);
	
	// Prepare data for POST request
	$data = array("apikey" => $apiKey, "numbers" => $numbers, "sender" => $sender, "message" => $message);
	// Send the POST request with cURL
	$ch = curl_init("https://api.textlocal.in/send/");
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem"); //Add this line if getting empty response
	$response = curl_exec($ch);
	curl_close($ch);
	// Process your response here
	return $response;
}
?>

That’s it friends. Hope you have success in implementing this tutorial. If you have any questions, then let me know in the comments section below. If you liked this tutorial, then please do share it with your friends. Please subscribe our email newsletter to receive the update for every new published tutorial.

Download Source Code

If you want to directly jump on implementation, then feel free to download the source code from the link below.

Download Link

14 thoughts on “User Registration with SMS OTP verification in php

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.