Change Shipping method label name depending on its cost in WooCommerce - php

Prefacing this question, I know that there might be other ways to accomplish the goal, but I'm trying to understand how Woocommerce works a bit better, so the situation is I have a plugin that can change the cost of shipping depending on the products in the cart, but I want to change the name of the shipping fee depending on the cost.
From what I found in the HTML the current structure of the shipping method looks like this:
<td data-title="Shipping">
<ul id="shipping_method" class="shipping__list woocommerce-shipping-methods">
<li class="shipping__list_item">
<input type="hidden" name="shipping_method[0]" data-index="0" id="shipping_method_0_flat_rate24" value="flat_rate:24" class="shipping_method" /><label class="shipping__list_label" for="shipping_method_0_flat_rate24">Flat Rate Shipping Fee: <span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>10.00</bdi></span></label>
</li>
</ul>
I'm attempting to create a function for the functions.php file of my Wordpress theme, I looked up some code on google and found a similar function involving "$available_shipping_methods" but I wasn't too sure how to use that variable so what I currently have is this:
add_filter('woocommerce_package_rates', 'wc_shipping_rate_rename', 100, 2)
function wc_shipping_rate_rename($rates, $package){
//Checking if the shipping rate exists
if ( isset( $rates['flat_rate:24'] ) ) {
//Getting the rate
$ship_cost = $rates['flat_rate:24']->cost;
if ( $ship_cost == 10) {
$rates['flat_rate:24'] -> 'Subsidized shipping fee:';
}
if ( $ship_cost == 100) {
$rates['flat_rate:24'] -> 'Flat rate shipping fee:';
}
}
return $rates;
}
The goal would be change the part in the HTML that says "Flat Rate Shipping Fee:" depending on the cost of the shipping fee. Any help would be really appreciated.

For a specific shipping rate Id, to change the shipping rate displayed label based on its cost use:
add_filter('woocommerce_package_rates', 'custom_shipping_rate_label_based_on_cost', 100, 2)
function custom_shipping_rate_label_based_on_cost( $rates, $package ){
// Here your targeted shipping rate Id
$targeted_rate_id = 'flat_rate:24';
// Loop through available shipping rates
foreach ( $rates as $rate_key => $rate ) {
// Targetting specific rate Id
if( $targeted_rate_id === $rate_key ) {
$rate_cost = $rate->cost;
if ( $rate_cost < 100 ) {
$rate_label = __('Subsidized shipping fee');
}
elseif ( $rate_cost >= 100 ) {
$rate_label = __('Flat rate shipping fee');
}
if ( isset($rate_label) ) {
$rates[$rate_key]->label = $rate_label;
}
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Clearing shipping caches:
You will need to empty your cart, to clear cached shipping data
Or In shipping settings, you can disable / save any shipping method, then enable back / save.

Related

Disable only flat rate shipping method when free shipping is available in Woocommerce

I am using Hide specifics Flat Rates when Free Shipping is available in WooCommerce 3 lightly changed answer code to hide all shipping methods except one. The only method I want showing is a rate from the "Woocommerce Advanced Shipping" plugin.
I am using the correct rate ID etc...
Everything works fine except when a customer tries to click that shipping method, it won't stay selected. It just jumps back to free shipping.
I have tried debugging and also tried the code with a native woocommerce flat rate ID and it showed up/able to select it just fine.
add_filter( 'woocommerce_package_rates', 'conditionally_hide_shipping_methods', 100, 2 );
function conditionally_hide_shipping_methods( $rates, $package ) {
$flat_rates_express = array( '2588' );
$free = $flat2 = array();
foreach ( $rates as $rate_key => $rate ) {
// Updated Here To
if ( in_array( $rate->id, $flat_rates_express ) )
$flat2[ $rate_key ] = $rate;
if ( 'free_shipping:12' === $rate->id )
$free[ $rate_key ] = $rate;
}
return ! empty( $free ) ? array_merge( $free, $flat2 ) : $rates;
}
ID I want to Keep Shown: "2588" (Custom Shipping Rate From Plugin)
How can I disable the Flat rate shipping method when free shipping is available o and keep a custom shipping rate (from a plugin)?
As you have 3 shipping methods, 1 free shipping, 1 flat rate and 1 custom '2588', it's possible to hide the flat rate shipping method when free shipping is available instead:
add_filter( 'woocommerce_package_rates', 'free_shipping_disable_flat_rate', 1000, 2 );
function free_shipping_disable_flat_rate( $rates, $package ) {
// Here your free shipping rate Id
$free_shipping_rate_id = 'free_shipping:12';
// When your Free shipping method is available
if ( array_key_exists( $free_shipping_rate_id, $rates ) ) {
// Loop through shipping methods rates
foreach ( $rates as $rate_key => $rate ) {
// Removing "Flat rate" shipping method
if ( 'flat_rate' === $rate->method_id ){
unset($rates[$rate_key]);
}
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches:
This code is already saved on your function.php file.
In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.

Set all shipping methods cost to zero for a Free shipping coupon in Woocommerce

I have 3 shipping methods in my cart that should become zero prices as soon as your customer enters Free Shipping coupon.
I know how to add a filter in functions.php to detect the coupon but is someone know a snippet to set shipping methods visibles in cart (radio button) to ZERO for this order?
My deliveries methods are companies like UPS, FedEx...
I activated the free shipping option in order it can be managed with coupon.
The list of choice of deliveries methods for the customers is calculated according to my products shipping class and order total weight.
Shipping class are not calculated but set by product and i use TABLE RATE PLUGIN to calculate the weight.
First free shipping method has to be enabled with option "A valid free shipping coupon"…
Then you need to set the desired coupon codes with option "Allow free shipping" enabled.
The following code will set all shipping methods costs to zero when a valid coupon code (with option "Allow free shipping" enabled) will be applied.
Update: Hide "Free shipping" method and append shipping label titles with "(free)"
add_filter( 'woocommerce_package_rates', 'coupon_free_shipping_customization', 20, 2 );
function coupon_free_shipping_customization( $rates, $package ) {
$has_free_shipping = false;
$applied_coupons = WC()->cart->get_applied_coupons();
foreach( $applied_coupons as $coupon_code ){
$coupon = new WC_Coupon($coupon_code);
if($coupon->get_free_shipping()){
$has_free_shipping = true;
break;
}
}
foreach( $rates as $rate_key => $rate ){
if( $has_free_shipping ){
// For "free shipping" method (enabled), remove it
if( $rate->method_id == 'free_shipping'){
unset($rates[$rate_key]);
}
// For other shipping methods
else {
// Append rate label titles (free)
$rates[$rate_key]->label .= ' ' . __('(free)', 'woocommerce');
// Set rate cost
$rates[$rate_key]->cost = 0;
// Set taxes rate cost (if enabled)
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = 0;
}
$rates[$rate_key]->taxes = $taxes;
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works. It should works also for you.
Sometimes, you should may be need to refresh shipping methods:
1) Empty cart first.
2) Go to shipping Zones settings, then disable/save and re-enable/save the related shipping methods.
If you want to achieve the same but whenever there is a free shipping method available (not only applied coupon, but also cart total is above certain price), you can use this:
add_filter( 'woocommerce_package_rates', 'wc_apply_free_shipping_to_all_methods', 10, 2 );
function wc_apply_free_shipping_to_all_methods( $rates, $package ) {
if( isset( $rates['free_shipping:11'] ) ) {
unset( $rates['free_shipping:11'] );
foreach( $rates as $rate_key => $rate ) {
// Append rate label titles (free)
$rates[$rate_key]->label .= ' ' . __('(free)', 'woocommerce');
// Set rate cost
$rates[$rate_key]->cost = 0;
// Set taxes rate cost (if enabled)
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = 0;
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
Notice, that after free_shipping there is a :11. Prior to WooCommerce 2.6, the details of shipping method "Free Shipping" were stored under array element $rates['free_shipping']. Now, however, it is stored as $rates['free_shipping:shipping_zone_instance_id'] where shipping_zone_instance_id is the shipping zone instance id of the shipping method. You can check the instance id of the shipping method by inspecting the "Free Shipping" in admin panel, or opening it in new tab and looking at the url http://prntscr.com/jd2zjy.

Update WooCommerce "flat rate" shipping cost using jQuery

I am trying to update the shipping cost after the address is entered. When the client starts typing the address, and autocomplete function helps the client find the street name, building, floor, and side.
Once the address is entered JavaScript calculates the distance and the price.
Then the price is via AJAX send to shipment.php
It is my goal to have shipment update the shipping cost accordingly.
I have tried:
include '../../../../wp-load.php';
add_action( 'woocommerce_flat_rate_shipping_add_rate','add_another_custom_flat_rate', 10, 2 );
function add_another_custom_flat_rate( $method, $rate ) {
$new_rate = $rate;
$new_rate['cost'] = 50; // Update the cost to 50
$method->add_rate( $new_rate );
}
But without luck.
I have also following this guide and added another shipping method: Tuts
https://code.tutsplus.com/tutorials/create-a-custom-shipping-method-for-woocommerce--cms-26098
But once again, I cannot update the price once the address is entered.
I think that You don't need Query ajax to update the price directly for this calculated shipping cost and you don't need a custom shipping method as in your code or linked tutorial.
THERE IS THREE STEPS:
1) In your existing Ajax driven PHP function, you will set the calculated price in a custom WC_Session attribute where $shipping_cost variable will be the collected value of the calculated shipping cost passed via JS Ajax:
WC()->session->set( 'shipping_calculated_cost', $shipping_cost );
Then in jQuery Ajax "on success" event you will update checkout with the following:
$('body').trigger('update_checkout');
That will refresh checkout data…
2) In the custom function hooked in woocommerce_package_rates filer hook, you will get the session value of the calculated shipping cost…
IMPORTANT: In WooCommerce settings > shipping, you will set the "flat rate" cost to 1…
In The function code you will set the default price for this flat rate (that will be used when the shipping cost calculation doesn't exist yet):
add_filter('woocommerce_package_rates', 'update_shipping_costs_based_on_cart_session_custom_data', 10, 2);
function update_shipping_costs_based_on_cart_session_custom_data( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// SET HERE the default cost (when "calculated cost" is not yet defined)
$cost = '50';
// Get Shipping rate calculated cost (if it exists)
$calculated_cost = WC()->session->get( 'shipping_calculated_cost');
// Iterating though Shipping Methods
foreach ( $rates as $rate_key => $rate_values ) {
$method_id = $rate_values->method_id;
$rate_id = $rate_values->id;
// For "Flat rate" Shipping" Method only
if ( 'flat_rate' === $method_id ) {
if( ! empty( $calculated_cost ) ) {
$cost = $calculated_cost;
}
// Set the rate cost
$rates[$rate_id]->cost = number_format($rates[$rate_id]->cost * $cost, 2);
// Taxes rate cost (if enabled)
foreach ($rates[$rate_id]->taxes as $key => $tax){
if( $rates[$rate_id]->taxes[$key] > 0 ){ // set the new tax cost
$taxes[$key] = number_format( $rates[$rate_id]->taxes[$key] * $cost, 2 );
$has_taxes = true;
} else {
$has_taxes = false;
}
}
if( $has_taxes )
$rates[$rate_id]->taxes = $taxes;
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme) or in any plugin file.
3) Refresh the shipping caches (needed sometimes):
First empty your cart.
This code is already saved on your function.php file.
Go in a shipping zone settings and disable one "flat rate" (for example) and "save". Then re-enable that "flat rate" and "save". You are done and you can test it.
This should work for you,
If you have many different "flat rates" by shipping zones, you will need to make some changes in my code, if the default cost is different for each…

Hide specifics Flat Rates when Free Shipping is available in WooCommerce 3

In WooCommerce 3, I have these shipping options (settings):
Free Shipping: free_shipping:1 - Minimum order amount is set at $50.
Normal Shipping flat_rate:3 - Amount $5.
Express Shipping flat_rate:5 - Amount $10.
I would like Express Shipping option to be always available (shown).
But when Free shipping is available (meaning that the customer has more than $50 in the cart) I would like to hide Normal Shipping only.
So when Free shipping is NOT available (and hidden), the available shipping rates will be Normal Shipping and Express Shipping.
Is that possible? How can I get this on WooCommerce 3?
Based on the official WooCommerce snippet code, making some light changes, you will be able to hide only your first flat rate when free shippings is available:
add_filter( 'woocommerce_package_rates', 'conditionally_hide_shipping_methods', 100, 2 );
function conditionally_hide_shipping_methods( $rates, $package ) {
// HERE yours 2nd flat rate "Express Shipping" (that you never hide) in the array:
$flat_rates_express = array( 'flat_rate:5', 'flat_rate:12', 'flat_rate:14' );
$free = $flat2 = array();
foreach ( $rates as $rate_key => $rate ) {
// Updated Here To
if ( in_array( $rate->id, $flat_rates_express ) )
$flat2[ $rate_key ] = $rate;
if ( 'free_shipping' === $rate->method_id )
$free[ $rate_key ] = $rate;
}
return ! empty( $free ) ? array_merge( $free, $flat2 ) : $rates;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested on WooCommerce 3 and works.
Refresh the shipping caches:
1) First empty your cart.
2) This code is already saved on your function.php file.
3) Go in a shipping zone settings and disable one "flat rate" (for example) and "save". Then re-enable that "flat rate" and "save". You are done and you can test it.

WooCommerce shipping cost based on cart item count

I want to count shipping cost based on number of products add on cart like,
If I purchase one mobile then it will count shipping cost as 2.5 and after more than two or two mobile I purchased then shipping cost will be 5.0
<?php
$qty(1) * 2.5 = 2.5
$qty(2) * 2.5 = 5.0
$qty(3) * 2.5 = 5.0
?>
So is there any idea or suggestion how to count the shipping cost based on number of products ?
Updated:
As your question is a bit unclear, you could just need to add [qty]*2.5 in the Flat rate shipping method cost (for each shipping zone) in your wooCommerce shipping settings.
But it will not work if you have 2 different items in cart like: item1 (qty 1) + item2 (qty 1)
So this answer will do it in all cases:
1) First you will need to set a "Flat rate" shipping method for each Shipping Zones which cost will be set to 2.5 (in your WooCommerce shipping settings).
2) Adding this code that will calculate for each cart items (based on the total quantity of items) the new updated shipping cost:
add_filter( 'woocommerce_package_rates', 'custom_flat_rate_cost_calculation', 10, 2 );
function custom_flat_rate_cost_calculation( $rates, $package )
{
// The cart count (total items in cart)
$cart_count = WC()->cart->get_cart_contents_count();
$taxes = array();
// If there is more than 1 cart item
if( $cart_count > 1 ){
// Iterating through each shipping rate
foreach($rates as $rate_key => $rate_values){
// Targeting "Flat Rate" shipping method
if ( 'flat_rate' === $rate_values->method_id ) {
// Set the new calculated rate cost
$rates[$rate_id]->cost = number_format($rates[$rate_id]->cost * $cumulated_active_quantity, 2);
// Taxes rate cost (if enabled)
foreach ($rates[$rate_id]->taxes as $key => $tax){
if( $rates[$rate_id]->taxes[$key] > 0 ){ // set the new tax cost
$taxes[$key] = number_format( $rates[$rate_id]->taxes[$key] * $cumulated_active_quantity, 2 );
$has_taxes = true;
} else {
$has_taxes = false;
}
}
if( $has_taxes )
$rates[$rate_id]->taxes = $taxes;
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on WooCommerce 3+ and works
You will need to refresh shipping zones caches: disabling the Flat rate, then save. And enabling back this rate and save.
You can add a custom fee: Add to theme functions.php or use a plugin
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$price_per_mobile = 2.5;
$shipcharge = ( $woocommerce->cart->cart_contents_total * $price_per_mobile);
$woocommerce->cart->add_fee( 'Total Shipping Cost', $shipcharge, true, '' );
}
Go ahead with Woocommerce filter woocommerce_package_rates. Where you can customize all the shipping rates available in cart page.
Here is the code for adding extra cost to all items for both domestic and international shipement
add_filter('woocommerce_package_rates', 'wf_modify_rate', 10, 3);
function wf_modify_rate( $available_shipping_methods, $package ){
$origin_country = 'US';
$amount_to_add_domestic = 10;
$amount_to_add_inter_national = 20;
$amount_to_add = ($package['destination']['country'] == $origin_country) ?
$amount_to_add_domestic : $amount_to_add_inter_national;
$item_count = 0;
foreach ($package['contents'] as $key => $item) {
$item_count += $item['quantity'];
}
foreach ($available_shipping_methods as $methord_name => $methord) {
$available_shipping_methods[$methord_name]->cost += ($amount_to_add*$item_count);
}
return $available_shipping_methods;
}

Categories