【问题标题】:Fee based on checkout radio buttons choice in WooCommerce基于 WooCommerce 中的结帐单选按钮选择的费用
【发布时间】:2020-09-08 15:27:39
【问题描述】:

在 WooCommerce 结帐中,我已成功添加自定义单选按钮。我想根据客户的选择设置动态费用。客户可以从自定义单选按钮中选择一个选项。

这是我的代码:

// Output the Custom field in check out
add_action( 'woocommerce_review_order_before_payment', 'checkout_radio_choice', 10,2);
function checkout_radio_choice(){
    ?>
    <label for="custom_field">

        <input type="radio" name="custom_field" checked="checked" value="option0">DECLINED  <br />
        <input type="radio" name="custom_field" value="option1">SIGNATURE <br />
        <input type="radio" name="custom_field" value="option2">INSURANCE<br />
    </label> <br />
    <?php
}

// Stores the custom field value in Cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_product_field_data', 10, 2 );
function save_custom_product_field_data( $cart_item_data, $product_id ) {
    if( isset( $_REQUEST['custom_field'] ) ) {
        $cart_item_data[ 'custom_field' ] = $_REQUEST['custom_field'];
        // below statement make sure every add to cart action as unique line item
        $cart_item_data['unique_key'] = md5( microtime().rand() );
        WC()->session->set( 'my_order_data', $_REQUEST['custom_field'] );
    }
    return $cart_item_data;
}

// Outuput custom Item value in Cart and Checkout pages
add_filter( 'woocommerce_get_item_data', 'output_custom_product_field_data', 10, 2 );
 function output_custom_product_field_data( $cart_data, $cart_item ) {

    if( !empty( $cart_data ) )
        $custom_items = $cart_data;

    if( isset( $cart_item['custom_field'] ) ) {
        $custom_items[] = array(
            'key'       => __('Custom Item', 'woocommerce'),
            'value'     => $cart_item['custom_field'],
            'display'   => $cart_item['custom_field'],
        );
    }
    return $custom_items;
}

// Dynamic fee
function WPE_checkout_radio_choice_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    if ( "option_1" == $radio ) {
        $fee = 4;
    }
    elseif ( "option_2" == $radio ) {
        $fee = ( ( wc_prices_include_tax() ? $cart->get_cart_contents_total() + $cart->get_cart_contents_tax() : $cart->get_cart_contents_total() ) * 0.027 + 4.00 );
    }

    $cart->add_fee( __('Protection', 'woocommerce'), $fee );-
}

但是“WPE_checkout_radio_choice_fee()”函数出了点问题,因为它不起作用。

如何根据 WooCommerce 中的结帐单选按钮选择添加动态费用?

【问题讨论】:

    标签: php jquery wordpress woocommerce checkout


    【解决方案1】:

    woocommerce_add_cart_item_datawoocommerce_get_item_data 操作挂钩用于产品自定义字段,但不用于结帐自定义字段。

    您的案例需要 Ajax 将选定的“保护选择”传递给WC_Session,以解决您的问题。

    // Output the Custom field in check out
    add_action( 'woocommerce_review_order_before_payment', 'checkout_radio_choice', 10,2);
    function checkout_radio_choice(){
        $input_key = 'protection_choice';
        $value     = WC()->session->get($input_key);
        $options   = array(
            __("DECLINED", "woocommerce"),
            __("SIGNATURE", "woocommerce"),
            __("INSURANCE", "woocommerce"),
        );
    
        echo '<p class="form-row form-row-wide" id="'.$input_key.'_field"><label for="'.$input_key.'">
            <input type="radio" name="'.$input_key.'" value="" checked="checked"> '.__("DECLINED", "woocommerce").'<br />
            <input type="radio" name="'.$input_key.'" value="signature"> '.__("SIGNATURE", "woocommerce").'<br />
            <input type="radio" name="'.$input_key.'" value="insurance"> '.__("INSURANCE", "woocommerce").'<br />
        </label></p>';
    }
    
    // The jQuery Ajax request (client side)
    add_action( 'wp_footer', 'checkout_custom_jquery_script' );
    function checkout_custom_jquery_script() {
        // Only checkout page
        if( is_checkout() && ! is_wc_endpoint_url() ):
    
        $session_key = 'protection_choice';
    
        // Remove "options_choice" custom WC session on load
        if( WC()->session->get($session_key) ){
            WC()->session->__unset($session_key);
        }
        // jQuery Ajax code
        ?>
        <script type="text/javascript">
        jQuery( function($){
            if (typeof wc_checkout_params === 'undefined')
                return false;
    
            var a = 'input[name=<?php echo $session_key; ?>]';
    
            $('form.checkout').on( 'change', 'input[name=<?php echo $session_key; ?>]', function(){
                var choice = $(this).val();
                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: {
                        'action': 'get_<?php echo $session_key; ?>',
                        'the_choice': choice,
                    },
                    success: function (response) {
                        $(document.body).trigger('update_checkout');
                        console.log(response); // For testing, to be removed.
                    }
                });
            });
        });
        </script>
        <?php
        endif;
    }
    
    // The Wordpress Ajax PHP receiver (server side)
    add_action( 'wp_ajax_get_protection_choice', 'get_checkout_protection_choice' );
    add_action( 'wp_ajax_nopriv_get_protection_choice', 'get_checkout_protection_choice' );
    function get_checkout_protection_choice() {
        $session_key = 'protection_choice';
    
        if ( isset($_POST['the_choice']) ){
            WC()->session->set( $session_key, esc_attr( $_POST['the_choice'] ) );
            echo $_POST['the_choice'];
        }
        die();
    }
    
    // Add a custom fee
    add_action( 'woocommerce_cart_calculate_fees', 'chosen_custom_fee', 20, 1 );
    function chosen_custom_fee( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( $choice = WC()->session->get('protection_choice') ) {
            if ( "signature" === $choice ) {
                $fee = 4.00;
            }
            elseif ( "insurance" === $choice ) {
                $subtotal_excl_tax = (float) $cart->get_cart_contents_total();
                $subtotal_incl_tax = $subtotal_excl_tax + (float) $cart->get_cart_contents_tax();
                $fee = ( wc_prices_include_tax() ? $subtotal_incl_tax : $subtotal_excl_tax ) * 0.027 + 4.00;
            }
    
            $cart->add_fee( __("Protection", "woocommerce"), $fee );
        }
    }
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。

    【讨论】:

    • 感谢您的回答,(我希望您能回复)我已经实现了将其添加为费用的功能,由于我无法控制的原因,我得到了2个选项a:它必须是记录为产品或 b:将其保留为费用并让它在客户订单备注框中打印一条消息选项 0 - 客户拒绝选项 1 感谢您选择签名确认选项 2 感谢您选择保险和签名 ...原因我们是否正在使用 api 将我们所有的场地订单提供给我们的运输门户,说 api 不收取费用并拒绝提供帮助
    • 好的,但我的回答在这里有效,并且正在回答您最初的问题,并使用原始提供的详细信息。所以你可以请accept it,谢谢。
    猜你喜欢
    • 2015-09-06
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 2018-06-13
    • 2019-01-04
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多