I have a PHP contact form that performs validation via AJAX/JSON on the server side and pushes errors to Javascript to print out the errors and alter the HTML/CSS accordingly.

How can I properly implement Google ReCaptcha with AJAX validation?

Here is my code attempt.

ReCaptcha Snippet:

PHP Code:
        //reCAPTCHA validation
        
if (isset($_POST['g-recaptcha-response'])) {

            require(
'component/recaptcha/src/autoload.php');

            
$recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\SocketPost());

            
$resp $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

              if (!
$resp->isSuccess()) {
                    
$errors json_encode(array('type'=>'error''text' => 'Captcha is Required!'));
                    die(
$output);
              }
        } 
PHP:

PHP Code:
    <?php
  
    $errors         
= array();      // array to hold validation errors
    
$data             = array();         // array to pass back data
  
    // validate the variables ======================================================
        // if any of these variables don't exist, add an error to our $errors array
  
        
if (empty($_POST['firstName']))
            
$errors['firstName'] = 'First Name is required.';
  
        if (empty(
$_POST['lastName']))
            
$errors['lastName'] = 'Last Name is required.';
  
        if (empty(
$_POST['companyName']))
            
$errors['companyName'] = 'Company Name is required.';
  
        if (empty(
$_POST['companyAddress']))
            
$errors['companyAddress'] = 'Company Address is required.';
  
        if (empty(
$_POST['city']))
            
$errors['city'] = 'City is required.';
  
        if (empty(
$_POST['state']))
            
$errors['state'] = 'State is required.';
  
        if (empty(
$_POST['emailAddress']))
            
$errors['emailAddress'] = 'Email Address is required.';
  
        if (empty(
$_POST['comment']))
            
$errors['comment'] = 'Comment is required.';
  
            
//reCAPTCHA validation
            
if (isset($_POST['g-recaptcha-response'])) {
  
                require(
'component/recaptcha/src/autoload.php');
  
                
$recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\SocketPost());
  
                
$resp $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
  
                  if (!
$resp->isSuccess()) {
                        
$errors json_encode(array('type'=>'error''text' => 'Captcha is Required!'));
                        die(
$output);
                  }
            }
  
  
    
// return a response ===========================================================
  
        // if there are any errors in our errors array, return a success boolean of false
        
if ( ! empty($errors)) {
  
            
// if there are items in our errors array, return those errors
            
$data['success'] = false;
            
$data['errors']  = $errors;
        } else {
  
            
// if there are no errors process our form, then return a message
  
            // DO ALL YOUR FORM PROCESSING HERE
            // THIS CAN BE WHATEVER YOU WANT TO DO (LOGIN, SAVE, UPDATE, WHATEVER)
  
            // show a message of success and provide a true success variable
            
$data['success'] = true;
            
$data['message'] = 'Success!';
        }
  
        
// return all our data to an AJAX call
        
echo json_encode($data);
Javascript:

Code:
    // Start
    $(document).ready(function() {
  
        // process the form
        $('form').submit(function(event) {
  
            $('.form-group').removeClass('has-error'); // remove the error class
            $('.help-block').remove(); // remove the error text
  
            // get the form data
            // there are many ways to get this data using jQuery (you can use the class or id also)
            var formData = {
                'firstName'                 : $('input[name=firstName]').val(),
                'lastName'                 : $('input[name=lastName]').val(),
                'companyName'                 : $('input[name=companyName]').val(),
                'companyAddress'                 : $('input[name=companyAddress]').val(),
                'city'                 : $('input[name=city]').val(),
                'state'                 : $('input[name=state]').val(),
                'emailAddress'             : $('input[name=emailAddress]').val(),
                'comment'     : $('input[name=comment]').val()
            };
  
            // process the form
            $.ajax({
                type         : 'POST', // define the type of HTTP verb we want to use (POST for our form)
                url         : 'formMaster.php', // the url where we want to POST
                data         : formData, // our data object
                dataType     : 'json', // what type of data do we expect back from the server
                encode         : true
            })
                // using the done promise callback
                .done(function(data) {
  
                    // log data to the console so we can see
                    console.log(data);
  
                    // here we will handle errors and validation messages
                    if ( ! data.success) {
  
                        // handle errors for name ---------------
                        if (data.errors.firstName) {
                            $('#firstName-group').addClass('has-error'); // add the error class to show red input
                            $('#firstName-group').append('<div class="help-block">' + data.errors.firstName + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for name ---------------
                        if (data.errors.lastName) {
                            $('#lastName-group').addClass('has-error'); // add the error class to show red input
                            $('#lastName-group').append('<div class="help-block">' + data.errors.lastName + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for name ---------------
                        if (data.errors.companyName) {
                            $('#companyName-group').addClass('has-error'); // add the error class to show red input
                            $('#companyName-group').append('<div class="help-block">' + data.errors.companyName + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for Company Address ---------------
                        if (data.errors.companyAddress) {
                            $('#companyAddress-group').addClass('has-error'); // add the error class to show red input
                            $('#companyAddress-group').append('<div class="help-block">' + data.errors.companyAddress + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for Company Address ---------------
                        if (data.errors.city) {
                            $('#city-group').addClass('has-error'); // add the error class to show red input
                            $('#city-group').append('<div class="help-block">' + data.errors.city + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for Company Address ---------------
                        if (data.errors.state) {
                            $('#state-group').addClass('has-error'); // add the error class to show red input
                            $('#state-group').append('<div class="help-block">' + data.errors.state + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for Email Address ---------------
                        if (data.errors.emailAddress) {
                            $('#emailAddress-group').addClass('has-error'); // add the error class to show red input
                            $('#emailAddress-group').append('<div class="help-block">' + data.errors.emailAddress + '</div>'); // add the actual error message under our input
                        }
  
                        // handle errors for superhero alias ---------------
                        if (data.errors.comment) {
                            $('#comment-group').addClass('has-error'); // add the error class to show red input
                            $('#comment-group').append('<div class="help-block">' + data.errors.comment + '</div>'); // add the actual error message under our input
                        }
  
                    } else {
  
                        // ALL GOOD! just show the success message!
                        $('form').append('<div class="alert alert-success">' + data.message + '</div>');
  
                        // usually after form submission, you'll want to redirect
                        // window.location = '/thank-you'; // redirect a user to another page
  
                    }
                })
  
                // using the fail promise callback
                .fail(function(data) {
  
                    // show any errors
                    // best to remove for production
                    console.log(data);
                });
  
            // stop the form from submitting the normal way and refreshing the page
            event.preventDefault();
        });
  
    });

Right now I am just honestly confused on how to get this to work properly. Does the validation answer is obtained by Javascript or PHP or does Javascript pass it on to PHP? If there is an error how can I pass it to Javascript to print the error?

Am I correct?