8

I have a plugin that sends an advocates referral coupon code to e-mails that they enter. When the audience receives this email I'd like to create a flow where they can click on 'SHOP NOW' in the e-mail and the coupon will be automatically added.

As of now, for the link under the 'SHOP NOW' button I've entered the following:

websitename.biz/cart__trashed?code=DISCOUNTCODE

To handle $code I've put this in my functions.php file:

add_action('woocommerce_before_cart', 'discount');
function discount( ) {
    global $woocommerce;
    $code= $_GET["code"];
   if(!empty($code)){       
    if($woocommerce->cart->add_discount($code)){ 
    echo '<div class="woocommerce_message"><strong>Applied coupon!</strong></div>';
        }
    }
}

The problem I'm facing here is:

  • if there is nothing in the cart when the audience visits the website, the coupon will not be applied.
  • If there was something added and stayed there (because of a cookie) then the coupon code is applied perfectly.

I believe its because the cart is empty, the code does not work.

Just want the code to be applied when the audience clicks the link.

How can I make this working?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Mjall2
  • 253
  • 1
  • 9
  • 24
  • You can pass product ids along with the coupon code so that if any client clicks on the link, first check whether that product is present in cart or not. If not then first add the product to the cart by your code then finally apply the coupon. – Logan Young Oct 18 '17 at 18:37
  • I see that as a work-around when I have only 3 products, but would it not be easier for me to just add the coupon code to the cart and they can shop whatever they want and the code will be applied to the session? This is easier for the customer of course – Mjall2 Oct 18 '17 at 18:43
  • But Woocommerce does not allow coupons to be applied and save to cart when cart is empty. But you can write your custom code like as soon as client clicks on the link save the coupon code on your own session key, from there you can track whether customer has anything in cart or not. If yes then apply coupon by fetching from from your session key. – Logan Young Oct 18 '17 at 18:49
  • So I'd use WC-Cart::set_session($code)? – Mjall2 Oct 18 '17 at 19:53
  • There are multiple ways to set session, you can try any of those option and start working on it – Logan Young Oct 19 '17 at 03:21

3 Answers3

12

The correct way to do it should be to:

  • Set the coupon code from the URL in the cart session as custom data.
  • Apply the discount from this coupon code when customer add first item to cart.
  • Remove the discount from this coupon if customer empty cart

You can set any existing coupon code from any Url (like shop page, other archives pages, products pages, my account pages, or any existing pages) adding to this existing url:
?code=DISCOUNTCODE at the end
(where DISCOUNTCODE is your coupon code name).

Here is the code:

// Set coupon code as custom data in cart session
add_action('wp_loaded', 'add_coupon_code_to_cart_session');
function add_coupon_code_to_cart_session() {
    // Exit if no code in URL or if the coupon code is already set cart session
    if( empty( $_GET["code"] ) || WC()->session->get( 'custom_discount' ) ) return;

    if( ! WC()->session->get( 'custom_discount' ) ) {
        $coupon_code = esc_attr($_GET["code"]);
        WC()->session->set( 'custom_discount', $coupon_code );
        // If there is an existing non empty cart active session we apply the coupon
        if( ! WC()->cart->is_empty() ){
            WC()->cart->add_discount( $coupon_code );
        }
    }
}

// Add coupon code when a product is added to cart once
add_action('woocommerce_add_to_cart', 'add_coupon_code_to_cart', 10, 6 );
function add_coupon_code_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ){
    $coupon_code = WC()->session->get( 'custom_discount' );
    $applied_coupons = WC()->session->get('applied_coupons');

    if( empty($coupon_code) || in_array( $coupon_code, $applied_coupons ) ) return;

    WC()->cart->add_discount( $coupon_code );
}

// Remove coupon code when user empty his cart
add_action('woocommerce_cart_item_removed', 'check_coupon_code_cart_items_removed', 10, 6 );
function check_coupon_code_cart_items_removed( $cart_item_key, $cart ){
    $coupon_code = WC()->session->get( 'custom_discount' );

    if( $cart->has_discount( $coupon_code ) && $cart->is_empty() );
        $cart->remove_coupon( $coupon_code );
}

Code goes in function.php file of your active child theme (or active theme) or in any plugin file.

This is tested and works

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Just to improve this code a bit, notice that if the user is not logged in, the session for the user might not exist yet. So I added the following on the start of the `add_coupon_code_to_cart_session` function: `if ( ! WC()->session->has_session() ) { WC()->session->set_customer_session_cookie( true ); }` – Vinicius Garcia Jul 10 '20 at 04:17
  • @ViniciusGarcia I use that already [in all those answers too…](https://stackoverflow.com/search?q=user%3A3730754+set_customer_session_cookie) Thanks anyway – LoicTheAztec Jul 10 '20 at 06:18
  • I didn't notice that I found this on one of your answers! :D GJ! – Vinicius Garcia Jul 10 '20 at 18:55
1

use below code to make the coupan valid in any situation

add_filter('woocommerce_coupon_is_valid','coupon_always_valid',10,1);
function coupon_always_valid($valid){
     $valid = true;
     return $valid ; 
}
Rajkumar Gour
  • 1,131
  • 12
  • 26
  • what will this achieve? should i just append this to my functions.php aloong with the code I've written? – Mjall2 Nov 23 '17 at 14:07
0
add_action('woocommerce_before_cart', 'discount');
function discount( ) {
    global $woocommerce;
    $code= $_GET["code"];
   if(!empty($code)){       
    if(WC()->session->set( 'applied_coupons', $code )){ 
    echo '<div class="woocommerce_message"><strong>Applied coupon!</strong></div>';
        }
    }
}
Tarang koradiya
  • 702
  • 5
  • 7
  • Hey this isn't working, when I add a product it doesn't echo applied coupon, also does not apply coupon when product is added or on checkout. – Mjall2 Nov 21 '17 at 15:01