I would like to add a custom note automatically per order, based on if certain payment options are selected at checkout.
This would be a new line below the customers order notes.
Add the follows code snippet in your active theme's functions.php to achieve the above -
function modify_woocommerce_checkout_posted_data_comments( $posted_data ){
// Add extra custom notes for COD payment
if( isset( $posted_data['order_comments'] ) && isset( $posted_data['payment_method'] ) && $posted_data['payment_method'] == 'cod' ) {
$extra_note = __('Your custom notes goes here for COD payments.', 'textdomain' );
$posted_data['order_comments'] = nl2br( $posted_data['order_comments'] . "\n". $extra_note );
}
return $posted_data;
}
add_filter( 'woocommerce_checkout_posted_data', 'modify_woocommerce_checkout_posted_data_comments', 99 );
Here I added extra notes based on Cash on Delivery payment method. Change this as per your requirements.
Related
I'm selling Gift Cards via WooCommerce on Wordpress. My customer should be able to set a value for the gift card amount by himself. I just was able to do this via a plugin. Is there a possibilty to do this by changing some code or via functions.php?
Installed Pimwick Gift Card Pro
Yes, but it's a fairly complex process if doing so from a completely fresh WooCommerce installation with no additional plugins. You will need to do the following things to achieve it:
Add a custom input field to the product to add the custom price
Save the data from the custom input field to the session (cart) when that product is added to the cart
Add the cart meta (created above in #2) to the order when the order is created
Adjust the cost of the product based on the custom price meta (added above in #3).
Step 1: Add a custom input field:
You can add the input field using the woocommerce_before_add_to_cart_button filter as shown below.
Alternatively you can use the woocommerce_wp_text_input - here's an example.
add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_price_input', 100 );
function add_custom_price_input() {
if(get_the_ID() != 123) { //use the product ID of your gift card here, otherwise all products will get this additional field
return;
}
echo '<input type="number" min="50" placeholder="50" name="so_57140247_price">';
}
Step 2: Save custom price to Cart/Session
Next, we need to make sure that your custom input field data is carried over to the cart/session data. We can make use of the woocommerce_add_cart_item_data ( docs | example ) filter to that:
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_meta_to_cart', 10, 3 );
function add_custom_meta_to_cart( $cart_item_data, $product_id, $variation_id ) {
$custom_price = intval(filter_input( INPUT_POST, 'so_57140247_price' ));
if ( !empty( $custom_price ) && $product_id == 123 ) { //check that the custom_price variable is set, and that the product is your gift card
$cart_item_data['so_57140247_price'] = $custom_price; //this will add your custom price data to the cart item data
}
return $cart_item_data;
}
Step 3: Add cart meta to the order
Next we have to add the meta from the cart/session to the order itself so that it can be used in the order-total calculations. We use the woocommerce_checkout_create_order_line_item ( docs | example ) to do this:
add_action( 'woocommerce_checkout_create_order_line_item', 'add_custom_meta_to_order', 10, 4 );
function add_custom_meta_to_order( $item, $cart_item_key, $values, $order ) {
//check if our custom meta was set on the line item of inside the cart/session
if ( !empty( $values['so_57140247_price'] ) ) {
$item->add_meta_data( '_custom_price', $values['so_57140247_price'] ); //add the value to order line item
}
return;
}
Step 4: Adjust total of gift card line item
Finally, we simply adjust the cost of the line item of the gift card based on the value entered into the input field. We can hook into woocommerce_before_calculate_totals ( docs | example ) to do this.
add_action( 'woocommerce_before_calculate_totals', 'calculate_cost_custom', 10, 1);
function calculate_cost_custom( $cart_obj ) {
foreach ( $cart_obj->get_cart() as $key => $value ) {
$price = intval($value['_custom_price']);
$value['data']->set_price( $price );
}
}
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
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() );
}
}
I don't know if it's possible, but, we would need to add some different payment methods for Barcelona.
So, our idea is that if the customer lives in Barcelona area (Catalunya), he will see a credit card payment method and a bank transfer account different than the rest of Spain.
Is that possible with WooCommerce?
Thanks.
If you want to enable this kind of feature in WooCommerce, Customers need to be registered and logged on first, as it's the only way to get they town location before checkout process.
Also you will have to change some settings in WooCommerce allowing only registerers users to checkout.
Then you will have to add some mandatory fields in the registration process as the town, zip code and country.
Once that done, it's going to be easy to enable / disable payment gateways based on this registered customer fields.
1) For customizing the registration fields:
How to add custom fields in user registration on the “My Account” page
2) For payment gateways/methods based on this Customer information, You can use a custom hooked function in woocommerce_available_payment_gateways filter hook:
add_filter( 'woocommerce_available_payment_gateways', 'custom_payment_gateways_process' );
function custom_payment_gateways_process( $available_gateways ) {
// Not in backend (admin)
if( is_admin() )
return $available_gateways;
if ( is_admin() || !is_user_logged_in() )
return $available_gateways;
$current_user_id = get_current_user_id();
$user_meta = get_user_meta( $current_user_id );
// User City, Postcode, State and Country code
$user_city = $user_meta['billing_city'];
$user_postcode = $user_meta['shipping_postcode'];
$user_State = $user_meta['shipping_state'];
$user_country = $user_meta['shipping_country'];
// Disable Cash on delivery ('cod') method example for customer out of spain:
if ( isset( $available_gateways['cod'] ) && $user_country != 'ES' ) {
unset( $available_gateways['cod'] );
}
// You can set many conditions based on the user data
return $available_gateways;
}
This code is just an example, and you will have to set inside the right conditions for the targeted payment methods/gateways…
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.