WooCommerce中基于结帐单选按钮选择的费用

问题描述 投票:0回答:1

在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个回答
0
投票

动作挂钩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文件中。经过测试和工作。

© www.soinside.com 2019 - 2024. All rights reserved.