I'm currently using Gravity Forms (with referral as lead enabled). I'm using a hook on submit to generate a random coupon based off of a coupon template (in my functions.php). My goal is to then have that coupon automatically applied to their order at the checkout page. I'm successfully able to generate the coupon, but can't quite figure out how to apply it. FYI- I do not use a cart in the user experience, so Product Page > Checkout.
If someone could provide some help, or point me in the right direction, I'd be grateful.
// Generate Random Coupon
function after_submission () {
$coupon_code = substr( "abcdefghijklmnopqrstuvwxyz123456789", mt_rand(0, 50) , 1) .substr( md5( time() ), 1); // Code
$coupon_code = substr( $coupon_code, 0,10); // create 10 letters coupon
$amount = '0'; // Amount
$discount_type = 'free_shipping'; // Type: fixed_cart, percent, fixed_product, percent_product
$coupon = array(
'post_title' => $coupon_code,
'post_content' => 'Free Shipping & Handling',
'post_excerpt' => 'Free Shipping & Handling',
'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', '1' );
update_post_meta( $new_coupon_id, 'expiry_date', '' );
update_post_meta( $new_coupon_id, 'apply_before_tax', 'no' );
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', 'yes' );
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', '' );
return $coupon_code;
}
// Gravity Forms Referral
add_action( 'gform_after_submission_9', 'after_submission', 10, 2 );
// Add generated coupon to cart
add_action( 'woocommerce_add_to_cart', 'apply_matched_coupons' );
function apply_matched_coupons() {
if ( is_cart() || is_checkout() ) return;
if ( WC()->cart->has_discount( $coupon_code ) ) return;
WC()->checkout->add_discount( $coupon_code );
}
You need to set in a WC session variable the created coupon code. Then you will be able to get it easely.
Since WooCommerce 3, your code is a bit obsolete, with mistakes. Try the following instead:
// Early enable customer WC_Session
add_action( 'init', 'wc_session_enabler' );
function wc_session_enabler() {
if ( is_user_logged_in() || is_admin() )
return;
if ( isset(WC()->session) && ! WC()->session->has_session() ) {
WC()->session->set_customer_session_cookie( true );
}
}
// Utility function that generate a non existing coupon code (as each coupon code required to be unique)
function generated_counpon_code() {
for ( $i = 0; $i < 1; $i++ ) {
$coupon_code = strtolower( wp_generate_password( 10, false ) );
// Check that the generated code doesn't exist yet
if( coupon_exists( $coupon_code ) ) $i--; // continue
else break; // Stop the loopp
}
return $coupon_code;
}
function coupon_exists( $coupon_code ) {
global $wpdb;
return $wpdb->get_var( $wpdb->prepare("SELECT COUNT(ID) FROM $wpdb->posts
WHERE post_type = 'shop_coupon' AND post_name = '%s'", $coupon_code));
}
// Generate coupon and set code in customer WC session variable
function after_submission () {
// Get a random unique coupon code
$coupon_code = generated_counpon_code();
// Get an empty instance of the WC_Coupon Object
$coupon = new WC_Coupon();
$coupon->set_code( $coupon_code );
$coupon->set_status( 'publish' );
$coupon->set_discount_type( 'fixed_cart' );
$coupon->set_description( __('Free Shipping & Handling') );
$coupon->set_amount( 0 );
$coupon->set_usage_limit( 1 );
$coupon->set_free_shipping( 1 ); // <== Added back
$coupon->set_individual_use( 1 );
// Save coupon (data)
$coupon->save();
WC()->session->set( 'unique_coupon', $coupon_code );
}
// Gravity Forms Referral (hook)
add_action( 'gform_after_submission_9', 'after_submission', 10, 2 );
// Add generated coupon to cart
add_action( 'woocommerce_add_to_cart', 'apply_matched_coupons' );
function apply_matched_coupons() {
if ( is_cart() || is_checkout() ) return;
// Load coupon code
$coupon_code = WC()->session->get( 'unique_coupon' );
if ( $coupon_code && ! WC()->cart->has_discount( $coupon_code ) ) {
WC()->cart->apply_coupon( $coupon_code ); // Apply coupon code
WC()->session->__unset( 'unique_coupon' ); // remove session variable
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Documentation: WC_Coupon Class available setter and getter methods
Related: Create multiple coupons programmatically in WooCommerce 3+