skip to Main Content

I have three custom checkout fields, and people have to check at least one for the order to go through.
This is only needed for 1 product.

So, I loop through the cart items to check if the product is in the cart, then add the fields. This part works fine:

add_action( 'woocommerce_before_order_notes', 'mmm_add_custom_checkout_field' );

function mmm_add_custom_checkout_field( $checkout ) { 
    
       $product_id = 214884;
   $in_cart = false;
  
   foreach( WC()->cart->get_cart() as $cart_item ) {
      $product_in_cart = $cart_item['product_id'];
      if ( $product_in_cart === $product_id ) $in_cart = true;
   }
  
   if ( $in_cart ) {
    echo '<h2>Membership Application</h2>';
    echo '<p>Select all that applies</p>';
   woocommerce_form_field( 'read_wog', array(        
      'type' => 'checkbox',        
      'class' => array( 'form-row-wide no-req' ), 
       'required' => true,
      'label' => 'I accept term 1', 
   ), $checkout->get_value( 'read_wog' ) ); 
        woocommerce_form_field( 'one_on_one', array(        
      'type' => 'checkbox',        
      'class' => array( 'form-row-wide no-req' ),
      'required' => true,
      'label' => 'I accept term 2', 
   ), $checkout->get_value( 'one_on_one' ) ); 
        woocommerce_form_field( 'mm_sn', array(        
      'type' => 'checkbox',
      'required' => true,
      'class' => array( 'form-row-wide no-req' ),        
      'label' => 'I accept term 3).', 
   ), $checkout->get_value( 'mm_sn' ) ); 

      
  
   }

}

The site uses Paypal Express as a payment gateway, and the validation lets people go through Paypal regardless of the checkbox validation. The validation for default fields works fine. The error notice is added when manually refreshing the page though!

Here’s the validation code:

add_action( 'woocommerce_checkout_process', 'mmm_validate_new_checkout_field' );
  
function mmm_validate_new_checkout_field() {    
   $product_id = 214884;
   $in_cart = false;
  
   foreach( WC()->cart->get_cart() as $cart_item ) {
      $product_in_cart = $cart_item['product_id'];
      if ( $product_in_cart === $product_id ) $in_cart = true;
   }
     if( $in_cart && !isset($_POST['mm_sn']) && !isset($_POST['one_on_one']) && !isset($_POST['read_wog']) ) {
         wc_add_notice( 'You can only have a full membership if you accept at least 1 term', 'error' );
     }
}

Any idea how to make it work?

2

Answers


  1. "The site uses PayPal Express as a payment gateway"

    This isn’t specific enough to be able to advise. If PayPal JS SDK buttons are being used (called smart buttons in the WooCommerce PayPal plugin configuration), then you can add an onClick handler as documented here: https://developer.paypal.com/docs/business/javascript-sdk/javascript-sdk-reference/#oninitonclick

    You’ll need to edit the outputted JS of how the WooCommerce plugin invokes paypal.Buttons to include such a function.

    Login or Signup to reply.
  2. The following revisited code will throw an error validation message if at least one checkbox has not been checked on checkout:

    // Custom function that check if a specific product is in cart
    function is_product_in_cart( $product_id ) {
        foreach( WC()->cart->get_cart() as $item ) {
            if ( in_array( $product_id, array($item['product_id'], $item['variation_id']) ) ) {
                return true;
            }
        }
        return false;
    }
    
    // Add Custom checkout checkboxes fields
    add_action( 'woocommerce_before_order_notes', 'mmm_add_custom_checkout_field' );
    function mmm_add_custom_checkout_field( $checkout ) {
        $targeted_id = 214884;
    
        if ( is_product_in_cart( $targeted_id ) ) {
            echo '<h2>Membership Application</h2>
                <p>Select all that applies</p>';
            
            woocommerce_form_field( 'read_wog', array(
                'type' => 'checkbox',
                'class' => array( 'form-row-wide no-req' ),
                'required' => true,
                'label' => 'I accept term 1',
            ), $checkout->get_value( 'read_wog' ) );
            
            woocommerce_form_field( 'one_on_one', array(
                'type' => 'checkbox',
                'class' => array( 'form-row-wide no-req' ),
                'required' => true,
                'label' => 'I accept term 2',
            ), $checkout->get_value( 'one_on_one' ) );
            
            woocommerce_form_field( 'mm_sn', array(
                'type' => 'checkbox',
                'required' => true,
                'class' => array( 'form-row-wide no-req' ),
                'label' => 'I accept term 3).',
            ), $checkout->get_value( 'mm_sn' ) );
        }
    }
    
    // Custom checkout checkboxes fields validation
    add_action( 'woocommerce_checkout_process', 'mmm_validate_new_checkout_field' );
    function mmm_validate_new_checkout_field() {
        $targeted_id = 214884;
    
        if ( is_product_in_cart( $targeted_id ) && ! ( isset($_POST['read_wog']) || isset($_POST['one_on_one']) || isset($_POST['mm_sn']) ) ) {
            wc_add_notice( 'You can only have a full membership if you accept at least 1 term', 'error' );
        }
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search