Search code examples
phpwordpresswoocommercecartfee

Add and save custom meta data to fees in WooCommerce


I'm adding a custom fees to WC with WC()->cart->add_fee() method.

My problem is that I'd like to add metadata to that fee item too. Preferably same time I'm adding the actual fee.

Apparently the WC_Order_Item_Fee Object is generated in the order creation only, so there seems to be no way to add FeeItem-specific metadata to custom fees.

Of course I could save this meta to session, but because add_fee doesn't return any identifier I have no idea which custom fee is actually which.

Any ideas how to solve this issue?

This is the code I use to add Fees:

add_filter('woocommerce_cart_calculate_fees', function (){
    foreach( FeeChecker::getFees() as $fee )
    {
        $cart->add_fee("Added fee: ". $fee, 10 , true, $tax_class);
    }
}

Solution

  • It seems I overlooked WC_Cart->fees_api

    In there I have method that actually returns the created Fee so I know the exact Fee in woocommerce_checkout_create_order_fee_item action

    Edit: This code was originally mostly done by LoicTheAztec. I edited it to fit my particular use case and posted it as solution. Unfortunatelly he deleted his post which could have been beneficial to others.

    // Add cod fee
    add_action('woocommerce_cart_calculate_fees', function ( $cart ){
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        //Make sure it's the right payment method
        if( WC()->session->chosen_payment_method == "cod"){
    
            $tax_class = '';
            $amount = 5;
    
            $session_data = [];
            foreach(  $cart->get_shipping_packages() as $package)
            {
                $fee = $cart->fees_api()->add_fee(
    
                    array(
                        'name'      => "Additional cost: ".$package['custom_data'],
                        'amount'    => (float) $amount,
                        'taxable'   => true,
                        'tax_class' => $tax_class,
                    )
                );
    
                $session_data [ $fee->id ] = $package['custom_data'];
            }
    
            WC()->session->set('COD_fee_meta', $session_data);
    
        }
    
    }, 10, 2);
    
    // Save fee custom meta data to WC_Order_Item_Fee.
    add_action( 'woocommerce_checkout_create_order_fee_item', function ( $item, $fee_key, $fee, $order ) {
        // Get fee meta data from WC_Session
        $fees_meta = WC()->session->get('COD_fee_meta');
    
        // If fee custom meta data exist, save it to fee order item
        if ( isset($fees_meta[$fee_key]) ) {
            $item->update_meta_data( '_custom_data', $fees_meta[$fee_key] );
        }
    
    }, 10, 4 );
    
    // Remove Fee meta data from WC_Session.
    add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
        WC()->session->__unset('COD_fee_meta');
    }, 10, 2 );