Woocommerce cart amount AJAX shortcode - php

I've made a snippet to display the cart total in a shortcode. I use it at the checkout page (created a multistep checkout) before order validation.
add_shortcode( 'quote-total', 'get_quote_total' );
function get_quote_total(){
$total = WC()->cart->total;
return '<div>'.wc_price($total).'</div>';
}
// USAGE: [quote-total]
Now, I would like to use AJAX to make the amount change when there is new data, like shipping.
Do you know how can I achieve it ?

You should add some selector (e.g. class name) to your element:
return '<div class="step-cart-total">'.wc_price($total).'</div>';
Then you should be able to utilize woocommerce_add_to_cart_fragments filter like so:
function custom_woocommerce_add_to_cart_fragments( $fragments ) {
// Ajaxify checkout step cart total
ob_start();
$total = WC()->cart->total;
echo '<div class="step-cart-total">'.wc_price($total).'</div>';
$fragments['.step-cart-total'] = ob_get_clean();
return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'custom_woocommerce_add_to_cart_fragments');

Related

How do I programatically & DOM (checkout page) remove shipping from a WordPress order if the order contains a specific product type?

I'm trying to do a special logic for my custom plugin. If the user has added a specific product type in their cart, in the checkout page there must be radio inputs that determine whether the user wants the specific product type to be shipped or stored in vault. I've done everything for the frontend part (creating the radio inputs, built the JavaScript logic to remove from the DOM what's not necessary and so on...) but I now need to programatically remove the shipping from the order and remove the "Shipping" row inside the order preview in the checkout page. I tried the following filter
add_filter( 'woocommerce_cart_shipping_method_full_label', 'remove_shipping_labels', 10, 2 );
function remove_shipping_labels( $label, $method ) {
return '';
}
But it's removing just the label text "Free Shipping" but not the entire shipping row inside the order preview in the checkout page. How can I programatically remove the shipping availability from an order through AJAX and update the user interface inside the checkout page?
function hide_shipping_based_on_prod_type( $rates ) {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach ( $items as $item => $values ) {
$product_id = $values['data']->get_id();
$product_type = WC_Product_Factory::get_product_type( $values['data']->get_id() );
if ( 'simple' === $product_type ) { //check product types of woocommerce to add more conditions
unset( $rates['free_shipping:1'] );
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'hide_shipping_based_on_prod_type', 100 );
add_action(
'after_setup_theme',
function() {
WC_Cache_Helper::get_transient_version( 'shipping', true );
}
);

WooCommerce add order admin hook for recalculate button

I'm looking to loop over all the products added to an order in the admin before the order is actually submitted. So far the only WooCommerce hooks I have found only allow you access the product items individually.
I was looking for a hook that would fire when a user clicks the recalculate button but actually it could trigger when a user adds a product, tax, shipping method, etc.. I just need to loop over all items added to the order so far.
At the moment I'm using woocommerce_admin_order_item_values hook but it's a self-contained loop so doesn't allow me to add all my '$item['product_id']' together.
function action_woocommerce_admin_order_item_values( $null, $item, $absint ) {
$item_ids = array($item['product_id']);
}
add_action( 'woocommerce_admin_order_item_values', 'action_woocommerce_admin_order_item_values', 10, 3 );
You can also use -
woocommerce_before_order_itemmeta Hook but this only accesses each item individually whereas I need to loop over each item in the summary.
There are number of hooks provided by WooCommerce, when you are clicking the Recalculate button. I'm listing here those hooks and it depends on you to choose among them according to your requirement.
$order = WC_Order object
add_action("woocommerce_order_before_calculate_taxes", "custom_order_before_calculate_taxes", 10, 2);
function custom_order_before_calculate_taxes($args, $order) {
// Do something
}
add_action("woocommerce_order_item_after_calculate_taxes", "custom_order_item_after_calculate_taxes", 10, 2);
function custom_order_item_after_calculate_taxes($order, $calculate_tax_for) {
// Do something
}
add_action("woocommerce_before_order_object_save", "custom_before_order_object_save", 10, 2);
function custom_before_order_object_save($order, $data_store) {
// Do something
}
add_action( 'woocommerce_order_before_calculate_totals', "custom_order_before_calculate_totals", 10, 2);
function custom_order_before_calculate_totals($and_taxes, $order ) {
// Do something
}
add_action( 'woocommerce_order_after_calculate_totals', "custom_order_after_calculate_totals", 10, 2);
function custom_order_after_calculate_totals($and_taxes, $order) {
//Do something
}
add_filter("woocommerce_order_is_vat_exempt", function(){
return $boolean;
});
add_filter("woocommerce_order_get_total", "custom_order_get_total", 10, 2);
function custom_order_get_total($value, $order) {
//do somethig
return $value;
}

Which Hook is running after Woocommerce update cart button action

i need to know which hook is running after clicking the update cart button in the cart page .
That is in cart page we have 4 button , update cart , continue shopping, proceed to checkout , apply coupon .
So i want to know which hook is run after update cart button is clicked . When customer click the update cart button after changing the quantity then i have to run a special function that can change total price in the cart , If some condition met , i will change the total price in the cart , and this total price need to pass to the checkout page also /
Please help .
For example
add_filter('after_update_cart_function_finished', 'special_function');
function special_function(){
$applied_coupons= WC()->cart->get_applied_coupons();
if(!empty($applied_coupons)){
$new_value=WC()->cart->get_cart_subtotal();
$discounted=WC()->cart->coupon_discount_totals;
$discounted_value=array_values($discounted)[0];
$new_value=$new_value-$discounted_value+100;
WC()->cart->set_total_price($new_value);
After this update all post_meta value that regarding to order total
}
}
Please see the following custom function that i write for to change value in cart
function action_woocommerce_cart_totals_after_order_total( ) {
$applied_coupons= WC()->cart->get_applied_coupons();
if(!empty($applied_coupons)){
$new_value=WC()->cart->get_cart_subtotal();
$discounted=WC()->cart->coupon_discount_totals;
$discounted_value=array_values($discounted)[0];
$new_value=$new_value-$discounted_value;
if($new_value<100){
$new_value=$new_value+5;
}
?>
<style>
.new-price-new{
color:black;
font-size: 17px;
}
</style>
<script>
jQuery(function($){
$(".order-total .woocommerce-Price-amount.amount").text("£<?php echo $new_value;?>");
$(".order-total .woocommerce-Price-amount.amount").hide();
$(".new-price").remove();
$('.order-total .woocommerce-Price-amount.amount').after('<div class="new-price-new">£<?php echo $new_value;?></div>');;
$(".new-price-new").show();
});
</script>
<?php
}
else{
?>
<script>
jQuery(function($){
$(".new-price-new").remove();
});
</script>
<?php }
};
add_action( 'woocommerce_cart_totals_after_order_total', 'action_woocommerce_cart_totals_after_order_total', 10, 0 );
And this function have many problems , i write this function because of some reason or some other function woocommerce is not calculating coupon price correctly , so i write this function for to manually update the product price in cart .Here if the cart value is more than 100 we provide free shipping other vise we will add 5 . Even this function is not working properly .
Woocommerce Create new discount functionality
You should try woocommerce_update_cart_action_cart_updated action hook. I have revisited your code a bit. Try this:
add_action( 'woocommerce_update_cart_action_cart_updated', 'on_action_cart_updated', 20, 1 );
function on_action_cart_updated( $cart_updated ){
$applied_coupons = WC()->cart->get_applied_coupons();
if( count( $applied_coupons ) > 0 ){
$new_value = WC()->cart->get_cart_subtotal();
$discounted = WC()->cart->coupon_discount_totals;
$discounted_value = array_values($discounted)[0];
$new_value = $new_value-$discounted_value + 100;
WC()->cart->set_total( $new_value );
if ( $cart_updated ) {
// Recalc our totals
WC()->cart->calculate_totals();
}
}
}
Code goes in function.php file of your active child theme (or active theme). Untested. It could work.
Update: The WC_Cart set_total_price() method doesn't exist… I have replaced it by existing WC_Cart set_total()

Disable WooCommerce Payment methods if cart item quantity limit is reached

Is there a way or filter to disable selective payment methods if cart quantity increase more than "X number of items" example "15"?
I know we can limit max number of quantity before adding to cart but I want to disable some payment methods only.
Thanks
You can use a custom function hooked in woocommerce_available_payment_gateways filter hook. You will have to set inside it your quantity limit and your payment methods slugs.
Here is that code:
add_filter('woocommerce_available_payment_gateways', 'unsetting_payment_gateway', 10, 1);
function unsetting_payment_gateway( $available_gateways ) {
// Not in backend (admin)
if( is_admin() )
return $available_gateways;
// HERE Define the limit of quantity item
$qty_limit = 15;
$limit_reached = false;
// Iterating through each items in cart
foreach(WC()->cart->get_cart() as $cart_item){
if($cart_item['quantity'] > $qty_limit ){
$limit_reached = true;
break;
}
}
if($limit_reached){
// HERE set the slug of your payment method
unset($available_gateways['cod']);
unset($available_gateways['bacs']);
}
return $available_gateways;
}
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on WooCommerce version 2.6 and 3+.
You can specify in the payment condition that if the basket number exceeds your chosen amount (e.g., 15), then the payment method will not be displayed in the auction.

Woocommerce add to cart button redirect to checkout

I created an ecommerce using the plugin woocommerce. I am selling only a subscription so the "/cart/" page is useless. I'm trying to get rid of it so that when my customer click on "Add to cart" button, he ends up on the checkout page.
In WooCommerce 3.6 or later you can use woocommerce_add_to_cart_redirect (props #roman)
add_filter ('woocommerce_add_to_cart_redirect', function( $url, $adding_to_cart ) {
return wc_get_checkout_url();
}, 10, 2 );
Original answer:
you can use a filter in functions.php:
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
it doesn't seem to work with ajax, but it works from the single product pages, which I think is what you use
On WooCommerce (>= 2.1) the function can be simplified as:
function redirect_to_checkout() {
return WC()->cart->get_checkout_url();
}
There is an option within WooCommerce settings that allows you to enable this functionality:
Simply login to your WP admin panel > WooCommerce > Catalog and select the option. I hope this helps!
I've found a simple solution that work like magic.
As mentioned by #Ewout, check the box that says "Redirecto to cart page after succesful addtion".
Woocommerce > Settings > Checkout (Tab) - where you should select pages for cart and checkout, select the checkout page as the cart page (image attached).
That's it. works for me.
Update for WooCommerce 3.5.1
Step 1.
First of all go to WooCommerce Products settings and deactivate AJAX add to cart.
Step 2.
Use woocommerce_add_to_cart_redirect hook to make a redirect to checkout.
add_filter( 'woocommerce_add_to_cart_redirect', function( $url ) {
return wc_get_checkout_url();
});
Of course there some small things are left to do, like changing add to cart buttons text and removing some WooCommerce cart-related notices. I recommend to check this tutorial for more https://rudrastyh.com/woocommerce/redirect-to-checkout-skip-cart.html
#RemiCorson posted this brief but beneficial tutorial:
http://www.remicorson.com/woocommerce-skip-product-cart-pages/
He mentions the same filter as #Ewout above,
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
but one line of code stands out and is of super value for me for my current woocommerce project:
There is a direct link that a user can use to automatically bypass the product page.
http://your-site.com/?add-to-cart=37
'37' will be replaced by your product ID.
This was useful for me to eliminate unnecessary steps and take users directly to checkout from the home page and other non-woocommerce pages/posts.
Filter add_to_cart_redirect is deprecated in WooCommerce 2.6. Use woocommerce_add_to_cart_redirect instead.
Add this to your functions.php :
add_filter ('woocommerce_add_to_cart_redirect', function() {
return WC()->cart->get_checkout_url();
} );
Try the below code in the themes function.php file
add_filter( 'woocommerce_add_to_cart_redirect', 'woo_skip_cart_redirect_checkout' );
function woo_skip_cart_redirect_checkout( $url ) {
return wc_get_checkout_url();
}
On shop page, if you want use ajax and redirect toghether. The second method only when there are some condition, you can use this filter and leave on Woocommerce setting ajax enabled:
add_filter('woocommerce_loop_add_to_cart_link', array( $this, 'add_quantity_input' ), 4, 2);
to remove on a class attribute ajax_add_to_cart and change the href value to checkout url page;
On my template case:
public function add_quantity_input($text = null, $product = null) {
global $product, $woocommerce;
if ( $text != null and $product != null ) {
if(ismycondition($product->id)) {
$s = explode('class="', $text);
$s[2]=str_replace('ajax_add_to_cart', '', $s[2]);
$text = implode('class="', $s);
$text = preg_replace('/<a(.*)href="([^"]*)"(.*)>/','<a$1href="'.$woocommerce->cart->get_checkout_url().'"$3>', $text);
}
}
return $text;
}
I hope that this help.
None of the solutions actually worked out for me, the filter add_to_cart_redirect was triggering on every page,not only on the cart.I did some modification on the suggested answer.
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
if(is_cart()){
$checkout_url = WC()->cart->get_checkout_url();
?>
<script>
location = '<?=$checkout_url?>';
</script>
<?php
}
}

Categories