Reputation: 3174
is there any way discount on shipping for a special product?
All USA shipping cost is $10.00 but if a product is in a cart the shipping cost will be $3.00 I have tried this using coupon code. How Can I check Billing /Shipping Country ?
But it set discount on total cost but I need to discount the shipping I also use different shipping classes.
What I am trying.
function shipping_costs_discounted( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id_in_cart = array( 1391193 );// this is product ID
if( in_array( $cart_item['product_id'], $product_id_in_cart ) ) {
//Looking for the shipping classes
$shipping_class = 'special-offer-discount'; // <=== Shipping class slug
$discount_rate = 1.46;
$is_found = false;
// Loop through cart items and checking for the specific defined shipping class
foreach( $package['contents'] as $cart_item ) {
if( $cart_item['data']->get_shipping_class() == $shipping_class )
$is_found = true;
}
// Set shipping costs shipping class is found
if( $is_found ){
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false;
// Targeting "flat rate"
if( 'flat_rate' === $rate->method_id ){
$rates[$rate_key]->cost = $rate->cost - $discount_rate;
// Taxes rate cost (if enabled)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $tax > 0 ){
$has_taxes = true;
$taxes[$key] = $tax - $discount_rate;
}
}
if( $has_taxes )
$rates[$rate_key]->taxes = $taxes;
}
}
}
return $rates;
}
}
}
add_filter('woocommerce_package_rates', 'shipping_costs_discounted', 10, 2);
Upvotes: 0
Views: 281
Reputation: 5311
Assuming you'll modify the woocommerce_package_rates
filter, all the items in cart are in $package
variables inside contents
key, so you can simply loop through it and pull all the id for checking if the product you want are in there.
Destination info are also in the $package
variable inside destination
keys, it contains full shipping address including country;
this is an example json output of $package
variable
{
"contents": {
"044a23cadb567653eb51d4eb40acaa88": {
"key": "044a23cadb567653eb51d4eb40acaa88",
"product_id": 2754,
"variation_id": 0,
"variation": [],
"quantity": 2,
"data_hash": "b5c1d5ca8bae6d4896cf1807cdf763f0",
"line_tax_data": {
"subtotal": [],
"total": []
},
"line_subtotal": 35.9,
"line_subtotal_tax": 0,
"line_total": 35.9,
"line_tax": 0,
"data": {}
},
"0fc170ecbb8ff1afb2c6de48ea5343e7": {
"key": "0fc170ecbb8ff1afb2c6de48ea5343e7",
"product_id": 2800,
"variation_id": 0,
"variation": [],
"quantity": 1,
"data_hash": "b5c1d5ca8bae6d4896cf1807cdf763f0",
"line_tax_data": {
"subtotal": [],
"total": []
},
"line_subtotal": 107.95,
"line_subtotal_tax": 0,
"line_total": 107.95,
"line_tax": 0,
"data": {}
}
},
"contents_cost": 143.85,
"applied_coupons": [],
"user": {
"ID": 1
},
"destination": {
"country": "US",
"state": "",
"postcode": "",
"city": "Pine Bluff",
"address": "",
"address_1": "",
"address_2": ""
},
"cart_subtotal": 143.85,
"rates": {
"flat_rate:3": {}
}
}
So with that info, you can do something like this to modify the Shipping Cost and Shipping label
add_filter('woocommerce_package_rates', '_shipping_cost_product_ID', 100, 2);
function _shipping_cost_product_ID( $rates, $package ){
// duh
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// The ID of the product you want to modify shipping cost if found in cart
$discounted_product_id = 2800;
// Get all the product IDs added in cart and put them in array
$ids_in_cart = [];
foreach ( $package['contents'] as $key => $item ) {
$ids_in_cart[] = $item['product_id'];
}
// loop through each shipping rates
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false;
// Only modify shipping if all conditions below are meet
if(
'flat_rate' === $rate->method_id // if shipping method is "Flat RATE"
&& ( isset($package['destination']['country'] ) && $package['destination']['country'] == 'US' ) // if country is US
&& in_array($discounted_product_id, $ids_in_cart )//if $discounted_product_id is in cart
) {
$rates[$rate_key]->label = 'Cool Shipping'; // Modify Shipping Name
$rates[$rate_key]->cost = 3.00; // Modify Shiping Cost
//Taxes rate cost (if enabled)
$taxes = [];
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
$initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key];
$tax_rate = $initial_tax_cost / $initial_cost;
$taxes[$key] = $new_cost * $tax_rate;
$has_taxes = true;
}
}
if( $has_taxes ) $rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
Upvotes: 2