Add a required checkbox field in WooCommerce checkout page

Here is how you can add a required checkbox field in the WooCommerce checkout page that forces a user to checkbox the request before they can proceed to payment, similar to the terms and condition checkbox.

Add Checkbox Woocommerce Checkout Page

WooCommerce Form Field

Add the code in your functions.php – the example uses the a new checkbox field named ‘checkout_checkbox

add_action( 'woocommerce_review_order_before_submit', 'bt_add_checkout_checkbox', 10 );
/**
 * Add WooCommerce additional Checkbox checkout field
 */
function bt_add_checkout_checkbox() {
   
    woocommerce_form_field( 'checkout_checkbox', array( // CSS ID
       'type'          => 'checkbox',
       'class'         => array('form-row mycheckbox'), // CSS Class
       'label_class'   => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
       'input_class'   => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
       'required'      => true, // Mandatory or Optional
       'label'         => 'Ok I agree with <a href="/checkout-checkbox" target="_blank" rel="noopener">Checkout Checkbox Page</a>', // Label and Link
    ));    
}

add_action( 'woocommerce_checkout_process', 'bt_add_checkout_checkbox_warning' );
/**
 * Alert if checkbox not checked
 */ 
function bt_add_checkout_checkbox_warning() {
    if ( ! (int) isset( $_POST['checkout_checkbox'] ) ) {
        wc_add_notice( __( 'Please acknowledge the Checkbox' ), 'error' );
    }
}

If you don’t want a warning and leave the checkbox as optional leave out the 2nd code block and change the required value in the 1st code block to false.

So change the CSS ID (checkout-checkbox)  to what you want, optional to add a secondary CSS Class and change your text Label and Link

CSS

.woocommerce-invalid #checkout-checkbox {
    outline: 2px solid red;
    outline-offset: 2px;
}

Add a bit of CSS to get the failed validation style of red box around the checkbox, use the same CSS ID.

So far the checkbox just displays on screen – see the 3 steps below to save that value to the database and display it on the backend and display it in emails.

 

Add Custom Field to Database as Order Meta

To add this field and value to the WordPress database

add_action( 'woocommerce_checkout_update_order_meta', 'bt_checkout_field_order_meta_db' );
/**
 * Add custom field as order meta with field value to database
 */
function bt_checkout_field_order_meta_db( $order_id ) {
    if ( ! empty( $_POST['checkout_checkbox'] ) ) {
        update_post_meta( $order_id, 'checkout_checkbox', sanitize_text_field( $_POST['checkout_checkbox'] ) );
    }
}

Retreive and display Custom Field to back end in WooCommerce Order Screen

To display the field and label in the backend WooCommerce order.

add_action( 'woocommerce_admin_order_data_after_billing_address', 'bt_checkout_field_display_admin_order_meta', 10, 1 );
/**
 * Display field value on the backend WooCOmmerce order
 */
function bt_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Checkout Checkbox Label').':</strong> ' . get_post_meta( $order->get_id(), 'checkout_checkbox', true ) . '<p>'; 
}

Add Custom Field to WooCommerce Emails

To display the field in emails:

add_filter('woocommerce_email_order_meta_keys', 'bt_custom_order_meta_email');

function bt_custom_order_meta_email( $keys ) {
     $keys[] = 'checkout_checkbox'; // This will look for a custom field called 'checkout_checkbox' and add it to WooCommerce emails
     return $keys;
}


The above code will drop the checkbox in as is, you may though want to use some arbitrary label and text instead, in which case you can use the woocommerce_email_order_meta_fields filter.

add_filter( 'woocommerce_email_order_meta_fields', 'bt_woocommerce_email_order_meta_fields', 10, 3 );
/**
 * Add a custom field (in an order) to the emails with text and label
 */

function bt_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
    
    $checkbox = get_post_meta( $order->get_id(), 'checkout_checkbox', true );
    
    if( $checkbox == 1 ) {
        $fields['checkout_checkbox'] = array(
            'label' => __( 'Member' ),
            'value' => __( 'Welcome Aboard' ),
        );
        return $fields;
    }
    else {
        $fields['checkout_checkbox'] = array(
            'label' => __( 'Member' ),
            'value' => __( 'See You Later' ),
        );
        return $fields;
    }
}

So we are assigning our custom field to a variable $checkbox and if that variable is checked (value of 1) it will output Member: Welcome Aboard if it is not checked it will output Member: See You Later

Ref

24 Comments

  1. Greg on June 9, 2021 at 9:02 am

    Great, thanks!

  2. Michael on June 8, 2021 at 8:51 am

    Hi,
    Hav anyone modified the code to be product specific?

    Best
    Michael

  3. Arne on June 3, 2021 at 1:40 pm

    Thanks for this great little Tutorial.

    The CSS is not working because the CSS-Ids are different (checkout_checkbox in php and checkout-checkbox in css)

    I had to add an additional:

    #checkout-checkbox {
    position: relative;
    }
    since the woocommerce classes seems to let the checkbox have an absolute position, which looks not good.

  4. JM on May 5, 2021 at 1:09 pm

    This is awesome! Massive respect to you Neil for helping newbies do what WooCommerce doesn’t.

    When checking or not checking the box, is it possible to show a different value in the email/backend? By default the value of checked box is 1, and un-checked is nothing.

    • Neil Gowran on May 6, 2021 at 12:14 am

      I updated the post so you can see how it’s possible to output different text based on whether the checkbox is checked or not.

      • JM on June 14, 2021 at 11:14 am

        You’re the best!

  5. chris on April 24, 2021 at 12:19 pm

    ok my bad, it’s working !
    my error came because I’ve translated ‘error’ in wc_add_notice in my language…
    thanks

  6. chris on April 24, 2021 at 12:08 pm

    thanks but not working, you can pass trough with last wp version 5.7.1

  7. Joel on March 9, 2021 at 4:57 am

    This was super easy to implement. Is there a way to have this recorded in the customer meta or the order meta?

  8. jacek on December 2, 2020 at 6:46 pm

    Hi, i have added your snippet to my page but unfortunately even when it is checked the error appears that it is unchecked. even if somebody want to buy my product on product page with apple pay without going to checkout page.

  9. ame bin salam on November 26, 2020 at 10:17 pm

    hi, I want to add a description before the checkbox and after that the check box. how can I do it. can any help me

    • Neil Gowran on January 18, 2021 at 10:05 pm

      You can echo out some html before and after the woocommerce_form_field

        
      echo '<h3>Hello Customer</h3>';
          woocommerce_form_field( 'checkout-checkbox', array( // CSS ID
             'type'          => 'checkbox',
             'class'         => array('form-row mycheckbox'), // CSS Class
             'label_class'   => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
             'input_class'   => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
             'required'      => true, // Mandatory or Optional
             'label'         => 'Ok I agree with <a href="/checkout-checkbox" target="_blank" rel="noopener">Checkout Checkbox Page</a>', // Label and Link
          ));    
          echo '<h3>Goodbye Customer</h3>';
      
  10. Paco on November 5, 2020 at 5:31 am

    ???????? Thank you very much for that, really very useful (͡⚈‿⚈͡).

  11. Menachem Engel on October 26, 2020 at 11:22 am

    Hi. This is so perfect for what I need on my site. Thank you so much! Any way to get this on the cart page instead of checkout and a customer wont be able to proceed to checkout unless they check the box? Thank you!

  12. Bertrand on October 16, 2020 at 10:05 am

    Hi,

    This code is really helping, thanks a lot!
    However, the required mode only works for Woocommerce bank transfer payment.

    Paypal & Stripe keep skipping the required mode for this checkbox.
    I have been looking around but do not know how to resolve this, any idea?

    thanks in advance

  13. Naomi on September 4, 2020 at 11:49 am

    Hi,
    thanks for the code, but as well as Damian, “required” is not working.

  14. Damian on September 2, 2020 at 2:07 pm

    Hi,
    Looks good, but this code is not working for me. It passes even when user will leave them not checked :/

    • Neil Gowran on September 4, 2020 at 9:42 pm

      Have updated the code snippet

      • Damian on September 4, 2020 at 10:08 pm

        Great! Work as expected :)
        Thank you again!

        I let myself extend your code and add an option to save this checkbox in WooCommerce order status for case when I have more chceckboxes (required or not) and want to know which one was selected:

        /* Save checkbox information in order details admin area meta */
        add_action(‘woocommerce_checkout_update_order_meta’, ‘checkout_order_meta’);
        function checkout_order_meta( $order_id ) {
        if ($_POST[‘checkout-checkbox’]) update_post_meta( $order_id, ‘checkout-checkbox’, esc_attr($_POST[‘checkout-checkbox’]));
        }

        /* Display field value on the order edition page */
        add_action( ‘woocommerce_admin_order_data_after_billing_address’, ‘select_checkout_field_display_admin_order_meta’, 10, 2 );
        function select_checkout_field_display_admin_order_meta($order){

        echo ‘‘.__(‘Checkbox no. 1′).’‘.__(‘ (user selected value): ‘) . get_post_meta( $order->id, ‘checkout-checkbox’, true ) . ”;

        }

        It work’s, but If you have any comment on that it would be great. I’m just a beginner.

        • Neil Gowran on September 4, 2020 at 11:51 pm

          Nice one, will have to check it out

  15. khan on August 19, 2020 at 4:55 pm

    how to add a required checkbox but only when a specific product is in checkout?

    • David on October 5, 2020 at 9:04 pm

      The same question for me… Someone knows hot to do?

  16. Damiaan van Vliet on May 18, 2020 at 6:55 am

    Great, thanks for sharing the code. Could be useful on a future project.

Leave all Comment