1
votes

I'm working on woocommerce API plugin development and trying to pass custom cart item data using the below code in add to cart API endpoint.

$cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations, array('margin' => 200));

and want to use that custom cart item data on woocommerce_before_calculate_totals hook (see code below) but can't getting custom cart item data ($cart_item['margin']) there.

add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 30, 1 );
function custom_cart_item_price( $cart ) {
  if ( is_admin() && ! defined( 'DOING_AJAX' ) )
      return;

  foreach ( $cart->get_cart() as $cart_item ) {
    if( isset($cart_item['margin']) ){
        $final_price = ($cart_item['data']->get_price() + $cart_item['margin']);
        $cart_item['data']->set_price($final_price);
    }
  }
}

I have installed Woocommerece 4.9 version, please help me to solve this issue. Thanks in advance.

2

2 Answers

1
votes

I had kind of the same problem, the issue was there was another plugin that might have a higher priority on the filter. It was a Role based pricing plugin, after deactivating it, everything worked. So just check if there is no other thing overwriting the function.

0
votes

To do a test I used the woocommerce_add_to_cart_validation hook and I added a product to cart with add_to_cart() method of the WC_Cart class.

add_action( 'woocommerce_add_to_cart_validation', 'add_product_to_cart_programmatically', 10, 3 );
function add_product_to_cart_programmatically( $passed, $product_id, $quantity) {
    $product_id = 166;  // product id to add
    $quantity = 10;     // quantity product to add
    WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), array( 'margin' => 200 ) );
    return $passed;
}

Once the product has been added to the cart, I can apply a custom price based on the custom cart item data:

add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 30, 1 );
function custom_cart_item_price( $cart ) {

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

    foreach ( $cart->get_cart() as $cart_item ) {
        if ( isset( $cart_item['margin'] ) && ! empty( $cart_item['margin'] ) ) {
            $final_price = $cart_item['data']->get_price() + $cart_item['margin'];
            $cart_item['data']->set_price( $final_price );
        }
    }
}

As recommended by @danielsalare you can try to increase the priority of the action, as in my example above.