Guides & tutorials

Signup form with phone verification

Table of contents

Create and set up a registration form with phone verification for your API. A really common use case, especially on SaaS platforms, which you can easily build with Arengu.

Previous requirements

  • Your own API to authenticate and register the users.
  • A Twilio account to send the OTP by SMS.
  • An Arengu account to create the form and the server-side logic.

Overview

This use case consists of a signup form with 3 steps and a flow connected to each one:

  • Form step 1 will ask for an email address and a password, and the linked flow will check if the email is already registered.
  • Form step 2 will ask for a mobile phone number and the linked flow will generate and send a temporary code (OTP) to it.
  • Form step 3 will ask for the temporary code (OTP) and the linked flow will check if it is correct, register the user and submit the form.

You can create it from scratch or use the Phone verification template. If you choose the template, two of the steps and the corresponding flows will be automatically created, and you will only need to make minor changes on them and build the first step and its flow.

Create a three-step form

First, add an Email field and a Password field in the first step with the following settings:

  • ID: change them to ‘email’ and ‘password’ in order to make them easier to reference.
  • Required: enable this option in both fields to make them mandatory.

In form step 2, include a HTML block and Phone field with these settings:

  • ID: change it to ‘phone’.
  • Required: enable this option.

We are going to use the HTML block to add the phone library jackocnr/intl-tel-input, a JavaScript plugin for entering and validating international telephone numbers. 

To add the library, just paste this code inside the <div></div> of the HTML block:

<style>
  .af-field-phone .iti {
  	width: 100%;
  }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/intlTelInput.min.js" integrity="sha512-DNeDhsl+FWnx5B1EQzsayHMyP6Xl/Mg+vcnFPXGNjUZrW28hQaa1+A4qL9M+AiOMmkAhKAWYHh1a+t6qxthzUw==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/css/intlTelInput.min.css" integrity="sha512-yye/u0ehQsrVrfSd6biT17t39Rg9kNc+vENcCXZuMz2a+LWFGvXUnYuWUW6pbfYj1jcBb/C39UZw2ciQvwDDvg==" crossorigin="anonymous" />
<script>
const phoneFieldId = 'phone';
const phoneInput = document.querySelector('.af-field-' + phoneFieldId + ' input');
const iti = window.intlTelInput(phoneInput, {
  initialCountry: 'us',
  separateDialCode: true
});
phoneInput.addEventListener('countrychange', function(e) {
  $form.setHiddenField('countryCode', iti.getSelectedCountryData().dialCode);
});
</script>

Click on the eye icon from the top of the form to add a hidden field configured like this:

  • Write “countryCode” in the first input and set ‘1’ as default value in the second one. 

As you can see in the code of the HTML block, initialCountry is set to “us” so you must initialize your “countryCode” with the USA code that is “1”. If you want to set another initialCountry, remember to update your “countryCode” default value too.

On form step three, include a Text field to ask the user for the temporary code that will be sent by SMS. Configure it as follows:

  • ID: change it to ‘code’.
  • Required: enable this option.

Finally, go to the Flows tab — on the light grey menu on the left — and create a flow linked to each step of the form, as you can see in the picture.

Create new flows by clicking on the plus icon. If you have used the Phone verification template, you will only have to create the signup flow and make a few changes in the other two flows. Finally, publish the changes and open the first flow on a new tab.

Flow 1: Check email

The flow connected to the first step of the form will check if the email is already registered on our API, and it will have this structure:

First, include a HTTP Request action with these settings:

  • ID: change it to ‘checkEmail’ to make it easier to reference.
  • URL: paste the registration URL of your API.
  • Method: choose POST.
  • Content type: choose application/json.
  • Body
{
  "sub": "{{input.body.email}}"
}

If needed, add the Authorization header and the secret API key of your API in the Headers section. Remember that these settings may vary depending on how your API is configured.

Then, add an If/then condition action to create two branches and trigger different actions based on whether the mail is already registered or not. 

To configure this action we will set two different conditions:

  • Condition: reference again the {{checkEmail.body.error_code}} variable from the outputs of the previous action, set ‘is equal to’ as the condition and write the error string ‘unknown_sub’ in the second input.

In the False branch, include a Show error message action and personalize the text to invite the user to log in instead.

In the True branch, include a Go to the next form step action, which does not need configuration, and publish the changes.

Flow 2: Generate and send the OTP

The flow connected to the second step of the form will generate an OTP and send it to the user by SMS, and it will have this structure:

First, include a Generate one-time password action and configure it as follows:

  • ID: change it to ‘generateOtp’.
  • Reference value: reference the {{input.body.countryCode}} and the {{input.body.phone}} variables from the form. 
  • Code length: define the length of the code that will generate the action.

Then add a Send SMS with Twilio action, to send the one-time password by SMS. For testing purposes, you can use the Arengu sending sms action.

To configure the Send SMS with Twilio action:

  • Connection: select the Twilio connection that you want to use. If you don't have any created, click on the plus button to create a new one. If you still don't have the connection data, you can create an empty connection and add them later in the vault.
  • From: include the sender phone number.
  • To: reference the +{{input.body.countryCode}}{{input.body.phone}} variables from the form by clicking on the plus button.
  • Message: write the SMS content and include the {{generateOtp.code}} variable from the outputs of the previous action after an execution of the flow.

Include an If/then condition action to manage Twilio's responses, with these settings:

  • Condition: reference the {{sendSms.success}} variables from the previous action and set ‘is true’ as condition.

In the False branch, include a Show error message action with these settings:

  • Error message: reference the {{sendSms.body.error_message}} variable from the outputs of the Twilio action, to display the proper error message in the form.

In the True branch, include a Go to the next form step action, which does not need configuration, and publish the changes.

Flow 3: Verify the OTP, signup and submit

The flow connected to the third step of the form will verify the code input by the user in the form, register the user and submit the form. This flow will have this structure:

First, include a Verify one-time password action with these settings:

  • ID: change it to ‘verifyOtp’.
  • Reference value: reference the {{input.body.countryCode}} and the {{input.body.phone}} variables from the form.
  • Code value: reference the {{input.body.code}} variable from the form.

Then add an If/then condition action and configure it as follows:

  • Condition: reference the {{verifyOtp.valid}} from the outputs of the previous action after an execution of the flow and set ‘is true’ as condition.

In the False branch, include a Show error message action and personalize the message that will be shown to the user in case the temporary code is not correct.

In the True branch, include a HTTP Request action to register the user:

  • ID: change it to ‘signup’.
  • URL: paste the registration URL of your API.
  • Method: choose POST.
  • Content type: application/json.
  • Body:
{
  "sub": "{{input.body.email}}",  
  "password": "{{input.body.password}}"
}

If needed, add the Authorization header and the secret API key of your API in the Headers section. Remember that these settings may vary depending on how your API is configured.

Then add an If/then condition action to create two branches and trigger different actions based on if the signup is successful or not. 

To configure this action:

  • Condition: reference the {{signup.success}} variable from the previous action and set ‘is true’ as condition. Get the variable on the plus button after a flow execution.

In the False branch, include a Show error message action with these settings:

  • Error message: reference the {{signup.body.error_message}} variable from the outputs of the HTTP Request actions after an execution of the flow, to display the proper error message in the form.

In the True branch, include a Submit the form action and customize the message to display after submitting the form. You can also include here the destination URL to which the user will be redirected. Then, publish the changes.

Preview, test and debug

Go back to the Form editor and click on the Preview button to test the form. Check if everything is working properly, action by action, on the Executions tab of each flow.

Haven't you tried Arengu yet? Sign up free or schedule a demo with our team!

You might like to read

Getting started with Arengu

Arengu allows you to build all your user flows connected to your current stack, and avoids coding all the UI, complex integrations, validations or logic from scratch. Try it for free and start building faster and scaling your application needs as they grow.