Integrate Google reCAPTCHA Checkbox with PHP

Protecting a PHP contact form from spam is no longer just about checking whether a visitor ticked an “I’m not a robot” checkbox. A more robust implementation should validate the reCAPTCHA response on the server, inspect the assessment returned by Google’s reCAPTCHA Enterprise API, and make the final decision based on the risk score.

In this tutorial, we will integrate a Google reCAPTCHA Enterprise Checkbox into a PHP contact form and verify it on the server using a score-based decision model.

The Google reCAPTCHA Checkbox (v2) is a user-friendly way to protect your website from spam and abuse. It requires users to check a box to prove they are human, while also analyzing their behavior to determine the likelihood of them being a bot. By using the reCAPTCHA Enterprise API, we can get a risk score for each submission and make informed decisions about whether to accept or reject it.

What We’ll Build

In this example, we will create a simple contact form that includes a reCAPTCHA checkbox. When the form is submitted, we will send the reCAPTCHA response to the server for verification. The server will then call the reCAPTCHA Enterprise API to get a risk score and decide whether to accept or reject the submission based on that score.

The Google reCAPTCHA with PHP implementation uses three PHP files:

  1. config.php: Stores Google Cloud and reCAPTCHA configuration.
  2. index.php: Displays the contact form with the reCAPTCHA checkbox.
  3. process_form.php: Handles the form submission, verifies the reCAPTCHA response, and makes a decision based on the risk score.

Understand How the Integration Works

Before writing the PHP code, it is important to understand the difference between the checkbox and the score.

The checkbox is the user-facing part of the integration. It gives the visitor an explicit reCAPTCHA interaction.

The score is the server-side risk signal returned by the reCAPTCHA Enterprise assessment.

So, these are two different things:

Checkbox → User completes reCAPTCHA → Token generated → Server validates token → Google returns risk assessment → PHP evaluates score

Simply receiving a token is not enough. The backend should create an assessment and verify that the token is valid before trusting the score.

Google specifically recommends creating an assessment from the backend to verify the token and assess the risk associated with the interaction.

Step 1: Create a reCAPTCHA Checkbox Key

The simplest way to create a reCAPTCHA key is through the reCAPTCHA Admin console.

  1. Go to the Google Cloud Fraud Defense Admin console.
  2. Create a new reCAPTCHA checkbox key by filling out the form with your website’s domain and selecting the “Checkbox” option.
    • Enter Label to identify the key.
    • Select the Challenge (v2) » I’m not a robot tickbox option for the reCAPTCHA type.
    • Enter your website’s domain (e.g., example.com) in the Domains field.
    • If you are new to the Google Cloud console, then Project Name will be automatically created for you (read the terms of service, and select the checkbox). Otherwise, select an existing Google Cloud project.
    • Click Submit.
  3. The reCAPTCHA checkbox Site Key and Secret Key will be generated.
  4. Note down the Site Key for use in your PHP code.
create-google-recaptcha-admin-api-keys-codexworld

Step 2: Set Up Google Cloud Project

To use Google reCAPTCHA Enterprise, you need to set up a project in the Google Cloud Console and enable the reCAPTCHA Enterprise API.

Since, you already created a reCAPTCHA key in the reCAPTCHA Admin console, you don’t need to create a new project in the Google Cloud Console. You can use the same project that was automatically created for you when you created the reCAPTCHA key.

  1. Click on the VIEW IN CLOUD CONSOLE and you will be directed to the Google Cloud Console.
  2. Navigate to the Google Cloud APIs & Services » Credentials page.
  3. Create a new API key by clicking Create Credentials and selecting API Key.
    – In Select API restrictions, choose reCAPTCHA Enterprise API from the list of APIs.
  4. Click Create.
  5. Note down the API Key along with the Project ID for use in your PHP code.

After completing the above steps, you will have the necessary keys (reCAPTCHA Site Key, API Key, and Project ID) to integrate reCAPTCHA Enterprise into your PHP application.

Step 3: Configure PHP Application

Create a configuration file (e.g., config.php) in your PHP application to store the reCAPTCHA Site Key, API Key, and Project ID as constants or variables. This will allow you to easily access these keys throughout your application.

<?php 
// Define constants for Google reCAPTCHA Enterprise configuration
define('GCP_PROJECT_ID', '_YOUR_GOOGLE_CLOUD_PROJECT_ID_HERE_');
define('GCP_API_KEY', '_GOOGLE_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 4: Implement reCAPTCHA in the HTML Form

Build your HTML form (e.g., index.php) and include the reCAPTCHA checkbox using the Site Key.

First, include the reCAPTCHA Enterprise JavaScript API in the <head> section of your HTML:

<script src="https://www.google.com/recaptcha/enterprise.js" async defer></script>

Create a simple contact form with fields for name, email, subject, and message. Add the reCAPTCHA checkbox to the form, the data-sitekey attribute should be set to your reCAPTCHA Site Key and the data-action attribute should be set to a custom action name (e.g., “submit”).

<form method="POST" action="process_form.php">
    <!-- 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 more about your inquiry..." required></textarea>
    </div>

    <div class="form-group">
        <!-- Google reCAPTCHA Checkbox -->
        <div class="g-recaptcha" data-sitekey="YOUR_RECAPTCHA_SITE_KEY" data-action="submit"></div>
    </div>
    
    <!-- Submit Button -->
    <input type="submit" name="submit" value="Send Message" class="form-submit">
</form>

On form submission, the reCAPTCHA checkbox will generate a response token that will be sent to the server (process_form.php) along with the form data.

Step 5: Handle Form Submission and Verify reCAPTCHA

In your form submission handler (e.g., process_form.php), you will need to capture the reCAPTCHA response token from the form submission and send it to the reCAPTCHA Enterprise API for verification.

  • Include configuration file to access reCAPTCHA settings.
  • Retrieve the reCAPTCHA response token from the form submission.
  • Use the API Key and Project ID to authenticate your request to the reCAPTCHA Enterprise API.
  • Send a POST request to the reCAPTCHA Enterprise API endpoint with the token and your project information using PHP cURL. The API will return a risk score and other assessment details.
  • Based on the risk score returned by the API, you can decide whether to accept or reject the form submission. For example, you might choose to accept submissions with a score above 0.5 and reject those below that threshold. You can also log the assessment details for further analysis or debugging.
<?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($email, FILTER_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($curl, CURLINFO_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($response, true);
                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 6: Display Results

After processing the form submission and evaluating the risk score, you can display an appropriate message to the user. If the submission is accepted, you might show a success message. If it is rejected due to a low risk score, you can inform the user that their submission could not be processed and suggest trying again later.

If you want to display the status message on the same page as the form, do the following:

  • Include handling logic in the index.php file to check for a status message passed from process_form.php.
    require_once 'process_form.php';
  • Use PHP to display the message in a user-friendly format, such as a styled alert box or a notification area on the form page.
    <?php if (!empty($response['message'])): ?>
        <div class="alert alert-<?php echo $response['success'] ? 'success' : 'error'; ?>">
            <?php echo htmlspecialchars($response['message']); ?>
        </div>
    <?php endif; ?>

Note: Ensure that you remove process_form.php from the form’s action attribute and instead submit the form to index.php to handle the status message display.

Conclusion

Integrating Google reCAPTCHA Enterprise into a PHP contact form is more effective when the implementation treats reCAPTCHA as a server-side risk assessment system, rather than merely a checkbox. By validating the reCAPTCHA response on the server and using the risk score to make decisions, you can significantly reduce spam submissions and improve the security of your contact form.

This approach provides a clean separation between the public reCAPTCHA widget and the private server-side verification logic, while giving the PHP application a configurable risk-based decision instead of relying solely on whether the checkbox was completed.

Understanding Checkbox vs. Score-Based reCAPTCHA:
The terminology can be confusing because the implementation can use a checkbox key while the backend still receives a risk score.

  • Checkbox key → Displays the checkbox and may present a challenge.
  • Score-based key → Does not display the “I’m not a robot” checkbox and instead produces risk signals without a visible CAPTCHA challenge.

If you want to use a score-based key and don’t want to display the checkbox, see our Google reCAPTCHA v3 with PHP tutorial. It uses a score-based key and does not display the checkbox, but still provides risk signals for backend verification.

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

52 Comments

  1. Emmanuel Abruquah Said...
  2. Lucian Said...
    • CodexWorld Said...
  3. Jeremy Said...

Leave a reply

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