Create a coupon programmatically since WooCommerce 3+

1.3k views Asked by At

I add coupons at woocommerce with this code programmatically.

    if(empty($coupon_post)){

        $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', 'yes' );
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', '' );
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' );      
update_post_meta( $new_coupon_id, 'exclude_sale_items', 'no' );     
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );      
update_post_meta( $new_coupon_id, 'product_categories', '' );       
update_post_meta( $new_coupon_id, 'exclude_product_categories', '' );       
update_post_meta( $new_coupon_id, 'minimum_amount', '' );       
update_post_meta( $new_coupon_id, 'customer_email', '' ); 
    }

But it says always the usage_limit = 1.

I add additional this code to update:

add_action( 'save_post_shop_coupon', 'my_child_after_coupon_save', 10, 3 );

function my_child_after_coupon_save( $post_id, $post, $update ) {
   update_post_meta( $post_id, 'usage_limit', '');
}

But it doesn't work first.But if I open the coupon in the backend and update without any changes. The usage limit is set to unlimited.

How can trigger this, that I needn't to open all coupons.

1

There are 1 answers

0
LoicTheAztec On BEST ANSWER

Since WooCommerce 3, your code is a bit outdated as for example apply_before_tax is not used anymore. You should better use all available WC_Coupon setter methods, for coupon creation.

In the code below I just use the necessary setter methods (related to your code):

// Get an empty instance of the WC_Coupon Object
$coupon = new WC_Coupon();

// Set the necessary coupon data (since WC 3+)
$coupon->set_code( $coupon_code ); // (string)
// $coupon->set_description( $description ); // (string)
$coupon->set_discount_type( $discount_type ); // (string)
$coupon->set_amount( $coupon_amount ); // (float)
// $coupon->set_date_expires( $date_expires ); // (string|integer|null)
// $coupon->set_date_created( $date_created ); // (string|integer|null)
// $coupon->set_date_modified( $date_created ); // (string|integer|null)
// $coupon->set_usage_count( $usage_count ); // (integer)
$coupon->set_individual_use( true ); // (boolean) 
// $coupon->set_product_ids( $product_ids ); // (array)
// $coupon->set_excluded_product_ids( $excl_product_ids ); // (array)
$coupon->set_usage_limit( 0 ); // (integer)
// $coupon->set_usage_limit_per_user( $usage_limit_per_user ); // (integer)
// $coupon->set_limit_usage_to_x_items( $limit_usage_to_x_items ); // (integer|null)
// $coupon->set_free_shipping( $free_shipping ); // (boolean) | default: false
// $coupon->set_product_categories( $product_categories ); // (array)
// $coupon->set_excluded_product_categories( $excl_product_categories ); // (array)
// $coupon->set_exclude_sale_items( $excl_sale_items ); // (boolean)
// $coupon->set_minimum_amount( $minimum_amount ); // (float)
// $coupon->set_maximum_amount( $maximum_amount ); // (float)
// $coupon->set_email_restrictions( $email_restrictions ); // (array)
// $coupon->set_used_by( $used_by ); // (array)
// $coupon->set_virtual( $is_virtual ); // (array)

// Create, publish and save coupon (data)
$coupon->save();

Now to update coupons you can use the following hooked function with any setter method like:

add_action( 'woocommerce_coupon_options_save', 'action_coupon_options_save', 10, 2 );
function action_coupon_options_save( $post_id, $coupon ) {
    $coupon->set_usage_limit( 0 );
    $coupon->save();
}

Code goes in functions.php file of the active child theme (or active theme).