I don't have 50 reputation on stack overflow, so I can't comment on post. To ask a question I gotta make a new question unfortunately :/
So, from here :
Changing WooCommerce cart item names
OP asked about changing WooCommerce cart item names.
The answer below, which
#https://stackoverflow.com/users/3730754/loictheaztec
reply helped me but it isn't complete enough..
I've tested the code he gave,
add_filter( 'woocommerce_before_calculate_totals', 'custom_cart_items_prices', 10, 1 );
function custom_cart_items_prices( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Iterating through cart items
foreach ( $cart_object->get_cart() as $cart_item ) {
// Get the product name (item name)
$id = $cart_item['data']->get_name();
// THE NEW NAME
$new_name = 'mydesiredproductname';
// Set your cart item name
$cart_item['data']->set_name( $new_name );
}
}
it works great, for the code above on the cart page, checkout page customer invoice page and admin order page is changed to "mydesiredproductname" but I want the Cart Page, the Checkout Page, the customer invoice page and the admin order page to remain the same, only thing is changed is the item name that is submitted to payment gateway. Wonder if that is possible? Or what is the closest that I can achieve?
ps: I tested is_cart and also is_checkout function, for is_cart the cart is unchanged, for is_checkout the checkout page is unchanged.
Any help would be greatly appreciated
Thanks !
Related
In woocommerce store I add manually product to cart by WC()->cart->add_to_cart() function.
I need add tax to this cart/product (in product menu I have selected tax class). When I complete order, I don't have tax column in order menu in ACP. I tried with WC()->cart->add_fee() and set_tax_class() but it don't work.
Maybe I'm doing something wrong, I will be very grateful for any help, thanks.
I've always used the following and it works fine. You need to hook into the woocommerce_cart_calculate_fees hook.
add_action( 'woocommerce_cart_calculate_fees','rs_packaging_fee' );
function rs_packaging_fee() {
global $woocommerce;
//Set the Fee
$materials_surcharge = '5.00';//if negative it will subtract from total.
//add the fee to the cart
$woocommerce->cart->add_fee( 'Metals Surcharge', $materials_surcharge, true, 'standard' );
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
}
I am trying to build a custom functionality in Woocommerce with Advanced Custom Fields (ACF) plugin.
I created some code already but it is not working properly.
I want to select (simple) products at a Woocommerce product with ACF post object field. That products must be added free into the Woocommerce cart when that product will be added to the cart. Also when I add two or more items the free products must be added together.
I got also some images how the situation should work.
This is the ACF field setup.
For example: this is the product we give away.
This is the product we give away selected at a Woocommerce single product.
This is my actual code:
add_action('woocommerce_check_cart_items', 'free_products' );
function free_products() {
if( ( is_cart() || is_checkout () ) {
$free_product = get_field('gratis_producten'); // Incentive product we are giving away
$cart_id = WC()->cart->generate_cart_id( $free_product );
$free_products_in_cart = WC()->cart->find_product_in_cart( $cart_id );
if( $free_product ) {
// Removing existing "free products" from the cart.
WC()->cart->remove_cart_item( $free_products_in_cart );
// Adding to cart 40 free products
WC()->cart->add_to_cart( $free_product, 40 );
}
}
}
Any help will be highly appreciated.
Here's what I want to do:
If customer selects Canada as shipping country and there's a specific product in cart, checkout should not happen and an error message should generate informing customer of why checkout didn't happen.
My research:
Add or remove woocommerce error messages has code to generate WooCommerce error messages. I asked a question yesterday that gave me codes to check if certain product is in cart and if shipping country is set to Canada Remove Canada from country list when specific products are in cart on Woocommerce I am not sure which filter/action I must hook my code to so it runs whenever "Place Order" is clicked on checkout page.
Update:
So I tried combining the two codes I have listed in my research but it didn't work. Any help if I need to approach this differently will be really appreciated
Product IDs are 15631 & 12616
This can be done using the action hook woocommerce_check_cart_items through this custom function:
add_action( 'woocommerce_check_cart_items', 'products_not_shipable_in_canada' );
function products_not_shipable_in_canada() {
// Only on checkout page (allowing customer to change the country in cart shipping calculator)
if( ! is_checkout() ) return;
// Set your products
$products = array(15631, 12616);
// Get customer country
$country = WC()->session->get('customer')['shipping_country'];
if( empty($country) ){
$country = WC()->session->get('customer')['billing_country'];
}
// For CANADA
if( $country == 'CA' ){
// Loop through cart items
foreach( WC()->cart->get_cart() as $item ){
// IF product is in cart
if( in_array( $item['product_id'], $products ) ){
// Avoid checkout and display an error notice
wc_add_notice( sprintf(
__("The product %s can't be shipped to Canada, sorry.", "woocommerce" ),
'"' . $item['data']->get_name() . '"'
), 'error' );
break; // Stop the loop
}
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Related: Set minimum allowed weight for a specific country in WooCommerce
I am trying to redirect my custom shop page to cart page after user select custom attributes (liability and hours) and then clicks the purchase button.
I have written custom JS code which retrieves the variation_id and attributes value and append it to the URL so that it automatically gets added to cart and get's redirected to cart page.
href="yourdomain.com/?add-to-cart=47&variation_id=88&quantity=3&attribute_pa_colour=blue&attribute_pa_size=m"
This is the URL format which I have found in a blog: (https://businessbloomer.com/woocommerce-custom-add-cart-urls-ultimate-guide/) and I made my link in this format.
My link is:
localhost/wordpress/cart/?add-to-cart=1185&variation_id=1641&quantity=1&attribute_pa_liability=2_million&attribute_pa_hours=500_hours
Where liability and hours is my custom attribute which has values as 1 million, 2 million and 500 hours, 750 hours respectively.
But when it get's redirected to cart page woocommerce give me an error and shows it's alert box which shows the error message as "liability and hours are required fields".
I think woocommerce is unable to get the attribute values through my URL.
Can anyone explain why is this happening and what is the error if there is any?
Updated
This "Business Bloomer" guide is a little outdatedā¦ You need 2 things:
1). The correct URL
You don't need to addto cart the product and the variation Id with all related attributes. You just need to add to cart the variation ID + your custom attributes like this: localhost/wordpress/cart/?add-to-cart=1641&quantity=1&pa_liability=2_million&pa_hours=500_hours
2). Registering (and display) your custom attributes:
// Store the custom data to cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_product_data', 10, 2 );
function save_custom_product_data( $cart_item_data, $product_id ) {
$bool = false;
$data = array();
if( isset( $_REQUEST['pa_liability'] ) ) {
$cart_item_data['custom_data']['pa_liability'] = $_REQUEST['pa_liability'];
$data['pa_liability'] = $_REQUEST['pa_liability'];
$bool = true;
}
if( isset( $_REQUEST['pa_hours'] ) ) {
$cart_item_data['custom_data']['pa_hours'] = $_REQUEST['pa_hours'];
$data['pa_hours'] = $_REQUEST['pa_hours'];
$bool = true;
}
if( $bool ) {
// below statement make sure every add to cart action as unique line item
$cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'custom_variations', $data );
}
return $cart_item_data;
}
// Displaying the custom attributes in cart and checkout items
add_filter( 'woocommerce_get_item_data', 'customizing_cart_item_data', 10, 2 );
function customizing_cart_item_data( $cart_data, $cart_item ) {
$custom_items = array();
if( ! empty( $cart_data ) ) $custom_items = $cart_data;
// Get the data (custom attributes) and set them
if( ! empty( $cart_item['custom_data']['pa_liability'] ) )
$custom_items[] = array(
'name' => 'pa_liability',
'value' => $cart_item['custom_data']['pa_liability'],
);
if( ! empty( $cart_item['custom_data']['pa_hours'] ) )
$custom_items[] = array(
'name' => 'pa_hours',
'value' => $cart_item['custom_data']['pa_hours'],
);
return $custom_items;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works
You will need to add this data to the order items too
First uncheck the ajax add to cart option from admin panel
Then you need to make variation with your attributes then find out product id, quantity, attribute slug and attribute name(used to show in cart) and variation id and then make your cart url like given below.
The add to cart link with attribute is : https://www.your-domain.com/?add-to-cart=(product id)&quantity=(numeric quantity)&attribute_pa_(attribute slug)=(attribute name)&variation_id=(variation id)
For more details you can visit http://www.codemystery.com/wordpress-woocommerce-add-cart-link-variations/
The other answers are correct in regards to the add to cart url format (should be: /add-to-cart=product_id&my_custom_attr=whatever&my_custom_attr2=somthing)
Then there is a very good plugin to handle this type of functionality for storing the custom product attributes called WC Fields Factory.
And the writer of the plugin also has a great article on how to do this w/o need of a plugin. As well as an answer on a similar question here.
I did not want to post here but I could not find the answer I was looking for and I do not have enough reputation to comment on other VERY SIMILAR questions to get my exact answer.
I found an almost perfect answer from this post: WooCommerce: Add product to cart with price override?
using the code:
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price');
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
and it works great...if you set a hard coded custom price.
My question is: How can I set a custom price based on user input?
I have tried every way I can think of to pass information (I even tried using cookies, globals, sessions) and none of them worked how I wanted and all of them were, at BEST, hacks.
The specific product in question is a donation and the customer wants the user to be able to set the donation price (rather than just creating a variable product with set price points).
On the donation page when the user submits the donation form I am adding the donation product to the cart like so:
$donation_success = $woocommerce->cart->add_to_cart($donation_id);
My donation product has a set price of 0.00 so when it is added to the cart it has a price of 0.00 (I don't know if the price is set at this point or later)
I have tried passing in information at this point using the last variable in the add_to_cart method which accepts an array of arguments but I couldn't seem to get that to work either.
I am sure the answer is simple but I have been trying for hours to do this right and I cannot get it to work. I am out of ideas.
The actual code I am using at the moment is slightly different than was suggested by the answerer of the above post but works basically the same:
add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');
function woo_add_donation() {
global $woocommerce;
$donation = 10;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if($cart_item['data']->id == 358 || $cart_item['data']->id == 360){
$cart_item['data']->set_price($donation);
}
}
}
Thanks in advance for any helpful advice!
I found a solution which is not elegant but works for my purposes.
I was trying to use cookies before but I didn't set the cookie path so it was only available to the page it was set on.
I am now setting a cookie with the donation price:
setcookie("donation", $_GET['donation'], 0, "/");
Then I am setting the price like so:
add_action( 'woocommerce_before_calculate_totals', 'woo_add_donation');
function woo_add_donation() {
global $woocommerce;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if($cart_item['data']->id == 358 && ! empty($_COOKIE['donation'])){
$cart_item['data']->set_price($_COOKIE['donation']);
}
}
}
I have been looking for exactly the same thing. I found this WooCommerce plugin (not free) for this
name your price plugin
Initially I wasn't sure what search terms to use to find plugins like this but it looks like "WooCommerce name your price" brings up links to other sources of similar plugins.
[this is a comment] Where do you set the cookie? My first guess is that the refreshes in the same page, using the GET method, and provides a PHP code-block with the $_GET['donation'] to set the cookie with.
And then, once the cookie is set, you redirect the page to Woocommerce Cart page to continue the shopping process. If you're doing it easier way, please let me know. Thanks.
Sorry, I couldn't post this as a comment to the selected answer due to the lack of points.
This code will create order with custom price:
$product = wc_get_product($product_id);
$order = wc_create_order();
try {
$order->add_product($product);
//$order->set_customer_id($user->ID);
$order->set_billing_email($customer_email);
} catch (WC_Data_Exception $e) {
wp_send_json_error("Failed to create order");
}
$order->calculate_totals();
try {
$order->set_total($custom_price); // $custom_price should be float value
} catch (WC_Data_Exception $e) {
wp_send_json_error("Failed to change order details");
}
$order->save();
$order->update_status( 'completed' );