Help with verifying google recaptcha in a custom form

I am trying to add a recaptcha to my custom field. I have created a custom form in a page template and this the part of my code I think is relevant (don’t worry that API key is MerchantOne’s public demo api so it’s not personal):

// API Setup parameters
$gatewayURL = 'https://secure.merchantonegateway.com/api/v2/three-step';
$APIKey = '2F822Rw39fx762MaV7Yy86jXGTC7sCDy';


// If there is no POST data or a token-id, print the initial shopping cart form to get ready for Step One.
if (empty($_POST['DO_STEP_1']) && empty($_GET['token-id'])) {

    print '  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
    print '
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hansen Hunter Collect non-sensitive Customer Info</title>
      </head>
      <body>
      <p>We are pleased to offer the option for you to securely pay your Hansen Hunter & Co. invoice online.</p>
      <h2 class="pad">Invoice Details</h2>


        <form action="" method="post">
          <table>
          <tr><td><input type="text" name="shipping-address-first-name" placeholder="First Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-last-name" placeholder="Last Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-company" placeholder="Company" required></td></tr>
          <tr><td><input type="text" name="billing-address-phone" placeholder="Phone Number" required></td></tr>
          <tr><td><input type="text" name="billing-address-email" placeholder="Email Address" required></td></tr>
          <tr><td><input type="text" name="billing-invoice" placeholder="Invoice or Customer Number"></td></tr>
          <tr><td><input type="text" name="billing-amount" placeholder="Total Amount" required></td></tr>

          <tr><td><h4><br />Payment Information</h4></td></tr>

          <tr><td><input type="text" name="billing-address-first-name" placeholder="Cardholder First Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-last-name" placeholder="Cardholder Last Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-address1" placeholder="Address" required></td></tr>
          <tr><td><input type="text" name="billing-address-address2" placeholder="Address 2"></td></tr>
          <tr><td><input type="text" name="billing-address-city" placeholder="City" required></td></tr>
          <tr><td><input type="text" name="billing-address-state" placeholder="State" required></td></tr>
          <tr><td><input type="text" name="billing-address-zip" placeholder="Zip/Postal Code" required></td></tr>
          <tr><td><input type="text" name="billing-address-country" placeholder="Country" value="US" required></td></tr>
       <tr><td><div class="g-recaptcha" data-sitekey="6Lc2MiUTAAAAAGJeGAlku50gFi7hFKvIitP_-3e0"></div></td></tr>
          <tr><td><input type="submit" class="btn pad" value="Continue"><input type="hidden" name ="DO_STEP_1" value="true"></td></tr>
          </table>
        </form>

    ';
}else if (!empty($_POST['DO_STEP_1'])) {

    // Initiate Step One: Now that we've collected the non-sensitive payment information, we can combine other order information and build the XML format.

I’ve added this code to my functions.php to add the google api:

add_action('wp_head','hook_recaptca');

function hook_recaptca() {

    $output="<script src="https://www.google.com/recaptcha/api.js"></script>";

    echo $output;
} 

This allows my recaptcha to show up. The problem is it’s not verifying yet.

I know I have these 2 pieces of code to still add:

/**
 * Send a GET request to verify CAPTCHA challenge
 *
 * @return bool
 */
function captcha_verification() {

    $response = isset( $_POST['g-recaptcha-response'] ) ? esc_attr( $_POST['g-recaptcha-response'] ) : '';

    $remote_ip = $_SERVER["REMOTE_ADDR"];

    // make a GET request to the Google reCAPTCHA Server
    $request = wp_remote_get(
        'https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=" . $response . "&remoteip=' . $remote_ip
    );

    // get the request response body
    $response_body = wp_remote_retrieve_body( $request );

    $result = json_decode( $response_body, true );

    return $result['success'];
}

and

/**
 * Verify the CAPTCHA answer
 *
 * @param $user string login username
 * @param $password string login password
 *
 * @return WP_Error|WP_user
 */
function validate_captcha( $user, $password ) {

    if ( isset( $_POST['g-recaptcha-response'] ) && !captcha_verification() ) {
        return new WP_Error( 'empty_captcha', '<strong>ERROR</strong>: Please retry CAPTCHA' );
    }

    return $user;
}

but I’m not sure how to attach them (what hook to use?) in my form so that a user is stopped if they don’t fill the checkbox. I’ve see tutorials and questions about adding to the login form or the registration form or the comments, but can’t seem to figure out how to do it to my custom form.

In case it helps, this the entire php that merchant one supplied for their integration is here:

http://pastebin.com/mR5jf5B3

1 Answer
1

You need to validate the reCAPTCHA immediately once you POST the form. You’re just sending a POST to the same page, so it should be done before any other handling.

If it does not validate, you need to show the form again, with an error message.

function recaptcha_validated(){
    if( empty( $_POST['g-recaptcha-response'] ) ) return FALSE;
    $response = wp_remote_get( add_query_arg( array(
                                              'secret'   => 'your_secret',
                                              'response' => isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : '',
                                              'remoteip' => isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']
                                          ), 'https://www.google.com/recaptcha/api/siteverify' ) );

    if( is_wp_error( $response ) || empty($response['body']) || ! ($json = json_decode( $response['body'] )) || ! $json->success ) {
        //return new WP_Error( 'validation-error',  __('reCAPTCHA validation failed. Please try again.' ) );
        return FALSE;
    }

    return TRUE;
}

// reCAPTCHA data was POSTed, let's validate it!
if( ! empty( $_POST['DO_STEP_1'] ) ){

    if( recaptcha_validated() === FALSE ){
        $recaptcha_error = TRUE;
        print '<div class="error message">' . __('reCAPTCHA failed, please try again.') . '</div>';
    }

}

// Because we want to show the form again if there was an error, we first check if error var is set OR if DO_STEP_1 and token-id are empty
if ( isset( $recaptcha_error ) || ( empty($_POST['DO_STEP_1']) && empty($_GET['token-id']) ) ) {
     print '<p>We are pleased to offer the option for you to securely pay your Hansen Hunter & Co. invoice online.</p>
      <h2 class="pad">Invoice Details</h2>    
        <form method="post">
          <table>
          <tr><td><input type="text" name="shipping-address-first-name" placeholder="First Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-last-name" placeholder="Last Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-company" placeholder="Company" required></td></tr>
          <tr><td><input type="text" name="billing-address-phone" placeholder="Phone Number" required></td></tr>
          <tr><td><input type="text" name="billing-address-email" placeholder="Email Address" required></td></tr>
          <tr><td><input type="text" name="billing-invoice" placeholder="Invoice or Customer Number"></td></tr>
          <tr><td><input type="text" name="billing-amount" placeholder="Total Amount" required></td></tr>

          <tr><td><h4><br />Payment Information</h4></td></tr>

          <tr><td><input type="text" name="billing-address-first-name" placeholder="Cardholder First Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-last-name" placeholder="Cardholder Last Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-address1" placeholder="Address" required></td></tr>
          <tr><td><input type="text" name="billing-address-address2" placeholder="Address 2"></td></tr>
          <tr><td><input type="text" name="billing-address-city" placeholder="City" required></td></tr>
          <tr><td><input type="text" name="billing-address-state" placeholder="State" required></td></tr>
          <tr><td><input type="text" name="billing-address-zip" placeholder="Zip/Postal Code" required></td></tr>
          <tr><td><input type="text" name="billing-address-country" placeholder="Country" value="US" required></td></tr>
       <tr><td><div class="g-recaptcha" data-sitekey="6Lc2MiUTAAAAAGJeGAlku50gFi7hFKvIitP_-3e0"></div></td></tr>
          <tr><td><input type="submit" class="btn pad" value="Continue"><input type="hidden" name="DO_STEP_1" value="true"></td></tr>
          </table>
        </form>

    ';
}

Is there any reason you’re not using a plugin like Caldera Forms instead of completely custom code? The plugin would handle the majority of these things for you, including field HTML output, reCAPTCHA output/validation, and still provide you with actions/hooks that can be called on form submission to allow you to handle with custom code:

https://wordpress.org/plugins/caldera-forms/

https://calderawp.com/downloads/caldera-forms-run-action/

https://wordpress.org/plugins/caldera-forms-run-action/

Leave a Comment