title: How to integrate reCaptchaV3 in contact form?
body: <p>First of i'm a big enthusiast but no profesional in any way, so i got some basic knowledge in coding.
  I'm trying to integrate reCaptcha V3 in my existing contact form.
  But i don't know if it's done right. I've been googling like a mad man but all the "How to's" are all doing something different. I added it yesterday using this example: <a href="https://code.tutsplus.com/tutorials/example-of-how-to-add-google-recaptcha-v3-to-a-php-form--cms-33752" rel="nofollow noreferrer">https://code.tutsplus.com/tutorials/example-of-how-to-add-google-recaptcha-v3-to-a-php-form--cms-33752</a> and got some 0.9 score results in the analytics but i'm still not really confident it works correctly.</p>
  
  <p>I tested my score with this <a href="https://recaptcha-demo.appspot.com/recaptcha-v3-request-scores.php" rel="nofollow noreferrer">https://recaptcha-demo.appspot.com/recaptcha-v3-request-scores.php</a> which results in a score of 0.9
  I tried changing the needed score to 1.0 on my own website but the submit still came through.</p>
  
  <p>This is what i added to load the reCaptcha:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html&gt;
  &lt;head&gt;
  &lt;link rel="stylesheet" href="styles/contact.css"&gt;
  &lt;link rel="stylesheet" href="styles/layout.css"&gt;
  &lt;link rel="stylesheet" href="validate/css/style.css"&gt;
                                                                  &lt;!----- SITE KEY REPCAPTCHA -----&gt;
  &lt;script src="https://www.google.com/recaptcha/api.js?render=*****"&gt;&lt;/script&gt;
  &lt;script&gt;
      grecaptcha.ready(function() {
      grecaptcha.execute('******', {action: 'contact'}).then(function(token) {
         $('#contact').prepend('&lt;input type="hidden" name="token" value="' + token + '"&gt;');
         $('#contact').prepend('&lt;input type="hidden" name="action" value="contact"&gt;');
         $('#contact').unbind('submit').submit();
      });
  });
  &lt;/script&gt;
  </code></pre>
  
  <p>The $('#contact') part give's an error in firefox console: ReferenceError: $ is not defined. But i found other pieces of code were this is also used so i guess it just works?</p>
  
  <p>This is my complete contact form:</p>
  
  <pre><code>                &lt;h1&gt;&lt;/h1&gt;
                  &lt;br /&gt;
                  &lt;h2&gt;&lt;/h2&gt;
                  &lt;h2&gt;&lt;/h2&gt;
                      &lt;?php
                          //init variables
                          $cf = array();
                          $sr = false;
  
                      if(isset($_SESSION['cf_returndata'])){
                          $cf = $_SESSION['cf_returndata'];
                          $sr = true;
                      }
                      ?&gt;
                  &lt;ul id="errors" class="&lt;?php echo ($sr &amp;&amp; !$cf['form_ok']) ? 'visible' : ''; ?&gt;"&gt;
                      &lt;li id="info"&gt;Er zijn wat problemen met je bericht:&lt;/li&gt;
                          &lt;?php 
                              if(isset($cf['errors']) &amp;&amp; count($cf['errors']) &gt; 0) :
                              foreach($cf['errors'] as $error) :
                          ?&gt;
                      &lt;li&gt;&lt;?php echo $error ?&gt;&lt;/li&gt;
                          &lt;?php
                              endforeach;
                              endif;
                          ?&gt;
                  &lt;/ul&gt;
                      &lt;p id="success" class="&lt;?php echo ($sr &amp;&amp; $cf['form_ok']) ? 'visible' : ''; ?&gt;"&gt;Bedankt voor je bericht!&lt;br /&gt;Je hoort zo snel mogelijk van ons!&lt;/p&gt;
                  &lt;form id="contact" method="post" action="validate/process.php"&gt;
                      &lt;label for="name"&gt;Naam: &lt;span class="required"&gt;*&lt;/span&gt;&lt;/label&gt;
                      &lt;input type="text" id="name" name="name" value="&lt;?php echo ($sr &amp;&amp; !$cf['form_ok']) ? $cf['posted_form_data']['name'] : '' ?&gt;" placeholder="naam" /&gt;
  
                      &lt;label for="email"&gt;Email: &lt;span class="required"&gt;*&lt;/span&gt;&lt;/label&gt;
                      &lt;input type="email" id="email" name="email" value="&lt;?php echo ($sr &amp;&amp; !$cf['form_ok']) ? $cf['posted_form_data']['email'] : '' ?&gt;" placeholder="naam@voorbeeld.nl"  /&gt;
  
                      &lt;label for="telephone"&gt;Telefoon:&lt;/label&gt;
                      &lt;input type="tel" id="telephone" name="telephone"  placeholder="0612345678" value="&lt;?php echo ($sr &amp;&amp; !$cf['form_ok']) ? $cf['posted_form_data']['telephone'] : '' ?&gt;" /&gt;
  
                      &lt;label for="enquiry"&gt;Onderwerp: &lt;span class="required"&gt;*&lt;/span&gt;&lt;/label&gt;
                      &lt;select required id="enquiry" name="enquiry"&gt;
                          &lt;option value="" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Maak keuze') ? "selected='selected'" : '' ?&gt;&gt;Maak een keuze..&lt;/option&gt;
                          &lt;option value="steppen" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Steppen') ? "selected='selected'" : '' ?&gt;&gt;Steppen&lt;/option&gt;
                          &lt;option value="walks" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Walks') ? "selected='selected'" : '' ?&gt;&gt;Walks&lt;/option&gt;
                          &lt;option value="sessions" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Privatewalks') ? "selected='selected'" : '' ?&gt;&gt;Persoonlijke begeleiding (Private walks)&lt;/option&gt;
                          &lt;option value="sessions" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Events') ? "selected='selected'" : '' ?&gt;&gt;Events&lt;/option&gt;
                          &lt;option value="foto" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Foto') ? "selected='selected'" : '' ?&gt;&gt;Foto's opvragen&lt;/option&gt;
                          &lt;option value="website" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Website') ? "selected='selected'" : '' ?&gt;&gt;Website&lt;/option&gt;
                          &lt;option value="overig" &lt;?php echo ($sr &amp;&amp; !$cf['form_ok'] &amp;&amp; $cf['posted_form_data']['enquiry'] == 'Overig...') ? "selected='selected'" : '' ?&gt;&gt;Overig...&lt;/option&gt;
                      &lt;/select&gt;
  
                      &lt;label for="message"&gt;Bericht: &lt;span class="required"&gt;*&lt;/span&gt;&lt;/label&gt;
                      &lt;textarea id="message" name="message" placeholder="Minimaal 20 karakters"&gt;&lt;?php echo ($sr &amp;&amp; !$cf['form_ok']) ? $cf['posted_form_data']['message'] : '' ?&gt;&lt;/textarea&gt;
                      &lt;input type="submit" value="Versturen" id="submit-button" /&gt;
                      &lt;p id="req-field-desc"&gt;Velden met een &lt;span class="required"&gt;*&lt;/span&gt; zijn verplicht.&lt;/p&gt;
                      &lt;br /&gt;
  
                 &lt;/form&gt;
                  &lt;?php unset($_SESSION['cf_returndata']); ?&gt;
                  &lt;/div&gt;
  </code></pre>
  
  <p>And this is my form validation file:</p>
  
  <pre><code>if( isset($_POST) ){
  
      //form validation vars
      $formok = true;
      $errors = array();
  
      //sumbission data
      $ipaddress = $_SERVER['REMOTE_ADDR'];
      $date = date('d/m/Y');
      $time = date('H:i:s');
  
      //form data
      $name = $_POST['name']; 
      $email = $_POST['email'];
      $telephone = $_POST['telephone'];
      $enquiry = $_POST['enquiry'];
      $message = $_POST['message'];
  
      //validate form data
  
      //validate name is not empty
      if(empty($name)){
          $formok = false;
          $errors[] = "U heeft geen naam ingevuld";
      } elseif(!preg_match("/^[a-zA-Z ]*$/",$name)) {
          $formok = false;
          $errors[] = "Uw naam mag alleen letters en/of spaties bevatten";
      }
  
      //validate email address is not empty
      if(empty($email)){
          $formok = false;
          $errors[] = "U heeft geen email adres ingevuld";
      //validate email address is valid
      } elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
          $formok = false;
          $errors[] = "U heeft geen geldig email adres ingevuld";
      }
  
      //validate message is not empty
      if(empty($message)){
          $formok = false;
          $errors[] = "U heeft geen bericht ingevuld";
      }
      //validate message is greater than 20 charcters
      elseif(strlen($message) &lt; 20){
          $formok = false;
          $errors[] = "Uw bericht moet minimaal 20 karakters bevatten";
      }
  
      // reCaptcha V3 stuff
          define("RECAPTCHA_V3_SECRET_KEY", '*****');
          $token = $_POST['token'];
          $action = $_POST['action'];
  
      // call curl to POST request
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
          curl_setopt($ch, CURLOPT_POST, 1);
          curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' =&gt; RECAPTCHA_V3_SECRET_KEY, 'response' =&gt; $token)));
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          $response = curl_exec($ch);
          curl_close($ch);
          $arrResponse = json_decode($response, true);
  
      // verify the response
          if($arrResponse["success"] == '1' &amp;&amp; $arrResponse["action"] == $action &amp;&amp; $arrResponse["score"] &gt;= 0.5) {
              // valid submission
              // go ahead and do necessary stuff
          } else {
              $errors[] = "reCaptcha you are a bot";
              // spam submission
              // show error message
          }
  
      //send email if all is ok
      if($formok){
          $headers = "From: $email" . "\r\n";
          $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
  
          $emailbody = "";
  
          mail("",'',$emailbody,$headers);
  
      }
      //what we need to return back to our form
      $returndata = array(
          'posted_form_data' =&gt; array(
              'name' =&gt; $name,
              'email' =&gt; $email,
              'telephone' =&gt; $telephone,
              'enquiry' =&gt; $enquiry,
              'message' =&gt; $message
          ),
          'form_ok' =&gt; $formok,
          'errors' =&gt; $errors
      );
  
  
      //if this is not an ajax request
      if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) &amp;&amp; strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest'){
          //set session variables
          session_start();
          $_SESSION['cf_returndata'] = $returndata;
  
          //redirect back to form
          header('location: ' . $_SERVER['HTTP_REFERER']);
      }
  }
  </code></pre>
  
  <p>I tried adding $formok = false; in the verify response section:</p>
  
  <pre><code>        if($arrResponse["success"] == '1' &amp;&amp; $arrResponse["action"] == $action &amp;&amp; $arrResponse["score"] &gt;= 0.5) {
              // valid submission
              // go ahead and do necessary stuff
          } else {
      ---------&gt;      $formok = false;
                          $errors[] = "reCaptcha you are a bot";
              // spam submission
              // show error message
          }
  </code></pre>
  
  <p>But this results in a constant failure to submit.</p>
  
  <p>I hope someone can shed some light on how i'm doing. Is this the way, should it work? or have i made some mistake's?</p>
  
  <p>Thanks in advance!</p>