Get a Coupon Code via Url and Apply It in Woocommerce Checkout Page

GET a coupon code via URL and apply it in WooCommerce Checkout page

Update 3: This can be done in a very simple way with the following 2 hooked functions:

  • The first one will catch the coupon code in the Url and will set it in WC_Sessions.
  • The second one will apply the coupon code from session in checkout page.

Here is this code:

add_action('init', 'get_custom_coupon_code_to_session');
function get_custom_coupon_code_to_session(){
if( isset($_GET['coupon_code']) ){
// Ensure that customer session is started
if( isset(WC()->session) && ! WC()->session->has_session() )
WC()->session->set_customer_session_cookie(true);

// Check and register coupon code in a custom session variable
$coupon_code = WC()->session->get('coupon_code');
if(empty($coupon_code)){
$coupon_code = esc_attr( $_GET['coupon_code'] );
WC()->session->set( 'coupon_code', $coupon_code ); // Set the coupon code in session
}
}
}

add_action( 'woocommerce_before_checkout_form', 'add_discout_to_checkout', 10, 0 );
function add_discout_to_checkout( ) {
// Set coupon code
$coupon_code = WC()->session->get('coupon_code');
if ( ! empty( $coupon_code ) && ! WC()->cart->has_discount( $coupon_code ) ){
WC()->cart->add_discount( $coupon_code ); // apply the coupon discount
WC()->session->__unset('coupon_code'); // remove coupon code from session
}
}

Code goes in function.php file of the active child theme (or active theme). Tested and works

Inspired from this answer code, Lukasz Wiktor has published a plugin: Woo Coupon URL

Apply coupon code on Woocommerce checkout page with AJAX

as per your shared link, if you follow the same means you are using the coupon form inside the checkout form, so you should remove the coupon form tag and then use it.

  1. Copy woocommerce review-order.php and past inside your active then woocommerce folder.

  2. Open review-order.php and past coupon HTML inside table structure like this:

    <tr class="coupon_checkout">

    <td colspan="2">

    <?php
    if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
    }

    if ( ! wc_coupons_enabled() ) {
    return;
    }

    ?>
    <a href="#" class="showcoupon"><i class="fa fa-plus"></i> REDEEM A PROMO CODE/GIFT VOUCHER</a>
    <div class="checkout_coupon" method="post" style="display:none">

    <p class="form-row form-row-first">
    <input type="text" name="coupon_code" class="input-text" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" id="checkout_coupon_code" value="" />
    </p>

    <p class="form-row form-row-last">
    <input id="checkout_apply_coupon" type="button" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply Coupon', 'woocommerce' ); ?>" />
    </p>
    </div>
    </td>
    </tr>
  3. Add jQuery code either your custom.js file or directly on the footer page like this:

     <script>
    jQuery(document).on('click','#checkout_apply_coupon', function() {
    // Get the coupon code
    var code = jQuery( '#checkout_coupon_code').val();
    var button = jQuery( this );
    data = {
    action: 'ajaxapplucoupon',
    coupon_code: code
    };
    button.html( 'wait.');
    // Send it over to WordPress.
    jQuery.post( wc_checkout_params.ajax_url, data, function( returned_data ) {
    if( returned_data.result == 'error' ) {
    jQuery( 'p.result' ).html( returned_data.message );
    } else {
    setTimeout(function(){
    //reload with ajax
    jQuery(document.body).trigger('update_checkout');
    button.html( 'Apply');
    }, 2000);
    console.log( returned_data+code );
    }
    })
    });
    </script>

As I have tested on my checkout page it's working perfectly like this:
https://www.loom.com/share/7dfc833895d248f191ba327cf5290403


  1. Optional (if not setup wp_localize_script yet then add into functions.php)

     function custom_enqueue() {
    wp_enqueue_script( 'ajax-script', get_template_directory_uri() . '/js/custom.js', array('jquery') ); // optional - if you want to add custom.js then goto theme directory- > js -> and create/add custom.js file
    wp_localize_script( 'ajax-script', 'wc_checkout_params', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); // setup ajax call url
    }
    add_action( 'wp_enqueue_scripts', 'custom_enqueue' );

Apply coupon discount via GET method in URL even if cart is empty in WooCommerce

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

How to auto generate a coupon in WooCommerce and apply it to the cart?

You can get a coupon code from the URL using the GET method. try the below code. You remove the function random_coupon_code because now you generate coupon code based on URL.

function coupon_exists( $coupon_code ) {
global $wpdb;

$sql = $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_type = 'shop_coupon' AND post_name = '%s'", $coupon_code );

$coupon_codes = $wpdb->get_results($sql);

if ( count( $coupon_codes ) > 0 ) {
return true;
} else {
return false;
}
}

function generate_coupon($coupon_generated) {

// Set some coupon data by default
$date_expires = date('Y-m-d', strtotime('+1 days'));
$discount_type = 'fixed_cart'; // 'store_credit' doesn't exist
$coupon_amount = '10';

$coupon = new WC_Coupon();

$coupon->set_code($coupon_generated);
//the coupon discount type can be 'fixed_cart', 'percent' or 'fixed_product', defaults to 'fixed_cart'
$coupon->set_discount_type($discount_type);
//the discount amount, defaults to zero
$coupon->set_amount($coupon_amount );
$coupon->set_date_expires( $date_expires );

//save the coupon
$coupon->save();

return $coupon_generated;
}

function hwn_add_programmatically_created_coupon_to_basket( $cart ) {

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;

$coupon_code = ( isset( $_GET['coupon-code'] ) && $_GET['coupon-code'] != '' ) ? $_GET['coupon-code'] : '' ;

if( $coupon_code == '' ){
return;
}

$applied_coupons = $cart->get_applied_coupons();

if( empty( $applied_coupons ) || ! in_array( $coupon_code, $applied_coupons ) ){
if ( !coupon_exists( $coupon_code ) ) {
generate_coupon( $coupon_code );
}
$cart->add_discount( $coupon_code );
}

}
add_action('woocommerce_before_calculate_totals', 'hwn_add_programmatically_created_coupon_to_basket');

Tested and works

Sample Image

Add WooCommerce coupon through URL

Apparently the user session is not stored if you apply a coupon. You need to have first added a product or do something else which stores your session. We can do it manually though, namely by creating the session cookie ourselves.

if( !WC()->session->has_session() )
WC()->session->set_customer_session_cookie(true);

Took me all day. Hopefully someone will be able use it.

Programmatically apply a coupon in WooCommerce 3.0+ for first order made by a customer

The code you are using no longer works in current WooCommere versions because it contains outdated code, shortcomings and some superfluous steps:

  • It is not necessary to use get_posts() with multiple arguments, use wc_get_customer_order_count() instead
  • $tmp_order->ID changed to $tmp_order->get_id() since WooCommerce 3
  • Your code does not take guest users into account, so they can manually apply the coupon
  • The coupon is not automatically awarded, your code assumes that the customers have apply this coupon
  • The woocommerce_after_checkout_validation hook contains 2 parameters
  • You don't need to return true\false as it's an action hook not a filter.

This updated version takes into account:

  • If the coupon been applied, but the customer is NOT logged in, coupon will be removed
  • If the coupon been applied, the customer is logged in, but NOT the first order, the coupon will be removed
  • If the coupon been applied, the customer is logged in and it is the first order, the coupon remains
  • If the coupon NOT been applied, the customer is logged in and it is the first order, the coupon is applied

So you get:

function action_woocommerce_after_checkout_validation( $data, $error ) {
// Change the name to your coupon
$new_cust_coupon_code = 'coupon1';

// Initialize
$coupon_been_applied = false;
$remove_coupon = false;

// Get applied coupons
$applied_coupons = WC()->cart->get_applied_coupons();

// Has coupon already been applied by the customer
if ( in_array( $new_cust_coupon_code, $applied_coupons ) ) {
$coupon_been_applied = true;

// Coupon has been applied, but customer is a guest user
if ( ! is_user_logged_in() ) {
$remove_coupon = true;
}
}

// Customer is logged in
if ( is_user_logged_in() ) {
// Check if the customer has bought before
$has_bought_before = wc_get_customer_order_count( get_current_user_id() ) >= 1 ? true : false;

// Coupon been applied, but customer has bought before
if ( $coupon_been_applied && $has_bought_before ) {
$remove_coupon = true;
// NOT been applied AND NOT has bought before
} elseif ( ! $coupon_been_applied && ! $has_bought_before ) {
// Apply coupon
WC()->cart->apply_coupon( $new_cust_coupon_code );
}
}

// When true
if ( $remove_coupon ) {
// Remove coupon
WC()->cart->remove_coupon( $new_cust_coupon_code );

// Show message
$error->add( 'validation', sprintf( __( 'Coupon code: "%s" is only applicable for logged in new customers. So the coupon has been removed', 'woocommerce' ), $new_cust_coupon_code ) );
}
}
add_action( 'woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );


Related Topics



Leave a reply



Submit