Google reCAPTCHA v3 with PHP: HTML Form Integration using Enterprise API

Google reCAPTCHA helps protect web forms from bots, automated submissions, and other abusive traffic without forcing legitimate visitors to solve traditional CAPTCHA challenges. With a score-based reCAPTCHA key, Google evaluates the interaction and returns a risk score that your server can use to decide whether the form submission should be accepted, rejected, or subjected to additional verification.

In this tutorial, you’ll learn how to integrate Google reCAPTCHA v3 with an HTML form using PHP and the Google reCAPTCHA Enterprise API. The implementation uses the reCAPTCHA Enterprise JavaScript API on the frontend and a server-side cURL request to create an assessment and retrieve the score.

Unlike a traditional CAPTCHA, the score-based integration works silently in the background. The visitor simply fills out the form and clicks Submit. Your JavaScript obtains a reCAPTCHA token, sends it along with the form data to PHP, and the PHP backend asks Google to evaluate the token.

What You’ll Build

In this tutorial, you’ll build a simple contact form that uses Google reCAPTCHA v3 to protect against spam and abuse. The form will include reCAPTCHA integration on the frontend and PHP backend verification to ensure only legitimate submissions are processed.

This example uses the following files:

  • config.php: Configuration file for setting up the reCAPTCHA keys and other settings.
  • index.php: The HTML form with reCAPTCHA Enterprise JavaScript API integration.
  • process_form.php: The PHP script that processes the form submission, verifies the reCAPTCHA token, and processes the email notification or database entry.

How Score-Based reCAPTCHA Works

Traditional CAPTCHA systems often ask the visitor to identify images, type distorted characters, or click a checkbox.

A score-based reCAPTCHA integration takes a different approach.

When the user performs an important action, such as submitting a contact form, the browser calls:

grecaptcha.enterprise.execute()

Google generates a token representing that interaction. Your server then sends the token to the reCAPTCHA Enterprise assessment endpoint.

Google returns information including:

  • whether the token is valid
  • the action associated with the token
  • the risk score
  • optional risk reasons

The score ranges from 0.0 to 1.0.

A score close to 1.0 indicates a low-risk interaction that is more likely to be legitimate, while a score close to 0.0 indicates higher risk. Google currently describes 11 possible score levels from 0.0 through 1.0, although access to all score levels depends on the project’s configuration and billing status.

For a contact form, you might use a policy such as:

  • 0.51.0 → Accept
  • 0.30.5 → Review / optionally accept
  • 0.00.3 → Reject or flag

These values are examples, not universal Google-recommended thresholds. Your website should determine an appropriate threshold based on its real traffic and false-positive/false-negative requirements.

Step 1: Create a reCAPTCHA key & Set Up Google Cloud Project

To use reCAPTCHA Enterprise, you need to create reCAPTCHA Site keys and enable the reCAPTCHA Enterprise API in your Google Cloud Project. Total 3 types of keys are required for reCAPTCHA Enterprise API integration:

  1. Site Key: Used in the frontend HTML to generate reCAPTCHA tokens and in the Enterprise API request payload.
  2. Project ID: Used in the backend PHP to verify the reCAPTCHA token with Google.
  3. API Key: Used to authenticate your server requests to the reCAPTCHA Enterprise API.

The simplest way to do this is to use the reCAPTCHA Admin console:

  1. Go to the Google Cloud Fraud Defense Admin console.
  2. Create a new reCAPTCHA key by filling out the required information.
    • In the Label field, enter a name that you can use to identify your site.
    • Choose Score based (v3) as reCAPTCHA type.
    • Specify the Domain(s) where the reCAPTCHA will be used.
    • If you are new to the Google Cloud console, then Project Name will be automatically created for you (just read the terms of service, and select the checkbox). Otherwise, select an existing project or create a new one.
  3. Click Submit. You will see your Site Key and Secret Key.
  4. Note down the reCAPTCHA Site Key for use in the configuration file.
create-google-recaptcha-admin-api-keys-codexworld

After creating the reCAPTCHA key, you will also need to create an API key for your Google Cloud Project to authenticate your server requests to the reCAPTCHA Enterprise API.

  1. Click on the VIEW IN CLOUD CONSOLE button available under the reCAPTCHA keys. You will be navigated to the Google Cloud Console.
  2. Navigate to the Google Cloud APIs & Services > Credentials page.
  3. Create a new API key by clicking the Create Credentials > API Key button. In Select API restrictions, choose reCAPTCHA Enterprise API.
  4. Click Create.
  5. Note down your Project ID and API Key for use in the configuration file.

Now, you have all the required keys, including the Site Key, Project ID, and API Key for your reCAPTCHA Enterprise integration.

Step 2: Configuration File

Create a file named config.php in your project directory. This file will hold your Google Cloud Project ID, API Key, reCAPTCHA Site Key, and the threshold score for accepting submissions. Here’s an example configuration:

<?php 
// Define constants for Google reCAPTCHA Enterprise configuration
define('GCP_PROJECT_ID''YOUR_GOOGLE_CLOUD_PROJECT_ID_HERE');
define('GCP_API_KEY''YOUR_PROJECT_API_KEY_HERE');
define('RECAPTCHA_SITE_KEY''YOUR_RECAPTCHA_SITE_KEY_HERE');
define('RECAPTCHA_THRESHOLD'0.5); // Minimum score required for reCAPTCHA validation

// Other configuration constants can be added here as needed, such as email settings, database credentials, etc.

Step 3: Create the HTML Contact Form

Create a file named index.php in your project directory. This file will contain the HTML form and the reCAPTCHA Enterprise JavaScript API integration.

To load reCAPTCHA on the web page, include the Enterprise JavaScript API with your score-based Site Key in the <head> section of your HTML:

<script src="https://www.google.com/recaptcha/enterprise.js?render=YOUR_RECAPTCHA_SITE_KEY"></script>

Define a JavaScript function to handle the form submission and obtain a reCAPTCHA token. The token will be sent to your PHP backend for verification.

<script>
function onSubmit(token) {
    document.getElementById("contact-form").submit();
}
</script>

Add the reCAPTCHA attributes to your form’s submit button. The data-sitekey attribute should contain your score-based Site Key, and the data-callback attribute should reference the JavaScript function that handles the token submission.

<button class="g-recaptcha"
data-sitekey="YOUR_RECAPTCHA_SITE_KEY"
data-callback="onSubmit"
data-action="submit">Submit</button>

Here’s an example of a simple contact form with reCAPTCHA v3 integration:

<form id="contact-form" method="POST" action="">
    <!-- Name Field -->
    <div class="form-group">
        <label for="name">Your Name <span class="required">*</span></label>
        <input type="text" name="name" placeholder="John Doe" required>
    </div>

    <!-- Email Field -->
    <div class="form-group">
        <label for="email">Your Email <span class="required">*</span></label>
        <input type="email" name="email" placeholder="john@example.com" required>
    </div>

    <!-- Subject Field -->
    <div class="form-group">
        <label for="subject">Subject <span class="required">*</span></label>
        <input type="text" name="subject" placeholder="How can we help?" required>
    </div>

    <!-- Message Field -->
    <div class="form-group">
        <label for="message">Message <span class="required">*</span></label>
        <textarea name="message" placeholder="Tell us about your inquiry..." required></textarea>
    </div>

    <!-- Submit Button with reCAPTCHA attributes -->
    <button class="form-submit g-recaptcha"
    data-sitekey="YOUR_RECAPTCHA_SITE_KEY"
    data-callback="onSubmit"
    data-action="submit">Send Message</button>
</form>

Step 4: Backend Verification with PHP

Create a file named process_form.php in your project directory. This file will handle the form submission, verify the reCAPTCHA token with Google, and process the form data if the score meets your threshold.

  • Include the configuration file to access your reCAPTCHA settings.
  • Check if the form was submitted via POST and retrieve the reCAPTCHA token from the form submission.
  • Prepare Google Enterprise REST endpoint URL with Project ID and API Key.
  • Build the reCAPTCHA Enterprise assessment request payload with the token and site key.
  • Send a request to Google’s reCAPTCHA verification endpoint using cURL in PHP.
  • Check the response from Google to determine if the score meets your threshold.
  • Process the form data if the verification is successful, otherwise display an error message.
<?php 
// Include the configuration file
require_once 'config.php';

// Check if the form was submitted via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
// Sanitize input fields
    
$name trim($_POST['name'] ?? '');
    
$email trim($_POST['email'] ?? '');
    
$subject trim($_POST['subject'] ?? '');
    
$message trim($_POST['message'] ?? '');

    
// Validate input fields
    
$validationErrors = [];
    if(empty(
$name)){
        
$validationErrors['name'] = 'Name is required.';
    }
    if(empty(
$email)){
        
$validationErrors['email'] = 'Email is required.';
    } elseif(!
filter_var($emailFILTER_VALIDATE_EMAIL)){
        
$validationErrors['email'] = 'Invalid email format.';
    }
    if(empty(
$subject)){
        
$validationErrors['subject'] = 'Subject is required.';
    }
    if(empty(
$message)){
        
$validationErrors['message'] = 'Message is required.';
    }

    if(!empty(
$validationErrors)){
        
// Return validation errors if any fields are invalid
        
$response = [
            
'success' => false,
            
'message' => 'Please correct the errors in the form.',
            
'errors' => $validationErrors
        
];
    }else{
        
// Verify the reCAPTCHA token
        
$token $_POST['g-recaptcha-response'] ?? '';
        if(empty(
$token)){
            
$response = [
                
'success' => false,
                
'message' => 'reCAPTCHA verification failed. Please try again.',
                
'errors' => ['recaptcha' => 'reCAPTCHA token is missing.']
            ];
        }else{
            
// Create the reCAPTCHA Enterprise API endpoint URL
            
$url 'https://recaptchaenterprise.googleapis.com/v1/projects/' GCP_PROJECT_ID '/assessments?key=' GCP_API_KEY;

            
// Build the assessment request payload
            
$assessmentRequest = [
                
'event' => [
                    
'token' => $token,
                    
'siteKey' => RECAPTCHA_SITE_KEY,
                    
'expectedAction' => 'submit',
                    
'userAgent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown',
                    
'userIpAddress' => $_SERVER['REMOTE_ADDR'] ?? ''
                
]
            ];

            
// Initialize CURL and send the request to the reCAPTCHA Enterprise API
            
$curl curl_init();
            
curl_setopt_array($curl, [
                
CURLOPT_URL => $url,
                
CURLOPT_POST => true,
                
CURLOPT_POSTFIELDS => json_encode($assessmentRequest),
                
CURLOPT_RETURNTRANSFER => true,
                
CURLOPT_SSL_VERIFYPEER => true,
                
CURLOPT_SSL_VERIFYHOST => 2,
                
CURLOPT_HTTPHEADER => [
                    
'Content-Type: application/json; charset=utf-8'
                
]
            ]);
            
$response curl_exec($curl);
            
$httpCode curl_getinfo($curlCURLINFO_HTTP_CODE);
            
$curlError curl_error($curl);
            
curl_close($curl);

            if (
$curlError) {
                
$response = [
                    
'success' => false,
                    
'message' => 'Error communicating with reCAPTCHA API: ' $curlError,
                    
'errors' => ['recaptcha' => 'CURL error: ' $curlError]
                ];
            } elseif (
$httpCode !== 200) {
                
$response = [
                    
'success' => false,
                    
'message' => 'reCAPTCHA API returned an unexpected HTTP code: ' $httpCode,
                    
'errors' => ['recaptcha' => 'HTTP error code: ' $httpCode]
                ];
            } else {
                
// Decode the API response and check the assessment result
                
$assessmentResponse json_decode($responsetrue);
                if (isset(
$assessmentResponse['tokenProperties']['valid']) && $assessmentResponse['tokenProperties']['valid'] === true) {
                    
$score $assessmentResponse['riskAnalysis']['score'] ?? 0.0;
                    if (
$score >= RECAPTCHA_THRESHOLD) {
                        
// Here you would typically send the email or save the form data to a database
                        
                        // For demonstration, we'll just return a success response
                        
$response = [
                            
'success' => true,
                            
'message' => 'Thank you! Your message has been sent successfully. We will get back to you soon.'
                        
];

                        
// Unset the POST data to prevent resubmission on page refresh
                        
unset($_POST);
                    } else {
                        
$response = [
                            
'success' => false,
                            
'message' => 'reCAPTCHA verification failed. Your score was too low.',
                            
'errors' => ['recaptcha' => 'Low reCAPTCHA score: ' $score]
                        ];
                    }
                } else {
                    
$response = [
                        
'success' => false,
                        
'message' => 'Invalid reCAPTCHA token.',
                        
'errors' => ['recaptcha' => 'Token is invalid or expired.']
                    ];
                }
            }
        }
    }
}
?>

Step 5: Displaying Results

Once the form is submitted and verified, you can display the results to the user. This could be a simple success message or more detailed information about the submission.
Add the following code block in your index.php to display success or error messages based on the response from process_form.php.

<?php if (!empty($response['message'])): ?>
    <div class="alert alert-<?php echo $response['success'] ? 'success' 'error'?>">
        <?php echo htmlspecialchars($response['message']); ?>
    </div>
<?php endif; ?>

Conclusion

Adding Google reCAPTCHA v3 to an HTML contact form with PHP using the reCAPTCHA Enterprise score-based API involves three main stages:

  1. Frontend Integration: Use the reCAPTCHA Enterprise JavaScript API to generate a token when the user submits the form.
  2. Backend Verification: Send the token to your PHP backend, which will call the Google reCAPTCHA Enterprise API to retrieve a score.
  3. Decision Making: Based on the score returned by Google, decide whether to accept the submission, reject it, or require additional verification.

The frontend uses:

grecaptcha.enterprise.execute()

while the PHP backend creates an assessment through:

POST /v1/projects/PROJECT_ID/assessments

The backend should then verify the token, confirm the expected action, retrieve the risk score, and apply an application-specific threshold before processing the form.

The key principle is simple:

Never trust the browser to decide whether a submission is legitimate. Generate the token in the browser, but verify and evaluate it on the server.

With this architecture, you can add a largely invisible layer of bot and abuse protection to contact forms, registration forms, login forms, newsletter forms, and other sensitive HTML form submissions while keeping the user experience friction-free.

Looking for expert assistance to implement or extend this script’s functionality? Submit a Service Request

3 Comments

  1. Jon Said...
  2. Anuradha Said...
  3. Jan Said...

Leave a reply

construction Need this implemented in your project? Request Implementation Help → keyboard_double_arrow_up