In this post I’ll show you how to use Woocommerce coupons in 23 different ways. That means I’m going to use 23 different hacks to make it work like charm.
Now, in order to make this work, add your chosen snippets shown to your child theme’s functions.php file or better yet, use a snippet manager like Code Snippets or WpCodeBox (my favorite). If you’re interested, then grab WPCodeBox with a nice 20% discount here (SAVE 20% Coupon WPSH20).
Video: How to use Woocommerce coupons in 23 different ways?
How to Filter Woocommerce orders by coupons used?
If you would like to know how to filter Woocommerce orders by coupons used, then it’s just a snippet away. That is, use this one here below.
// Filter Woocommerce orders by coupons used
defined( 'ABSPATH' ) or exit;
// fire it up!
add_action( 'plugins_loaded', 'wc_filter_orders_by_coupon' );
class WC_Filter_Orders_By_Coupon {
const VERSION = '1.1.0';
/** @var WC_Filter_Orders_By_Coupon single instance of this plugin */
protected static $instance;
public function __construct() {
// load translations
add_action( 'init', array( $this, 'load_translation' ) );
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
// adds the coupon filtering dropdown to the orders page
add_action( 'restrict_manage_posts', array( $this, 'filter_orders_by_coupon_used' ) );
// makes coupons filterable
add_filter( 'posts_join', array( $this, 'add_order_items_join' ) );
add_filter( 'posts_where', array( $this, 'add_filterable_where' ) );
}
}
public function filter_orders_by_coupon_used() {
global $typenow;
if ( 'shop_order' === $typenow ) {
$args = array(
'posts_per_page' => - 1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
if ( ! empty( $coupons ) ) : ?>
<select name="_coupons_used" id="dropdown_coupons_used">
<option value="">
<?php esc_html_e( 'Filter by coupon used', 'wc-filter-orders' ); ?>
</option>
<?php foreach ( $coupons as $coupon ) : ?>
<option value="<?php echo esc_attr( $coupon->post_title ); ?>" <?php echo esc_attr( isset( $_GET['_coupons_used'] ) ? selected( $coupon->post_title, $_GET['_coupons_used'], false ) : '' ); ?>>
<?php echo esc_html( $coupon->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
<?php endif;
}
}
public function add_order_items_join( $join ) {
global $typenow, $wpdb;
if ( 'shop_order' === $typenow && isset( $_GET['_coupons_used'] ) && ! empty( $_GET['_coupons_used'] ) ) {
$join .= "LEFT JOIN {$wpdb->prefix}woocommerce_order_items woi ON {$wpdb->posts}.ID = woi.order_id";
}
return $join;
}
public function add_filterable_where( $where ) {
global $typenow, $wpdb;
if ( 'shop_order' === $typenow && isset( $_GET['_coupons_used'] ) && ! empty( $_GET['_coupons_used'] ) ) {
// Main WHERE query part
$where .= $wpdb->prepare( " AND woi.order_item_type='coupon' AND woi.order_item_name='%s'", wc_clean( $_GET['_coupons_used'] ) );
}
return $where;
}
public function load_translation() {
// localization
load_plugin_textdomain( 'wc-filter-orders', false, dirname( plugin_basename( __FILE__ ) ) . '/i18n/languages' );
}
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __clone() {
/* translators: Placeholders: %s - plugin name */
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot clone instances of %s.', 'wc-filter-orders' ), 'Filter WC Orders by Coupon' ), '1.1.0' );
}
public function __wakeup() {
/* translators: Placeholders: %s - plugin name */
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot unserialize instances of %s.', 'wc-filter-orders' ), 'Filter WC Orders by Coupon' ), '1.1.0' );
}
}
function wc_filter_orders_by_coupon() {
return WC_Filter_Orders_By_Coupon::instance();
}
How to display used coupons on WooCommerce admin orders list?
If you would like to display used coupons on WooCommerce admin orders list then use this snippet here below. If no coupons are used then “No coupons used” is displayed. See the screenshot above.
// Display used coupons on WooCommerce admin orders list
add_filter( 'manage_edit-shop_order_columns', 'woo_customer_order_coupon_column_for_orders' );
function woo_customer_order_coupon_column_for_orders( $columns ) {
$new_columns = array();
foreach ( $columns as $column_key => $column_label ) {
if ( 'order_total' === $column_key ) {
$new_columns['order_coupons'] = __('Coupons', 'woocommerce');
}
$new_columns[$column_key] = $column_label;
}
return $new_columns;
}
add_action( 'manage_shop_order_posts_custom_column' , 'woo_display_customer_order_coupon_in_column_for_orders' );
function woo_display_customer_order_coupon_in_column_for_orders( $column ) {
global $the_order, $post;
if( $column == 'order_coupons' ) {
if( $coupons = $the_order->get_coupon_codes() ) {
echo implode(', ', $coupons) . ' ('.count($coupons).')';
} else {
echo '<small><em>'. __('No coupon used') . '</em></small>';
}
}
}
How to display used coupons on Woocommerce order preview template?
With the previous snippet we’re displaying coupons in the Woocommerce admin orders list. Now, with the help of this one here we’re going to display used coupons on Woocommerce order preview template.
// Display used coupons on Woocommerce order preview template
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'wpsh_coupon_in_order_preview', 10, 2 );
function wpsh_coupon_in_order_preview( $data, $order ) {
// Replace '_custom_meta_key' by the correct postmeta key
if( $coupons = $order->get_used_coupons() ) {
$data['coupons_count'] = count($coupons); // <= Store the count in the data array.
$data['coupons_codes'] = implode(', ', $coupons); // <= Store the count in the data array.
}
return $data;
}
// Display coupon in Order preview
add_action( 'woocommerce_admin_order_preview_end', 'wpsh_coupon_in_order_preview_data' );
function wpsh_coupon_in_order_preview_data(){
// Call the stored value and display it
echo '<div><strong>' . __('Coupons used') . ' ({{data.coupons_count}})<strong>: {{data.coupons_codes}}</div><br>';
}
How to remove Woocommerce payment gateways if any coupon code is applied?
Let’s imagine that you would like to remove Woocommerce payment gateway if your customer has used a coupon. Well, there you go – in this example here below we will remove BACS and Paypal payment gateways if any coupon is used.
// Remove Woocommerce payment gateways if any coupon code is applied
add_filter('woocommerce_available_payment_gateways', 'wpsh_remove_payment_for_used_coupons');
function wpsh_remove_payment_for_used_coupons($available_gateways)
{
$coupons = WC()->cart->applied_coupons;
if (!empty($coupons)) {
unset($available_gateways['bacs']); // Remove Direct bank transfer
unset($available_gateways['paypal']); // Remove Paypal
}
return $available_gateways;
}
How to remove Woocommerce payment gateways if a specific coupon code is applied?
But what happens if you would like to remove Woocommerce payment gateways if a specific coupon is used? In this case, just use this snippet here below. This will remove BACS and Paypal gateways onlu if coupon ABC30 is used.
// Remove Woocommerce payment gateways if a specific coupon code is applied
add_filter('woocommerce_available_payment_gateways', 'wpsh_remove_payment_for_specific_coupon');
function wpsh_remove_payment_for_specific_coupon($available_gateways)
{
$coupons = WC()->cart->applied_coupons;
foreach ($coupons as $coupon) {
if ($coupon == 'abc30') { // Add the coupon code here
unset($available_gateways['bacs']); // Remove Direct bank transfer
unset($available_gateways['paypal']); // Remove Paypal
}
}
return $available_gateways;
}
How to auto-apply coupon at Woocommerce Checkout Page using URL?
Today I will give you two options on how to auto-apply a coupon at Woocommerce checkout page. The first snippet here below allows you to add a coupon using url.
Step 1: add the code snippet
// Auto-apply coupon at Woocommerce Checkout Page using URL
function enable_woocommerce_coupon_links(){
if (!function_exists('WC') || !WC()->session) {
return;
}
$query_var = apply_filters('woocommerce_coupon_links_query_var', 'coupon_code');
// Bail if a coupon code isn't in the query string.
if (empty($_GET[$query_var])) {
return;
}
// Set a session cookie to persist the coupon in case the cart is empty.
WC()->session->set_customer_session_cookie(true);
// Apply the coupon to the cart if necessary.
if (!WC()->cart->has_discount($_GET[$query_var])) {
// WC_Cart::add_discount() sanitizes the coupon code.
WC()->cart->add_discount($_GET[$query_var]);
}
}
add_action('wp_loaded', 'enable_woocommerce_coupon_links', 30);
add_action('woocommerce_add_to_cart', 'enable_woocommerce_coupon_links');
Step 2: Use URL that contains your coupon code
For example, if you have a coupon test20 and you use URL https://yoursite.com/checkout/?coupon_code=test20 then your coupon is automatically applied. Don’t forget to change your coupon code accordingly.
How to auto-apply coupon at Woocommerce Checkout Page using button?
You can also add a button that auto-.applies coupon code to your Woocommerce checkout page.
This snippet here below adds the heading “Do you want 20% discount?” along with the button to your review order form. If the user clicks on the button then this Woocommerce coupon is auto-applied. See the screenshot.
// Auto-apply coupon at Woocommerce Checkout Page using button
add_action( 'woocommerce_review_order_before_payment', 'coupon_button', 10 );
function coupon_button() {
echo '<h4>Do you want 20% discount?</h4>';
echo '<p><a class="button" href="?coupon_code=test20"> Click to add your discount </a></p>'; // Change the coupon code accordingly
}
How to remove Woocommerce “Have a coupon?” section from checkout page?
In this part I’m going to show you how to customize Woocommerce checkout page by removing “Have a coupon” section.
First option, go to Woocommerce >> Settings and uncheck “Enable the use of coupon codes” option. This will disable coupon codes site-wide.
Second option, If you would like to use coupon codes and just want to remove Woocommerce “Have a coupon?” section from checkout page then use this small snippet here.
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
How to auto-expand coupon field on Woocommerce checkout page? No need to click on the “Have a coupon?” link.
Let’s be honest: it’s a bit annoying to click on a “Have a coupon?” link on your Woocommerce checkout page. Therefore, let’s auto-expand the coupon field and remove one more unnecessary click.
// Auto-expand coupon field on Woocommerce checkout page
add_filter( 'woocommerce_checkout_coupon_message', 'wpsh_autoexpand_coupon_field', 20, 1 );
function wpsh_autoexpand_coupon_field( $message ) {
?>
<script type='text/javascript'>
jQuery(document).ready( function($){
setTimeout(function(){
$('form.checkout_coupon').css('display','block');
}, 300);
});
</script>
<?php
// HERE your custom message
return __( 'Have a coupon? Add it to the field here below', 'woocommerce' ) . ' <a class="showcoupon-off">' . __( '', 'woocommerce' ) . '</a>';
}
How to change Woocommerce coupon field location on cart page?
With the help of this snippet here you can move your Woocommerce field location in cart page. See the screenshot.
Pay attention that you would also need to use some CSS for it. This will remove your original coupon field and tweak your coupon and cart buttons a bit.
// Change Woocommerce coupon field location on cart page
add_action( 'woocommerce_proceed_to_checkout', 'move_cart_coupon_field', 1 );
function move_cart_coupon_field() {
?>
<form class="woocommerce-coupon-form" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon under-proceed">
<input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" style="width: 100%" />
<button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>" style="width: 100%"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
</div>
<?php } ?>
</form>
<?php
}
Add this piece of CSS code to your Customizer >> Additional CSS area.
.coupon.under-proceed {
margin-bottom: 0.5em;
}
.coupon.under-proceed button {
margin-top: 0.5em;
background: #2a2a2a;
}
/* Hide original Coupon form */
div.coupon:not(.under-proceed) {
display: none !important;
}
@media only screen and (max-width: 1024px) {
.woocommerce-cart-form__contents .actions .button {
display: none;
}
}
How to change Woocommerce coupon field location on checkout page v.1?
If you like the styling and layout of the previous hack and you would like to display it also on a Woocommerce checkout page (under the Place order button), then use this snippet here below (and don’t forget to add CSS from the previous snippet).
// Move Woocommerce coupon field location in checkout page
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
add_action( 'woocommerce_review_order_after_submit', 'move_checkout_coupon_field', 1 );
function move_checkout_coupon_field() {
?>
<form class="woocommerce-coupon-form" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" method="post">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon under-proceed">
<input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" style="width: 100%; margin-top: 10px;" />
<button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>" style="width: 100%"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
</div>
<?php } ?>
</form>
<?php
}
How to change Woocommerce coupon field location on checkout page v.2?
There’s also another way to move your Woocommerce coupon field location on checkout page. Here’s the end result.
So, to make it work like that, just use this snippet.
// Change Woocommerce coupon field location in checkout page?
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
add_action( 'woocommerce_review_order_after_submit', 'wpsh_move_coupon_button', 1 );
function wpsh_move_coupon_button() {
echo '<hr/';
woocommerce_checkout_coupon_form();
}
How to make adding a coupon mandatory for certain Woocommerce products?
This snippet here below allows you to make adding a coupon mandatory for certain Woocommerce products. For example, see the screenshot here below.
What happens here is that:
- If cart contains a product with ID-s 400 (Golden lamp) or 510 (Hartek lamp)
- then adding a coupon “abs30” or “test20” is mandatory
- otherwise the checkout page is disabled
- if coupon is added then checkout page is open
// Make adding a coupon mandatory for certain Woocommerce products
add_action( 'woocommerce_check_cart_items', 'wpsh_mandatory_coupon' );
function wpsh_mandatory_coupon() {
$targeted_ids = array(400, 510); // Add the product ID-s for the mandatory coupon here
$coupon_codes = array('abc30', 'test20'); // Add the coupon codes here
$coupons_found = array_intersect( array_filter( array_map( 'sanitize_title', $coupon_codes) ), WC()->cart->get_applied_coupons() );
// Loop through cart items
foreach(WC()->cart->get_cart() as $item ) {
// Check cart item for defined product Ids and applied coupon
if( in_array( $item['product_id'], $targeted_ids ) && empty($coupons_found) ) {
wc_clear_notices(); // Clear all other notices
// Avoid checkout displaying an error notice
wc_add_notice( sprintf( 'The product "%s" requires a coupon for checkout.', $item['data']->get_name() ), 'error' );
break; // stop the loop
}
}
}
How to not apply any coupon if WooCommerce Cart contains back-ordered products?
One of my customers asked recently how to not apply any coupon if WooCommerce Cart contains back-ordered products? If you have the same question, then just use this snippet here below.
// Don’t apply any coupon if WooCommerce Cart contains back-ordered products?
add_filter( 'woocommerce_coupon_is_valid', 'wpsh_disable_coupons_for_backorder', 99, 2 );
function wpsh_disable_coupons_for_backorder( $valid, $coupon ){
$valid = true;
foreach ( WC()->cart->get_cart() as $cart_item ) {
// if($values['data']->backorders_allowed()){ //check if backorders are allowed on this product
// get the stock quantity - returns the available amount number
$stock_info = $cart_item['data']->get_stock_quantity();
if( $stock_info < 1 ){
$valid = false;
break;
}
}
return $valid ;
}
How to display Woocommerce coupon discount percentage on cart and checkout page?
By default, Woocommerce doesn’t display a discount percentage and instead shows only that coupon has been applied. So, if you would like to display Woocommerce coupon discount percentage in cart and checkout page then use this snippet.
Here’s the result.
// Display Woocommerce Coupon discount percentage in cart and checkout page
add_filter('woocommerce_cart_totals_coupon_html','wpsh_coupon_percentage',10,2);
add_filter('woocommerce_checkout_item_subtotal','wpsh_coupon_percentage',10,2);
function wpsh_coupon_percentage($value, $coupon)
{
if($coupon->get_discount_type() == 'percent' && !empty($coupon->get_amount()))
{
$amt = "<p><em><strong>You’ve got a deal with {$coupon->get_amount()}% OFF</strong></em></p>";
}
return $value.$amt;
}
How to display Woocommerce product discount in cart and checkout page after coupon is applied?
Now let’s take a look at how to display Woocommerce product discount in cart and checkout page after coupon is applied. See screenshot.
// Display Woocommerce product discount in cart and checkout page after coupon is applied
add_filter( 'woocommerce_cart_item_subtotal', 'wpsh_coupon_discount', 100, 3 );
function wpsh_coupon_discount( $subtotal, $cart_item, $cart_item_key ){
//Get product object
$_product = $cart_item['data'];
$line_subtotal_tax = $cart_item['line_subtotal_tax'];
if( $cart_item['line_subtotal'] !== $cart_item['line_total'] ) {
$line_tax = $cart_item['line_tax'];
$regular_price = $_product->get_regular_price()* $cart_item['quantity'];
$discountAmt=wc_price(($regular_price-$cart_item['line_subtotal']-$line_tax) + ($cart_item['line_subtotal']- $cart_item['line_total']));
$subtotal = sprintf( '<del>%s</del> <ins>%s</ins><p style="color:green;font-size:14px;"><span style="color:#242156;"><i class="fa fa-tags" aria-hidden="true"></i> Coupon applied</span><br>You Saved: %s</p>', wc_price($regular_price), wc_price($cart_item['line_total'] + $line_tax),$discountAmt );
}else{
if( '' !== $_product->get_sale_price() ) {
$regular_price = $_product->get_regular_price() * $cart_item['quantity'];
$sale_price = $_product->get_sale_price() * $cart_item['quantity'];
$discountAmt=wc_price($regular_price-$sale_price);
$subtotal = sprintf( '<del>%s</del> <ins>%s</ins><p style="color:green;font-size:14px;">You Saved: %s</p>', wc_price($regular_price), wc_price($_product->get_sale_price()),$discountAmt );
}
}
return $subtotal;
}
How to create Woocommerce coupon automatically after purchase (and display it on the Thank you page)?
One way to motivate your customers to buy more is to give them discounts. So, let’s see how to create Woocommerce coupon automatically after purchase and display it on the Thank you page.
// Create Woocommerce Coupon Code Automatically After Purchase and display it on the thank you page
add_action( 'woocommerce_before_thankyou', 'wpsh_create_coupon_code', 2 );
function wpsh_create_coupon_code($order_id) {
$order = wc_get_order( $order_id );
$billing_first_name = $order->get_billing_first_name();
$coupon = new WC_Coupon();
$coupon->set_code( $billing_first_name . '20' ); // Coupon code will contain billing first name and 20. For example: John20
$coupon->set_amount( 20 ); // Discount amount
$coupon->set_discount_type( 'percent' ); // Discount type can be 'fixed_cart', 'percent' or 'fixed_product', defaults to 'fixed_cart'
$coupon->set_usage_limit( 1 ); // usage limit
$coupon->save();
echo '<div class="woocommerce-message">Here’s your personal coupon for your next purchase: ' . $billing_first_name . '20 which gives you 20% discount.</div>';
}
How to display a WooCommerce coupon input field anywhere on your site with a shortcode?
Take a look at this screenshot below, and you’ll see that I added Woocommerce input field on my single product page. So, let’s take a closer look.
// Display a WooCommerce coupon input field anywhere on your site with a shortcode
add_shortcode( 'coupon_field', 'display_coupon_field' );
function display_coupon_field() {
if( isset($_GET['coupon']) && isset($_GET['redeem-coupon']) ){
if( $coupon = esc_attr($_GET['coupon']) ) {
$applied = WC()->cart->apply_coupon($coupon);
} else {
$coupon = false;
}
$success = sprintf( __('Coupon "%s" Applied successfully.'), $coupon );
$error = __("This Coupon can't be applied");
$message = isset($applied) && $applied ? $success : $error;
}
$output = '<div class="redeem-coupon"><form id="coupon-redeem">
<p><input type="text" style="width: 60%; float: left;" name="coupon" id="coupon"/>
<input type="submit" name="redeem-coupon" style="width: 40%;" value="'.__('Redeem Offer').'" /></p>';
$output .= isset($coupon) ? '<p class="result">'.$message.'</p>' : '';
return $output . '</form></div>';
}
If you would like to display Woocommerce coupon field on a single product page then you need to add also this snippet.
// Display coupon field in Woocommerce single product page
add_action( 'woocommerce_product_meta_end', 'wpsh_coupon_field_on_single_product_page' );
function wpsh_coupon_field_on_single_product_page() {
echo 'Have a coupon? Enter it here below.';
echo do_shortcode('[coupon_field]');
}
How to automatically apply Woocommerce coupon based on cart quantity?
For example, let’s add a rule “If cart contains at least 4 products or more, then add automatically coupon “test20″”.
// Automatically apply Woocommerce coupon based on cart quantity
add_action( 'woocommerce_before_calculate_totals', 'wpsh_autoapply_coupon', 25, 1 );
function wpsh_autoapply_coupon( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Setting and initialising variables
$coupon = 'test20'; // Here goes your coupon code
$item_count = 4; // Here goes the number of items
$matched = false;
if( $cart->cart_contents_count >= $item_count ){
$matched = true;
}
// If conditions are matched add coupon is not applied
if( $matched && ! $cart->has_discount( $coupon )){
// Apply the coupon code
$cart->add_discount( $coupon );
// Optionally display a message
wc_add_notice( __('20% discount coupon added'), 'notice');
}
// If conditions are not matched and coupon has been appied
elseif( ! $matched && $cart->has_discount( $coupon )){
// Remove the coupon code
$cart->remove_coupon( $coupon );
// Optionally display a message
wc_add_notice( __('Sorry, discount is not available'), 'error');
}
}
How to Apply a Woocommerce Coupon for Minimum Cart Total?
This is a slightly different approach than previous one. In this example we will set up a coupon called “test20” and it will give 20% discount for orders with minimum 50 euros cart total.
Now, if the cart total is less than 50 euros then the message “Get 20% off if you spend more than 50 euros” is automatically shown on Woocommerce cart and Checkout pages. If the minimum cart total is more than 50 euros then this coupon is automatically applied and “You just got 20% off your order!” is shown (see the screenshot).
// Apply a Woocommerce Coupon for Minimum Cart Total
add_action( 'woocommerce_before_cart' , 'add_coupon_notice' );
add_action( 'woocommerce_before_checkout_form' , 'add_coupon_notice' );
function add_coupon_notice() {
$cart_total = WC()->cart->get_subtotal();
$minimum_amount = 50; // Set your minimum cart total
$currency_code = get_woocommerce_currency();
wc_clear_notices();
if ( $cart_total < $minimum_amount ) {
WC()->cart->remove_coupon( 'test20' ); // Replace your copuon code.
wc_print_notice( "Get 20% off if you spend more than $minimum_amount $currency_code!", 'notice' );
} else {
WC()->cart->apply_coupon( 'test20' );
wc_print_notice( 'You just got 20% off your order!', 'notice' );
}
wc_clear_notices();
}
How to display Woocommerce discounted price on cart and checkout page if coupon has been applied?
Next, let’s take a look at how to display Woocommerce discounted price on cart and checkout page if coupon has been applied. See the screenshot.
// Display Woocommerce discounted price on cart and checkout page if coupon has been applied?
add_filter( 'woocommerce_cart_item_subtotal', 'wpsh_display_coupon_discount', 99, 3 );
function wpsh_display_coupon_discount( $subtotal, $cart_item, $cart_item_key ) {
$cart = WC()->cart;
$coupons = $cart->get_coupons();
// If no coupons, just go with subtotal.
if ( empty( $coupons ) ) {
return $subtotal;
}
// Set defaults.
$label = '';
$discounted_price = 0;
$amount_prev = 0;
$newsubtotal = '';
$iterator = 1;
$coupons_count = is_countable( $coupons ) ? count( $coupons ) : 0;
foreach ( $coupons as $coupon ) {
$data = $coupon->get_data();
$coupon_code = $data['code'];
$amount = $data['amount'];
$type = $data['discount_type'];
if ( $cart->has_discount( $coupon_code ) && $coupon->is_valid() ) {
$label = __( 'Coupon: ', 'textdomain' ) . $coupon_code;
// Sequentially apply coupons is applying next coupon to already disconted price, not original price.
$apply_seq = 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ? true : false;
// Price to be discounted - already discounted or original.
$price_to_discount = ( $apply_seq && $discounted_price ) ? $discounted_price : $cart_item['data']->get_price();
// Calculate the discount, depending on the discount type.
if ( 'percent' === $type ) {
$discounted_price = $price_to_discount - ( $price_to_discount * ( ( $amount + $amount_prev ) / 100 ) );
} elseif ( 'fixed_product' === $type ) {
$discounted_price = $price_to_discount - ( $amount + $amount_prev );
}
// Add the currency and html to new subtotal (after multiplied with quantity).
$wc_html_subtotal = wc_price( $discounted_price * $cart_item['quantity'] );
// New subtotal for each coupon discount and the final newsubtotal.
if ( $iterator < $coupons_count ) {
$newsubtotal .= sprintf( '<div class="discount"><small class="coupon-code">%s</small><s>%s</s></div>', $label, $wc_html_subtotal );
} else {
$newsubtotal .= sprintf( '<div class="discount"><small class="coupon-code">%s</small>%s</div>', $label, $wc_html_subtotal );
}
}
// If coupons not applied sequentially, apply all the coupons combined to the original price.
$amount_prev = ! $apply_seq ? $amount : 0;
$iterator++;
}
// Subtotal with new subtotal(s) added (applied coupons).
$subtotal = sprintf( '<s>%s</s> %s', $subtotal, $newsubtotal );
return $subtotal;
}
Now, in order to make it look like the one you see on the screenshot above, add this piece of CSS to your Customizer >> Additional CSS area.
.woocommerce table.shop_table .product-subtotal s,
.woocommerce table.shop_table .product-total > s {
font-size: 0.95em;
font-weight: normal;
margin: 0px !important;
opacity: 0.7;
}
.woocommerce table.shop_table .product-subtotal s,
.woocommerce table.shop_table .product-subtotal > span,
.woocommerce table.shop_table .product-total s,
.woocommerce table.shop_table .product-total > span {
line-height: 1.4;
margin: 5px;
}
.woocommerce table.shop_table .product-subtotal > span,
.woocommerce table.shop_table .product-total > span {
font-weight: bold;
}
.discount {
position: relative;
display: block;
}
.discount > * {
display: inline-block;
}
.coupon-code {
padding: 1px 4px 0px;
border: 1px solid #ddd;
line-height: 1.5;
background: #fbf2e5;
margin-right: 4px;
text-transform: uppercase;
font-size: 9px;
font-weight: bold !important;
border-radius: 4px;
opacity: 0.8;
}
@media screen and (max-width: 480px) {
.coupon-code {
display: none;
}
}
How to set all Woocommerce shipping rates to 0 if free shipping coupon is used?
Woocommerce allows you to allow free shipping if a coupon is used. This also means that you need to set up a free shipping method for your shop.
With the help of this snippet you can set all shipping rates to 0 if a free shipping coupon is used. See the screenshot.
// Set all Woocommerce shipping rates to 0 if free shipping coupon is used
add_filter( 'woocommerce_package_rates', 'wpsh_free_shipping_coupon', 20, 2 );
function wpsh_free_shipping_coupon( $rates, $package ) {
$has_free_shipping = false;
$applied_coupons = WC()->cart->get_applied_coupons();
foreach( $applied_coupons as $coupon_code ){
$coupon = new WC_Coupon($coupon_code);
if($coupon->get_free_shipping()){
$has_free_shipping = true;
break;
}
}
foreach( $rates as $rate_key => $rate ){
if( $has_free_shipping ){
// For "free shipping" method (enabled), remove it
if( $rate->method_id == 'free_shipping'){
unset($rates[$rate_key]);
}
// For other shipping methods
else {
// Append rate label titles (free)
$rates[$rate_key]->label .= ' ' . __('(free)', 'woocommerce');
// Set rate cost
$rates[$rate_key]->cost = 0;
// Set taxes rate cost (if enabled)
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = 0;
}
$rates[$rate_key]->taxes = $taxes;
}
}
}
return $rates;
}
How to create a coupon programmatically in Woocommerce?
Just a simple snippet for those who want to create a coupon programmatically in Woocommerce.
// Create a coupon programmatically in Woocommerce
add_action('wp_loaded' , 'wpsh_create_coupon');
function wpsh_create_coupon(){
$coupon = new wc_coupon();
if( !wc_get_coupon_id_by_code( 'yourcouponname20' ) ) { // Add your coupon name here
$coupon->set_code('yourcouponname20'); // Create coupon code
$coupon->set_discount_type( 'percent' ); // Discount type can be 'fixed_cart', 'percent' or 'fixed_product', defaults to 'fixed_cart'
$coupon->set_amount( 20 ); // Discount amount
$coupon->set_usage_limit( 10 ); // Usage limit
$coupon->save();
}
}
How to delete WooCommerce coupons automatically after they expire?
So, you set up an expiration date for your coupons, and you would not like to clutter your database after those coupons have expired. Which means, you need a snippet which allows you to delete WooCommerce coupons automatically after they expire. Take a look at the snippet here below. It automatically deletes those coupons 10 days after the expiration date .
PS! Line 13 is the one you may need to tweak in order to set up the days amount.
// Delete WooCommerce coupons automatically after they expire
add_action( 'delete_expired_coupons', 'wpsh_delete_expired_coupons' );
function wpsh_delete_expired_coupons() {
$args = array(
'posts_per_page' => -1,
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'date_expires',
'value' => strtotime( '-10 days', current_time( 'timestamp' ) ),
'compare' => '<='
),
array(
'key' => 'date_expires',
'value' => '',
'compare' => '!='
)
)
);
$coupons = get_posts( $args );
if ( ! empty( $coupons ) ) {
foreach ( $coupons as $coupon ) {
wp_trash_post( $coupon->ID );
}
}
}