When the customer order is placed, I would like if free shipping has been used, to remove shipping info from the order confirmation mail to the customer.
Is it possible to achieve this?
This is possible with this custom hooked function (but from all email notifications):
add_filter( 'woocommerce_get_order_item_totals', function( $total_rows, $order, $tax_display ){
// Only for "Free Shipping" method
if( ! $order->has_shipping_method('free_shipping') || is_account_page() || is_wc_endpoint_url( 'order-received' ) )
return $total_rows;
unset($total_rows['shipping']);
return $total_rows;
}, 11, 3 );
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Related
On Woocommerce, we need to remove the shipping-methods from the Cart section an add it to the Checkout page only.
Any track or help should be really appreciated?
There will be multiple ways to do it depending on the "why?" and on "for what?" you need this:
1) Hide shipping related from cart - The easiest way;
add_filter( 'woocommerce_cart_ready_to_calc_shipping', 'disable_shipping_on_cart' );
add_filter( 'woocommerce_cart_needs_shipping', 'disable_shipping_on_cart' );
function disable_shipping_on_cart( $enabled ){
return is_checkout() ? true : false;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
But it will not remove the shipping methods (or shipping packages) from session…
2) Remove all shipping methods (and shipping packages) everywhere except in checkout page:
// Shipping methods
add_filter( 'woocommerce_package_rates', 'keep_shipping_methods_on_checkout', 100, 2 );
function keep_shipping_methods_on_checkout( $rates, $package ) {
if ( ! is_checkout() ) {
// Loop through shipping methods rates
foreach( $rates as $rate_key => $rate ){
unset($rates[$rate_key]); // Remove
}
}
return $rates;
}
// Shipping packages
add_filter( 'woocommerce_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
add_filter( 'woocommerce_cart_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
function keep_shipping_packages_on_checkout( $packages ) {
if ( ! is_checkout() ) {
foreach( $packages as $key => $package ) {
WC()->session->__unset('shipping_for_package_'.$key); // Remove
unset($packages[$key]); // Remove
}
}
return $packages;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
It will remove all shipping methods and all shipping packages from cart and WC_Session.
The related registered WC_Session data will be something like:
WC_Session_Handler Object
(
[_data:protected] => Array
(
[previous_shipping_methods] => a:1:{i:0;a:3:{i:0;s:16:"free_shipping:10";i:1;s:12:"flat_rate:14";i:2;s:15:"local_pickup:13";}}
[shipping_method_counts] => a:1:{i:0;i:3;}
[chosen_shipping_methods] => a:1:{i:0;s:16:"free_shipping:10";}
)
)
without shipping package…
It will only keep the previous shipping methods and the previous chosen shipping method for customers that have already purchased something before.
I want to remove or hide "shipping" label from woocommerce order confirmation Email table.
The following little code snippet will remove only the label "Shipping", from email notifications:
add_filter( 'woocommerce_get_order_item_totals', 'customize_email_order_line_totals', 1000, 3 );
function customize_email_order_line_totals( $total_rows, $order, $tax_display ){
// Only on emails notifications
if( ! is_wc_endpoint_url() || ! is_admin() ) {
// Remove "Shipping" label text from totals rows
$total_rows['shipping']['label'] = '';
}
return $total_rows;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
To remove the shipping total line from email notifications, use the following instead:
add_filter( 'woocommerce_get_order_item_totals', 'customize_email_order_line_totals', 1000, 3 );
function customize_email_order_line_totals( $total_rows, $order, $tax_display ){
// Only on emails notifications
if( ! is_wc_endpoint_url() || ! is_admin() ) {
// Remove shipping line from totals rows
unset($total_rows['shipping']);
}
return $total_rows;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
It's not possible to target a specific email notification.
I am using Wordpress 4.9.6 and WooCommerce version 3.4.3 and I need to send 'Order on Hold' email for a specific shipping method.
Reason?
I use DHL shipping plugin to calculate shipping and an 'Alternate' shipping method is also available. If the user chooses DHL shipping while checking out, the shipping cost is calculated and the order is good to go. However, if they choose the 'Alternate' shipping method, I got to inform them that their order is on hold till they pay for shipping because the 'Alternate' method is 'Free Shipping' renamed and I will issue a separate invoice for them to pay for shipping once they have ordered.
Searching for a solution to my problem, I have found some code that matches my needs in this answer thread: Customizing Woocommerce New Order email notification based on shipping method
But I am unable to figure out how to edit this code in order to make it work for my specific scenario.
Your help is greatly appreciated.
To make it work for a renamed free shipping method, you will need to change the code a bit:
add_action ('woocommerce_email_order_details', 'custom_email_notification_for_shipping', 5, 4);
function custom_email_notification_for_shipping( $order, $sent_to_admin, $plain_text, $email ){
// Only for "On hold" email notification and "Free Shipping" Shipping Method
if ( 'customer_on_hold_order' == $email->id && $order->has_shipping_method('free_shipping') ){
$order_id = $order->get_id(); // The Order ID
// Your message output
echo "<h2>Shipping notice</h2>
<p>Your custom message goes here… your custom message goes here… your custom message goes here… your custom message goes here… your custom message goes here…</p>";
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
Forcing "On hold" and "Completed" email notification (optional)
On orders status change the below code will trigger "On hold" email notification only for your renamed "Free shipping" shipping method and "Completed" email notification.
add_action( 'woocommerce_order_status_changed', 'sending_on_hold_email_notification', 20, 4 );
function sending_on_hold_email_notification( $order_id, $old_status, $new_status, $order ){
// Only "On hold" order status and "Free Shipping" Shipping Method
if ( $order->has_shipping_method('free_shipping') && $new_status == 'on-hold' ){
// Getting all WC_emails objects
$notifications = WC()->mailer()->get_emails();
// Send "On hold" email notification
$notifications['WC_Email_Customer_On_Hold_Order']->trigger( $order_id );
} elseif ( ! $order->has_shipping_method('free_shipping') && $new_status == 'completed' ){
// Getting all WC_emails objects
$notifications = WC()->mailer()->get_emails();
// Send "On hold" email notification
$notifications['WC_Email_Customer_Completed_Order']->trigger( $order_id );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
Let me clear my question:
I have downloaded & activated WooCommerce Plugin for E-Commerce Functionality.
I want to add "Applied coupon code" in Admin New Order Email Template using my custom plugin.
Now:
Can you tell me that exact Hook or Function which is actually setting up that New Order Email Template so that i will override it?
Can you tell me how to call applied coupon code, so that i will display this in email template?
It would be great, if you help me please.
This can be done using a custom function hooked in woocommerce_email_order_details action hook (for example) that will display in admin emails notifications the used coupons in the order:
// The email function hooked that display the text
add_action( 'woocommerce_email_order_details', 'display_applied_coupons', 10, 4 );
function display_applied_coupons( $order, $sent_to_admin, $plain_text, $email ) {
// Only for admins and when there at least 1 coupon in the order
if ( ! $sent_to_admin && count($order->get_items('coupon') ) == 0 ) return;
foreach( $order->get_items('coupon') as $coupon ){
$coupon_codes[] = $coupon->get_code();
}
// For one coupon
if( count($coupon_codes) == 1 ){
$coupon_code = reset($coupon_codes);
echo '<p>'.__( 'Coupon Used: ').$coupon_code.'<p>';
}
// For multiple coupons
else {
$coupon_codes = implode( ', ', $coupon_codes);
echo '<p>'.__( 'Coupons Used: ').$coupon_codes.'<p>';
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works...
This is because $coupon_codes is not an array() define it with $coupon_codes=array();
Actually the Payment Instructions are displayed on Order Received page:
What I want is to display this Payment Instructions also in My account > Order view pages.
Like this:
My question: How do I make the payment instruction to appear in My account > order view pages?
I know it will be sent to the customer email but in case they are lazy to open email they can read the instructions in the order details page.
Using a custom hooked function in woocommerce_order_details_after_order_table action hook in which we add the woocommerce_thankyou_{$order->get_payment_method()} hook, will do the job:
add_action( 'woocommerce_order_details_after_order_table', 'view_order_custom_payment_instruction', 5, 1); // Email notifications
function view_order_custom_payment_instruction( $order ){
// Only for "on-hold" and "processing" order statuses and on 'view-order' page
if( in_array( $order->get_status(), array( 'on-hold', 'processing' ) ) && is_wc_endpoint_url( 'view-order' ) ){
// The "Payment instructions" will be displayed with that:
do_action( 'woocommerce_thankyou_' . $order->get_payment_method(), $order->get_id() );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works in WooCommerce 3+.
It was not working for me, I had to modify the code slightly:
add_action( 'woocommerce_order_details_after_order_table', 'view_order_custom_payment_instruction', 5, 1); // Email notifications
function view_order_custom_payment_instruction( $order ){
// Only for "on-hold" order statuses and on 'view-order' page
if( in_array( $order->get_status(), array( 'on-hold' ) ) && is_wc_endpoint_url( 'view-order' ) ){
WC()->payment_gateways();
// The "Payment instructions" will be displayed with that:
do_action( 'woocommerce_thankyou_' . $order->get_payment_method(), $order->get_id() );
}
}