In WooCommerce, I am hiding shipping methods based on different shipping classes in cart using "Hide shipping methods for specific shipping class in WooCommerce" answer code (the 2nd way), but the problem is that I use WPML plugin which manage 2 languages site, so looking for just one class won't do it.
So I need to handle 2 shipping classes instead of one. I tried addind 2 shipping classes this way:
// HERE define your shipping classes to find
$class = 3031, 3032;
But it breaks the website. So I would like to hide the defined flat rate not only for both shipping classes 3031 and 3032.
What I am doing wrong? How can I enable 2 shipping classes without breaking the web site?
To use multiple shipping classes, you should first defined them in an array and in the IF statement you will use in_array() conditional function this way:
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_shipping_class', 10, 2 );
function hide_shipping_method_based_on_shipping_class( $rates, $package )
{
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE define your shipping classes to find
$classes = [3031, 3032];
// HERE define the shipping methods you want to hide
$method_key_ids = array('flat_rate:189');
// Checking in cart items
foreach( $package['contents'] as $item ) {
// If we find one of the shipping classes
if( in_array( $item['data']->get_shipping_class_id(), $classes ) ){
foreach( $method_key_ids as $method_key_id ){
unset($rates[$method_key_id]); // Remove the targeted methods
}
break; // Stop the loop
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Sometimes, you should may be need to refresh shipping methods going to shipping areas, then disable / save and re-enable / save your "flat rates" shipping methods.
Related thread: Hide shipping methods for specific shipping class in WooCommerce
Related
I have woocommerce_shipping_package_name hook that makes API call after the customer fill his billing data to get the address and caculate shipping
`add_filter('woocommerce_shipping_package_name', 'customer_address_city_with_shipping', 10, 1);`
// this inside the customer_address_city_with_shipping function
$woocommerce->cart->add_fee('Shipping', $fee, true, '');
the shipping method added but without the fee (for sure I tried custom value)
I am trying to create a functionality when a user tries to select COD as a payment option then set shipping to Free Shipping (Make this shipping option available).
Right now I have added this code.
add_action( 'woocommerce_checkout_update_order_review', __NAMESPACE__.'\\refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods($post_data)
{
if (isset($post_data['payment_method']) && $post_data['payment_method'] === 'cod') {
// I am not sure how to add Free Shipping Method here.
}
}
I am unable to figure out how can I add free shipping method here when it isn't available in the available_shipping_method.
How can I add it programmatically ?
When the user buy a product, I want to save a series of data in custom tables in database. This data will be the product id, custom fields I have, and some other data.
My idea is that this should be done when the payment of the product has been made correctly, that is to say, at the time of payment.
I wanted you to give me advice, I have created a way but I don't know if it is the right one or if you would recommend any other way.
I've edited the thankyou page, and I have inserted this code:
$order = new WC_Order ($order->get_id ();
$check_payment = $order->payment_complete ();
if ($check_payment) {
global $wpdb;
wpdb->insert (/* CODE DATABASE*/);
}
As woocommerce Order-received (thankyou) page can be reloaded, it's not really the good way.
The correct hook to be used that you can find inside WC_Order payment_complete() method is woocommerce_payment_complete. So your code should be for most payment gateways:
add_action('woocommerce_payment_complete', 'action_payment_complete', 30, 1 );
function action_payment_complete( $order_id ){
global $wpdb;
// Get an instance of the WC_Order object (if needed)
$order = wc_get_order( $order_id );
// Your database actions code
wpdb->insert (/* CODE DATABASE*/);
}
Code goes in function.php file of the active child theme (or active theme).
For payment methods (CHEQUE HERE) as 'cheque', 'bacs' and 'cod' that needs to be "completed" by shop manager, you will use instead:
add_action( 'woocommerce_order_status_completed', 'action_order_status_completed', 20, 2 );
function action_payment_complete( $order_id, $order ){
// The specific payment methods to be target
$payment_methods = array('bacs','cheque','cod');
// Only for specific payment methods
if( ! in_array( $order->get_payment_method(), $payment_methods ) return;
global $wpdb;
// Your database actions code
wpdb->insert (/* CODE DATABASE*/);
}
So when order status will change to completed for this specific payment methods, this hook will be triggered…
You can also use instead woocommerce_order_status_processing if you target Processing order status or woocommerce_order_status_on-hold if you target On Hold order status
Code goes in function.php file of the active child theme (or active theme).
This should works.
I am a total beginner in programming with PHP. I wanted to create a PHP file in which the order_status from a predefined order (in my case 108) gets changed to completed.
Therefore I need the woocommerce functions get_order($ID) and update_status but I do not know how to use them in my PHP. I hope you understand my problem. From Java I could imagine that I need to get an instance from a class or something like that?
Here is the code I have so far:
<?php $ord = new WC_Order(108); $ord->update_status('completed'); ?>
When I open the page I receive the following error:
Fatal error: Uncaught Error: Class 'WC_Order' not found (...)
In general on Wordpress/WooCommerce you will include your functions code:
In your active child theme (or active theme) function.php file
In a plugin…
You can also enable some code in:
Your theme templates
WooCommerce templates that you will override through your active child theme (or active theme).
Now to execute that function, you will need an event that will execute your function.
In (Wordpress) Woocommerce there is a lot of action hooks that are triggered on some specific events that you can use to execute your function. In this case your function will be hooked (ready to be executed on a specific event).
If you want to change the status of a specific order is better to do it in the related order edit page in backend.
An example:
For example you can change the order status when a customer has submit his order after checkout on order-received end point (thankyou page):
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) return;
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Change order status to "completed"
$order->update_status( 'completed' );
}
This code is an official code snippet: Automatically Complete Orders.
It is a good example that shows you how things can work… So in your case you are using here WC_Order class methods like update_status().
Now with this code base, you can refine the behaviors like in this answer:
WooCommerce: Auto complete paid Orders (depending on Payment methods)
Related to orders: How to get WooCommerce order details
I have 2 shipping methods defined:
Table Rates - Priority 1
Local Pickup - Priority 2
Within Table Rates, I have 3 options:
Registered Australian Post (2 to 8 Business Days): $6.50
Tracking and Freight Insurance: $7.25
Nation-Wide Delivery (5 to 12 Business Days): $1.40
All orders that fall within the Local Table Rate area are presented with these 3 options and by default, Option 3 is selected ( I assume because it is the cheapest)
It defaults the priority to table rates but you can't define priority within the actual table rates. I want the default option to be Option 1: Registered Australian Post (2 to 8 Business Days)
I have discovered that the default shipping method is set here:
WC()->session->[chosen_shipping_methods] => a:1:{i:0;s:17:"table_rate-5 : 70";}
and apparently can be accessed and modified using the following two methods:
WC()->session->get('chosen_shipping_methods');
WC()->session->set('chosen_shipping_methods', $chosen_method);
BUT, I can get the current chosen_shipping_methods I just can't set a new one.
I'm trying to set it using the action woocommerce_shipping_method_chosen but it's not working
Can anyone guide me to what I should be looking at?
by only looking on your website and not looking at the code, I'm guessing this might be what you want...
add_action( 'template_redirect', 'reigel_chosen_shipping_methods' );
function reigel_chosen_shipping_methods(){
remove_action(current_filter(), __FUNCTION__);
WC()->session->set( 'chosen_shipping_methods', array('table_rate-7 : 72') );
}
You can reorder shipping methods via the admin dashboard. Goto Woocommerce > Shipping > Shipping Methods and change the order using drag and drop.
This is what I ended up using which worked as required:
/*=Use the shipping method filter to set the "selected" shipping method to
* the first (default) method in the list
**************************************************************************/
function oley_reset_default_shipping_method( $method, $available_methods ) {
$method = key($available_methods);
return $method;
}
add_filter('woocommerce_shipping_chosen_method', 'oley_reset_default_shipping_method', 10, 2);
(NOTE: This worked because the shipping rate I wanted was actually the first in the list but just wasn't being selected by default)