Programatically create multiple coupons in WooCommerce - php

I've been looking for a way to add coupons in bulk to WooCommerce, it's actually a list of 800 membership numbers, that grant a discount, and coupons seem to the best way to do this.
I've found a way to add a single coupon programatically: http://docs.woothemes.com/document/create-a-coupon-programatically/ but my limited PHP knowledge doesn't seem adequate to add 800.
I'm guessing an array or somehow linking to a .csv would do it, but I'm not sure. I'd be grateful for any help.

You could create an array of 800 diferent keys and just make a foreach loop to repeat the process for each different key you have on the array like this
forehach ( $your_800_array as $coupon_code){
//the code from the page you posted
$amount = '10'; // Amount
$discount_type = 'fixed_cart'; // 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', '' );
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' );
}
(Used the code that OP posted inside the loop. Not actually tested)

Related

Create a coupon programmatically since WooCommerce 3+

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.
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).

Is there a way to generate a number of Woocommerce coupons based on a certain amount?

I'm fixing a plugin-loaded Woocommerce site and now I have a requirement to implement an automatic coupon generator based on the purchase amount: for example, I would like to establish a rule for every $100 purchase, if the customer buys $450, 4 discount coupons of $40 will be generated. All of this codes should be sent to the customer.
I've reviewed the WooCommerce documentation where I can create the coupons: https://docs.woocommerce.com/document/create-a-coupon-programatically/ and already implemented it and sending in the order review mail (after payment has been confirmed):
function add_order_email_instructions( $order, $sent_to_admin ) {
if ( ! $sent_to_admin && $order->get_user_id() && 'processing' == $order->get_status()) {
$lista_cupones = array();
$amount = '40';
for ($i=1; $i<=$order->get_total()/100; $i++) {
$longitud = 12;
$key = '';
$pattern = '1234567890ABCDFGHIJKLMNOPQRSTUWYZ';
$max = strlen($pattern)-1;
for($i=0;$i < $longitud;$i++) $key .= $pattern{mt_rand(0,$max)};
$coupon_code = $key;
$discount_type = 'fixed_cart';
$coupon = array(
'post_title' => $coupon_code,
'post_content' => ''.$to,
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
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, 'minimum_amount', '100' );
update_post_meta( $new_coupon_id, 'exclude_sale_items', 'yes' );
update_post_meta( $new_coupon_id, 'exclude_sale', 'yes' );
update_post_meta( $new_coupon_id, 'usage_limit', '1' );
update_post_meta( $new_coupon_id, 'expiry_date', strtotime("+3 days") );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );
array_push($lista_cupones, $coupon_code);
}
echo '<h2>';
printf( __( 'Obtén 40 soles de descuento')
);
echo '</h2>';
printf(
__( 'Gracias por su compra. Use el código de descuento <strong>%2$s</strong> para recibir %1$s soles de descuento en su siguiente compra.'),
$amount,
$coupon_code
);
echo '</p>';
}
}
add_action('woocommerce_email_before_order_table','add_order_email_instructions',10);
Now this half works: it validates if order total is less than $100 and doesn't generate a coupon but if it's higher it only gives me one coupon even if order total is 200, 300 400, etc. (it doesn't even generate more than one coupon, seems like it only goes through the loop once and stops).
Thanks!
Already solved, this is the code:
function create_coupon () {
$amount = '40';
$longitud = 12;
$key = '';
$pattern = '1234567890ABCDFGHIJKLMNOPQRSTUWYZ';
$max = strlen($pattern)-1;
for($i=0;$i < $longitud;$i++) $key .= $pattern{mt_rand(0,$max)};
$coupon_code = $key;
$discount_type = 'fixed_cart';
$coupon = array(
'post_title' => $coupon_code,
'post_content' => ''.$to,
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
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, 'minimum_amount', '100' );
update_post_meta( $new_coupon_id, 'exclude_sale_items', 'yes' );
update_post_meta( $new_coupon_id, 'exclude_sale', 'yes' );
update_post_meta( $new_coupon_id, 'usage_limit', '1' );
update_post_meta( $new_coupon_id, 'expiry_date', strtotime("+3 days") );
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, 'customer_email', $order->get_billing_email());
return $coupon_code;
}
function add_order_email_instructions( $order, $sent_to_admin ) {
if ( ! $sent_to_admin && $order->get_user_id() && 'processing' == $order->get_status()) {
$lista_cupones = [];
$numero_cupones = $order->get_total()/100;
for ($i=1; $i<=$numero_cupones; $i++) {
array_push($lista_cupones, create_coupon());
}
echo '<h2>';
printf( __( 'Obtén 40 soles de descuento')
);
echo '</h2>';
printf(
__( 'Gracias por su compra. Use el código de descuento <strong>%2$s</strong> para recibir %1$s soles de descuento en su siguiente compra.'),
$amount,
$lista_cupones
);
echo '<br></p>';
}
}
add_action('woocommerce_email_before_order_table','add_order_email_instructions',10);
This is unfinished, now I have to show it in the adequate array format within the mail

WooCommerce Coupon Field Extension

I added new custom post type 'giftcard' and extended WooCommerce simple product by adding checkbox 'Gift Card'
Whenever order status changed to 'processing' and it contains product type giftcard, it creates new giftcard post by following code
function status_order_processing( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$is_gift_card = get_post_meta( $item['product_id'], '_woo_giftcard', true );
if($is_gift_card == 'yes'){
$token = base64_encode(openssl_random_pseudo_bytes(32));
$token = bin2hex($token);
$hyphen = chr(45);
$uuid = substr($token, 0, 8).$hyphen
.substr($token, 8, 4).$hyphen
.substr($token,12, 4).$hyphen
.substr($token,16, 4).$hyphen
.substr($token,20,12);
$gift_card = array(
'post_title' => $uuid,
'post_status' => 'publish',
'post_type' => 'giftcard',
);
$gift_card_id = wp_insert_post( $gift_card, $wp_error );
update_post_meta( $gift_card_id, 'woo_gift_card_amount', (int)$item['total'] );
}
}
add_action( 'woocommerce_order_status_processing', 'status_order_processing' );
New post name is a token generated in above code and save item total in meta field 'woo_gift_card_amount'.
Is there any way if I enter giftcard post type token in coupon field and it subtracts amount from Order amount according to meta field 'woo_gift_card_amount' of that post.
Any help would be appreciated.
Coupons are also a custom post. To use your gift card token/uuid as woocommerce coupon, you will need to insert it as a new post in shop_coupon post type.
A quick example (this should go inside your status_order_processing function, or you can use separate function - whichever way suits you):
$coupon_code = $uuid;
$amount = (int)$item['total'];
$discount_type = 'fixed_cart'; //available types: 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 );
if ( $new_coupon_id ) {
//add coupon/post 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, 'expiry_date', $expiry_date);
//update_post_meta($new_coupon_id, 'usage_limit', '1');
//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', '' );
//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' );
}

Set a coupon description in WooCommerce

My site dynamically gives users coupons if they have been a member for a long enough time. When I am generating the coupon I want to assign a description to the coupon. However, I seem to be unable to assign a description by updating the post's metadata with the key description as the docs suggest I should be able to.
Currently I am trying to assign the description like so:
$percent = 25;//DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; //Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
//ASSIGN COUPON AND DISCOUNT PERCENTAGE
$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 );//SET DICOUNT TO BE PERCENTAGE BASED
update_post_meta( $new_coupon_id, 'coupon_amount', $percent );//SET DISCOUNT PERCENTAGE
update_post_meta( $new_coupon_id, 'individual_use', 'yes' );//ONLY ONE CUPON BE USED AT A TIME
update_post_meta( $new_coupon_id, 'product_ids', '' ); //INCLUDE ALL PRODUCTS
update_post_meta( $new_coupon_id, 'exclude_product_ids', '' );//DO NOT EXCLUDE ANY PRODUCTS
update_post_meta( $new_coupon_id, 'usage_limit', '1' );//ONE TIME USE
update_post_meta( $new_coupon_id, 'expiry_date', strtotime("+6 months") );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'yes' );
update_post_meta( $new_coupon_id, 'free_shipping', 'no' );//DO NOT GIVE FREE SHIPPING
//ASSIGN DESCRIPTION TO COUPON
update_post_meta( $new_coupon_id, 'description', 'This is an example description used for the example coupon');
How else should I go about adding a description?
The coupon description has to be added in the post data as post_excerpt key (but not in post meta data)…
So your code should be instead:
$percent = 25;//DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; //Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
$description = __('This is an example description used for the example coupon');
//ASSIGN COUPON AND DISCOUNT PERCENTAGE
$coupon = array(
'post_title' => $coupon_code,
'post_content' => '',
'post_excerpt' => $description, // <== HERE goes the description
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
## … / … and so on
Or instead, since WooCommerce 3, you can use any related method on a WC_Coupon Object. In your case you will use setter methods to set the data (as getter methods are used to get the data on an existing coupon object):
// Get an instance of the WC_Coupon object
$wc_coupon = new WC_Coupon($coupon_code);
// Some data
$percent = 25; // DISCOUNT PERCENTAGE
$coupon_code = 'testcoupon'; // Coupon Code
$discount_type = 'percent'; // Type: fixed_cart, percent, fixed_product, percent_product
$description = __('This is an example description used for the example coupon'); // Description
// Set the coupon data
$wc_coupon->set_code($coupon_code);
$wc_coupon->set_description($description);
$wc_coupon->set_discount_type($discount_type);
$wc_coupon->set_amount( floatval($percent) );
$wc_coupon->set_individual_use( true );
$wc_coupon->set_usage_limit( 1 );
$wc_coupon->set_date_expires( strtotime("+6 months") );
## $wc_coupon->apply_before_tax( true ); // ==> Deprecated in WC 3+ with no replacement alternatie
$wc_coupon->set_free_shipping( false );
// Test raw data output before save
var_dump($wc_coupon);
// SAVE the coupon
$wc_coupon->save();

How to use customer email address as their own coupon code in woocommerce

I am trying to use customer email address as their own coupon code with a special discount. To achieve this I tried bellow code but nothing happen shows error Call to undefined function get_currentuserinfo(). Is it possible to use coupon code virtually not saving like custom post_type?
Here is the code what I'm trying so far.
global $current_user;
get_currentuserinfo();
$user_email = $current_user->user_email ;
$coupon_code = $user_email; // Code
$amount = '10'; // Amount
$discount_type = 'fixed_cart'; // 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', '' );
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' );
The get_currentuserinfo() function is deprecated. Use wp_get_current_user() instead.
You should use in your code:
// (Optional) depending where you are using this code
is_user_logged_in(){
global $current_user;
// If global $current_user is not working
if(empty($current_user))
$current_user = wp_get_current_user();
// Here goes all your other code below… …
}
After that, I have never tried to set an email as coupon code slug programatically, but it should work as it's possible to set in woocommerce a coupon code with an email address (I have test it with success)…
add_action( 'user_register', 'coupon_email', 10, 1 );
function coupon_email( $user_id ) {
if ( isset( $_POST['email_address'] ) )
$coupon = array(
'post_title' => $_POST['email_address'],
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
);
$new_coupon_id = wp_insert_post( $coupon );
}
This will add a coupon with the users email address as the title and input every time a new user registers for your website.

Categories