Search code examples
phpwordpresswoocommercediscountcoupon

Apply a coupon programmatically in Woocommerce


In Woocommerce I'm trying to find a way to apply a 10% discount to an entire customer's order if the weight in the cart is over 100 lbs. I'm partway to achieving this. For the next step, I'm looking for a way to programmatically apply a coupon code via action/hook through functions.php.

It appears that I can use the function woocommerce_ajax_apply_coupon to do this ( http://docs.woothemes.com/wc-apidocs/function-woocommerce_ajax_apply_coupon.html ) but I am unsure of how to use it.

So far I've modified cart.php to get the total weight of all the products in the cart, I've created a coupon that applies the discount (if entered manually) and I've added some code to functions.php to check the weight and display a message to the user.

EDIT: Partial code removed, completed code included in the solution below.


Thanks for the guidance Freney. Here's the working end result which successfully applies the discount coupon when the condition is met and also removes it when it's no longer met:

/* Mod: 10% Discount for weight greater than 100 lbs 
Works with code added to child theme: woocommerce/cart/cart.php lines 13 - 14: which gets $total_weight of cart:
        global $total_weight;
        $total_weight = $woocommerce->cart->cart_contents_weight;
*/
add_action('woocommerce_before_cart_table', 'discount_when_weight_greater_than_100');
function discount_when_weight_greater_than_100( ) {
    global $woocommerce;
    global $total_weight;
    if( $total_weight > 100 ) {
        $coupon_code = '999';
        if (!$woocommerce->cart->add_discount( sanitize_text_field( $coupon_code ))) {
            $woocommerce->show_messages();
        }
        echo '<div class="woocommerce_message"><strong>Your order is over 100 lbs so a 10% Discount has been Applied!</strong> Your total order weight is <strong>' . $total_weight . '</strong> lbs.</div>';
    }
}

/* Mod: Remove 10% Discount for weight less than or equal to 100 lbs */
add_action('woocommerce_before_cart_table', 'remove_coupon_if_weight_100_or_less');
function remove_coupon_if_weight_100_or_less( ) {
    global $woocommerce;
    global $total_weight;
    if( $total_weight <= 100 ) {
        $coupon_code = '999';
        $woocommerce->cart->get_applied_coupons();
        if (!$woocommerce->cart->remove_coupons( sanitize_text_field( $coupon_code ))) {
            $woocommerce->show_messages();
        }
        $woocommerce->cart->calculate_totals();
    }
}

Solution

  • First, create a discount coupon (via http://docs.woothemes.com/document/create-a-coupon-programatically/):

    $coupon_code = 'UNIQUECODE'; // Code - perhaps generate this from the user ID + the order ID
    $amount = '10'; // Amount
    $discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
    
    $coupon = array(
        'post_title' => $coupon_code,
        'post_content' => '',
        'post_status' => 'publish',
        'post_author' => 1,
        'post_type'     => 'shop_coupon'
    );    
    
    $new_coupon_id = wp_insert_post( $coupon );
    
    // Add meta
    update_post_meta( $new_coupon_id, 'discount_type', $discount_type );
    update_post_meta( $new_coupon_id, 'coupon_amount', $amount );
    update_post_meta( $new_coupon_id, 'individual_use', 'no' );
    update_post_meta( $new_coupon_id, 'product_ids', '' );
    update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );
    update_post_meta( $new_coupon_id, 'usage_limit', '1' );
    update_post_meta( $new_coupon_id, 'expiry_date', '' );
    update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
    update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
    

    Then apply that coupon to your order:

    if (!$woocommerce->cart->add_discount( sanitize_text_field( $coupon_code )))
        $woocommerce->show_messages();
    

    That last function returns a BOOL value: TRUE if the discount was successful, FALSE if it fails for any one of a variety of reasons.