【问题标题】:Add a dynamic fee based on a select field in WooCommerce Checkout根据 WooCommerce Checkout 中的选择字段添加动态费用
【发布时间】:2020-01-05 22:49:16
【问题描述】:

我正在使用 Update fee dynamically based on radio buttons in Woocommerce checkout 答案代码解决方案,该解决方案非常适合我为每个复选框添加不同价格的字段,并且价格变化会反映在结帐中。

但是我需要一些帮助:当我选择了一种附加税的包装时,它出现在后端的订单区,但只显示价格,我想显示标题也是。

复选框选项有:

'options' => array (
    'bag' => __ ('In a bag' .wc_price (3.00), $ domain),
    'box' => __ ('In a gift box' .wc_price (9.00), $ domain),
),

如何让它在订单上显示名字? 另外是否可以将复选框更改为选择字段?

【问题讨论】:

    标签: php jquery wordpress woocommerce checkout


    【解决方案1】:

    我对原始代码进行了一些更改:

    • 显示自定义选择字段(而不是单选按钮输入字段)
    • 如果客户未选择包装选项,则显示自定义错误通知
    • 在任何地方显示所选的包装类型(在订单和电子邮件通知上)

    代码:

    // Add a custom select fields for packing option fee
    add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_form_packing_addition', 20 );
    function checkout_shipping_form_packing_addition( ) {
        $domain = 'woocommerce';
    
        echo '<tr class="packing-select"><th>' . __('Packing options', $domain) . '</th><td>';
    
        $chosen   = WC()->session->get('chosen_packing');
    
        // Add a custom checkbox field
        woocommerce_form_field( 'chosen_packing', array(
            'type'      => 'select',
            'class'     => array( 'form-row-wide packing' ),
            'options'   => array(
                ''    => __("Choose a packing option ...", $domain),
                'bag' => sprintf( __("In a bag (%s)", $domain), strip_tags( wc_price(3.00) ) ),
                'box' => sprintf( __("In a gift box (%s)", $domain), strip_tags( wc_price(9.00) ) ),
            ),
            'required'  => true,
        ), $chosen );
    
        echo '</td></tr>';
    }
    
    // jQuery - Ajax script
    add_action( 'wp_footer', 'checkout_shipping_packing_script' );
    function checkout_shipping_packing_script() {
        // Only checkout page
        if ( is_checkout() && ! is_wc_endpoint_url() ) :
    
        WC()->session->__unset('chosen_packing');
        ?>
        <script type="text/javascript">
        jQuery( function($){
            $('form.checkout').on('change', 'select#chosen_packing', function(){
                var p = $(this).val();
                console.log(p);
                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: {
                        'action': 'woo_get_ajax_data',
                        'packing': p,
                    },
                    success: function (result) {
                        $('body').trigger('update_checkout');
                        console.log('response: '+result); // just for testing | TO BE REMOVED
                    },
                    error: function(error){
                        console.log(error); // just for testing | TO BE REMOVED
                    }
                });
            });
        });
        </script>
        <?php
        endif;
    }
    
    // Php Ajax (Receiving request and saving to WC session)
    add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
    add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
    function woo_get_ajax_data() {
        if ( isset($_POST['packing']) ){
            $packing = sanitize_key( $_POST['packing'] );
            WC()->session->set('chosen_packing', $packing );
            echo json_encode( $packing );
        }
        die(); // Alway at the end (to avoid server error 500)
    }
    
    // Add a custom dynamic packaging fee
    add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1 );
    function add_packaging_fee( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        $domain      = "woocommerce";
        $packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee
    
        if ( $packing_fee === 'bag' ) {
            $label = __("Bag packing fee", $domain);
            $cost  = 3.00;
        } elseif ( $packing_fee === 'box' ) {
            $label = __("Gift box packing fee", $domain);
            $cost  = 9.00;
        }
    
        if ( isset($cost) )
            $cart->add_fee( $label, $cost );
    }
    
    // Field validation, as this packing field is required
    add_action('woocommerce_checkout_process', 'packing_field_checkout_process');
    function packing_field_checkout_process() {
        // Check if set, if its not set add an error.
        if ( isset($_POST['chosen_packing']) && empty($_POST['chosen_packing']) )
            wc_add_notice( __( "Please choose a packing option...", "woocommerce" ), 'error' );
    }
    

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

    客户未选择包装选项时的错误消息:

    【讨论】:

    • 太好了,非常感谢,我已经尝试过了,它完全符合我的需要。我只做了一个很小的修改,因此它也允许从总数中减去一个值,因为最初如果这是负数 (-),那么什么都不会显示。非常感谢您的宝贵帮助!
    • @kamuran 我更新了代码以处理负成本费用。在add_packaging_fee() 功能代码中将if ( isset($cost) &amp;&amp; $cost &gt; 0 ) 替换为if ( isset($cost) )。它现在应该可以工作了。
    • 感谢您的代码,我试图通过更改挂钩名称将此 sn-p 的位置从结帐页面更改为购物车。但没有成功 woocommerce_cart_calculate_fees ..我做错了什么?
    猜你喜欢
    • 2015-06-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 2017-12-06
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    相关资源
    最近更新 更多