2

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
+50

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/

6
  • Thanks for your help! This doesn't seem to stop them from not checking the box. I've tried both codes. Any ideas? The system still let's them go to the next stage if they skip the validation at all. As for Caledera it looks great: i'll look into it next, but feel this project is almost complete so if i could get it done with where it is I would be ecstatic. the reason i'm using custom code is this is the code that Merchantone provided. – rudtek Nov 14 '16 at 19:35
  • don't i need to call the function? I've added the entire php file from merchant one (above) to show why it's all in the same page. – rudtek Nov 14 '16 at 20:27
  • ahh that's right, updated the code should work now. Just needed to run captcha check when DO_STEP_1 is not empty, and then in the function to check recaptcha, if the response is empty, immediately return false – sMyles Nov 14 '16 at 22:57
  • I'm trying, i promise! Thanks for staying with me. I tried both codes that you updated. I'm not getting any change. no errors reported in my error log or on screen. It doesn't seem like the function is being called. – rudtek Nov 14 '16 at 23:14
  • Let us continue this discussion in chat. – sMyles Nov 14 '16 at 23:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.