Available in Enterprise Plan and above.
StoreHippo allows you to enable login with mobile number and OTP. If you enable login via phone number and OTP in your store, your customers don't need an email id and password to login as they can log in to your store through a phone number and OTP. This helps your customers to not remember the password every time they log in. You can also select the OTP size and the same size OTP will be received by the customers for login.
You want your customers to log in with the phone number and OTP instead of email and password. Your customers will receive an OTP every time they try to log into your store.
To set up the login with mobile number and OTP, first, you need to provide a login field as a
You need to add the widget code to enable send OTP functionality. To do so, follow the steps mentioned below:
Template:
<div ms-widget='ms.th2.login_controller' class="login-form ms-fs-14" ms-data-formname="login" ms-data-buttonname="Login"> <form ng-if="formFields.length" name="login" ms-success="ms.location.path('/account/profile');removepop('.modal')" ng-submit="submit()" novalidate> <div ng-repeat="field in formFields"> <div ng-if="field.settings.display_type=='email'" class="form-group ms-mb-0"> <input data-ng-disabled="field.settings.read_only == '1'" type="text" class="form-control" id="{{field.name}}" ng-model='fields[field.name]' placeholder="{{field.settings.placeholder|msTranslate}}"> </div> <div ng-if="field.settings.display_type=='text'" class="form-group ms-mb-0"> <input data-ng-disabled="field.settings.read_only == '1'" type="text" class="form-control" id="{{field.name}}" ng-model='fields[field.name]' placeholder="{{field.settings.placeholder|msTranslate}}" autocomplete="off"> </div> <div class="checkbox" ng-if="field.settings.display_type=='checkbox'"> <label class="check1"> <span class="check2" ng-bind-html-unsafe="field.label|msTranslate"></span> <input type="checkbox" ng-model='fields[field.name]'> </label> </div> <div class="form-group ms-mb-xs" data-ng-if="field.settings.display_type=='phone' && !verification_otp"> <input name="phone" type="tel" id="phone" class="form-control phoneInputStyle" data-ng-model="fields[field.name]" data-ng-intl-tel-input placeholder="Phone Number" ng-enter="sendOTP(fields.username)"> <label ng-show="login.phone.$invalid" class="error"> {{'Please enter valid phone number'|msTranslate}} </label> </div> <div ng-if="field.settings.display_type=='password' && verification_otp" class="form-group ms-mb-0"> <p class="pull-left ms-fs-12"> Enter OTP </p> <input type="password" class="form-control passwordStyle" id="{{field.name}}" ng-model='fields[field.name]' ng-submit="submit()"> </div> <label ng-if="errors[field.name]" class="error">{{errors[field.name]|msTranslate}}</label> </div> <div ng-if="ms.settings.login_field == 'phone' && ms.settings.login_with_otp == '1'"> <p ng-if="verification_otp"> <a class="primary " ng-class="{'resendStyle2': ms.page.name == 'checkout' , 'resendStyle': ms.page.name != 'checkout'}" ng-if="timer.seconds <= 0" data-ng-click="sendOTP(fields.username)"> {{'RESEND '|msTranslate}} </a> <span ng-if="timer.seconds > 0" class="" ng-class="{'resendStyle2': ms.page.name == 'checkout' , 'resendStyle': ms.page.name != 'checkout'}">RESEND IN 00 : {{timer.seconds}}</span> </p> <div class="form-group ms-mt-m ms-mb-0"> <div ng-if="!verification_otp"> <a data-ng-disabled="!fields.username" class="ms-w-full btn btn-primary otpStyle" data-ng-click="sendOTP(fields.username)"> {{'SEND OTP'|msTranslate}} </a> </div> <div ng-if="verification_otp"> <button type="submit" class="ms-w-full btn btn-primary otpStyle"> {{'LOGIN'|msTranslate}} </button> </div> </div> </div> <div ng-if="ms.settings.login_field != 'phone' || ms.settings.login_with_otp != '1'"> <div class="form-group ms-mb-0"> <button type="submit" class="ms-w-full btn btn-primary"> {{'LOGIN'|msTranslate}} </button> </div> </div> <!-- form well --> <div ng-if=" ms.settings.login_providers.length" class="row social-login text-center ms-fs-11 ms-mt-x"> <p class=" gray-light ">- {{'EASILY USING'|msTranslate}} -</p> <a ng-repeat="data in ms.settings.login_providers" ng-if="data.name == 'facebook' " class="btn facebook-login login-social-links" ms-widget="ms.facebookLogin"> <div ng-if="!data.logo"> <i class="fa fa-facebook fa-lg"> </i> {{'Facebook'|msTranslate}} </div> <div ng-if="data.logo"> <img ms-data-valign='middle' class="ms-mh-30 img-responsive" data-ng-src="{{data.logo|image:'480x480'}}" title="{{data.name}}" alt="{{data.name}}"> </div> </a> <a ng-repeat="data in ms.settings.login_providers" data-ng-if="data.name == 'accountkit'" ms-data-provider="accountkit" class="btn facebook-login login-social-links" ms-widget="ms.socialLogin"> <div ng-if="!data.logo"> {{'AccountKit'|msTranslate}} </div> <div ng-if="data.logo"> <img ms-data-valign='middle' class="ms-mh-30 img-responsive" data-ng-src="{{data.logo|image:'480x480'}}" title="{{data.name}}" alt="{{data.name}}"> </div> </a> <a ng-repeat="data in ms.settings.login_providers" ng-if="data.name == 'google'" type="button" class="btn google-login login-social-links" ms-widget="ms.googleLogin"> <div ng-if="!data.logo"> <i class="fa fa-google-plus fa-lg"> </i> {{'Google'|msTranslate}} </div> <div ng-if="data.logo"> <img ms-data-valign='middle' class="ms-mh-30 img-responsive" data-ng-src="{{data.logo|image:'480x480'}}" title="{{data.name}}" alt="{{data.name}}"> </div> </a> <a ng-repeat="data in ms.settings.login_providers" data-ng-if="data.name == 'apple'" type="button" ng-click="ms.providerLogin('apple')" class="btn apple-login login-social-links"> <img ms-data-valign='middle' class="ms-mh-30 img-responsive" data-ng-src="https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple/images/apple-id-sign-up-with.png" title="{{data.name}}" alt="{{data.name}}"> </a> </div> </form> </div> <style> .btn.disabled, .btn[disabled], fieldset[disabled] .btn { opacity: 1 !important; } @media (max-width:754px) { .otpStyle { border-radius: 4px; font-size: 13px; height: 48px; font-size: 17px; padding-top: 12px; } .phoneInputStyle { height: 48px; font-size: 17px; padding-top: 12px; margin-bottom: 24px; background-color: #f2f2f2; border: none; padding: 10px 83px 11px 10px; } .passwordStyle { height: 48px; font-size: 17px; padding-top: 12px; background-color: #f2f2f2; border: none; padding: 10px 83px 11px 10px; } .resendStyle { position: absolute; top: 112px; font-size: 12px; right: 30px; } .resendStyle2 { position: absolute; top: 17px; font-size: 12px; right: 12px; } } .facebook-login { font-size: 14px; padding: 10px 10px; border: 1px solid #d2d2d2; margin: 5px; color: #3b5998 !important; } .google-login { color: #d34836 !important; font-size: 14px; padding: 10px 10px; border: 1px solid #d2d2d2; margin: 5px; } @media screen and (max-width:767px) { .check1 { display: flex !important; align-items: flex-start !important; flex-direction: row-reverse !important; } .check2 { margin-left: 5px !important; } } </style>
Controller:
function($scope, app) { var startTimer = function(duration) { $scope.timer = {}; var timer = duration; var mytimer = setInterval(function () { $scope.timer.seconds = Math.floor(timer - 1); if (--timer < 0) { timer = duration; } console.log($scope.seconds); if($scope.timer.seconds == 0) { clearInterval(mytimer) } if (!$scope.$$phase) { $scope.$apply(); } }, 1000); } $scope.sendOTP = function (phone) { var customRequest = { entity: 'ms.users', type: 'put', data : { username : phone } }; app.call('sendMobileOtp', customRequest, function (err, response) { if (err) { console.log('error==='. err) location.reload(); } else { $scope.verification_otp = true; startTimer(60); console.log('otp sent' , response) } }); }}
After enabling the login with phone number and OTP, you need to edit the login form.
Now, the login form will have a mobile number and OTP fields. The customers can enter the phone and number and provide the OTP received on their mobile number for logging in.