Search code examples
phpwordpressvalidationwoocommercepaypal-subscriptions

WooCommerce custom checkout checkboxes fields validation for one mandatory checkbox


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?


Solution

  • "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.