dougao1542 2019-08-09 07:59
浏览 32
已采纳

too long

How can to customize the product page to include an extract fee base on the user's choice. Something slimier to the attached photo with customize your order option on the product page not on checkout page. enter image description here

I have this code which display the radio buttons and option on the checkout but for some reason the fee is not being added to the total.

    // Part 1
// Display Radio Buttons
// Uses woocommerce_form_field()

add_action( 'woocommerce_before_add_to_cart_form', 'bbloomer_checkout_radio_choice' );

function bbloomer_checkout_radio_choice() {

   $chosen = WC()->session->get('radio_chosen');
   $chosen = empty( $chosen ) ? WC()->checkout->get_value('radio_choice') : $chosen;
   $chosen = empty( $chosen ) ? 'no_option' : $chosen;

   $args = array(
   'type' => 'radio',
   'class' => array( 'form-row-wide' ),
   'options' => array(
      'no_option' => 'No Option',
      'option_1' => 'Option 1 ($10)',
      'option_2' => 'Option 2 ($30)',
   ),
   'default' => $chosen
   );

   echo '<div id="checkout-radio">';
   echo '<h3>Customize Your Order!</h3>';
   woocommerce_form_field( 'radio_choice', $args, $chosen );
   echo '</div>';

}

// Part 2
// Add Fee and Calculate Total
// Based on session's "radio_chosen"

#2 Calculate New Total

add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_checkout_radio_choice_fee', 20, 1 );

function bbloomer_checkout_radio_choice_fee( $cart ) {

  if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

  $radio = WC()->session->get( 'radio_chosen' );

  if ( "option_1" == $radio ) {
   $fee = 10;
  } elseif ( "option_2" == $radio ) {
   $fee = 30;
  }

  $cart->add_fee( __('Option Fee', 'woocommerce'), $fee );

}

// Part 3
// Refresh Checkout if Radio Changes
// Uses jQuery

add_action( 'wp_footer', 'bbloomer_checkout_radio_choice_refresh' );

function bbloomer_checkout_radio_choice_refresh() {
if ( ! is_checkout() ) return;
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name=radio_choice]', function(e){
            e.preventDefault();
            var p = $(this).val();
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'woo_get_ajax_data',
                    'radio': p,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                }
            });
        });
    });
    </script>
    <?php
}

// Part 4
// Add Radio Choice to Session
// Uses Ajax

add_action( 'wp_ajax_woo_get_ajax_data', 'bbloomer_checkout_radio_choice_set_session' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'bbloomer_checkout_radio_choice_set_session' );

function bbloomer_checkout_radio_choice_set_session() {
    if ( isset($_POST['radio']) ){
        $radio = sanitize_key( $_POST['radio'] );
        WC()->session->set('radio_chosen', $radio );
        echo json_encode( $radio );
    }
    die();
}

If I change the hook to add_action( 'woocommerce_product_options_general_product_data', 'bbloomer_checkout_radio_choice' );

The option buttons shows up on the check out page and it work fine, I assume some how I need to pass the option value from product page to the check out page

  • 写回答

1条回答 默认 最新

  • dthhlf1777 2019-08-09 09:57
    关注

    Add to follows code snippets to achieve your work -

    function add_custom_fees_before_add_to_cart() {
        global $product;
    
        $args = array(
            'type' => 'radio',
            'class' => array( 'form-row-wide' ),
            'options' => array(
                '' => 'No Option',
                '10' => 'Option 1 ($10)',
                '30' => 'Option 2 ($30)',
            ),
            'default' => ''
        );
        ?>
        <div class="custom-fees-wrap">
            <label for="iconic-engraving"><?php _e( 'Customize Your Order!', 'textdomain' ); ?></label>
            <?php woocommerce_form_field( 'custom_fees', $args, '' ); ?>
        </div>
        <?php
    }
    
    add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_fees_before_add_to_cart', 99 );
    
    
    function save_value_add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
        $custom_fees = filter_input( INPUT_POST, 'custom_fees' );
    
        if ( empty( $custom_fees ) ) {
            return $cart_item_data;
        }
    
        $cart_item_data['custom_fees'] = $custom_fees;
    
        return $cart_item_data;
    }
    
    add_filter( 'woocommerce_add_cart_item_data', 'save_value_add_cart_item_data', 99, 3 );
    
    function calculate_add_cart_fee() {
        global $woocommerce;
        $cart_items = $woocommerce->cart->get_cart();
        foreach( $cart_items as $key => $item ) { 
            if( !isset( $item['custom_fees'] ) && empty( $item['custom_fees'] ) ) continue;
            $woocommerce->cart->add_fee( __('Custom fees', 'textdomain'), $item['custom_fees'] );
        }
    }
    add_action( 'woocommerce_cart_calculate_fees', 'calculate_add_cart_fee', 99 );
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线