Send a Birthday Coupon Instead of Birthday Points

The built-in birthday reward adds points to the customer’s balance. If you prefer to give a discount instead, this snippet replaces the birthday points with a 10% coupon: on the customer’s birthday, it creates a single-use coupon and emails the code to the customer. This works in both Points and Rewards for WooCommerce and Loyalty Program for WooCommerce.

The Snippet

Add the snippet to your theme’s functions.php or a code snippets plugin.

add_action('init', function () {
	if (!class_exists('WPGL_Points_Hooks')) {
		return;
	}
	remove_action('wpgens_loyalty_daily_cron', ['WPGL_Points_Hooks', 'process_birthday_points']);
	add_action('wpgens_loyalty_daily_cron', 'wpgl_send_birthday_coupons');
}, 20);

function wpgl_send_birthday_coupons()
{
	global $wpdb;

	$discount_percent = 10;
	$valid_days       = 30;
	$current_year     = current_time('Y');

	$users = $wpdb->get_results($wpdb->prepare(
		"SELECT user_id FROM {$wpdb->usermeta}
		 WHERE meta_key = '_wpgens_loyalty_birthday'
		 AND DATE_FORMAT(meta_value, '%%m-%%d') = %s",
		current_time('m-d')
	));

	foreach ($users as $row) {
		$user_id = (int) $row->user_id;
		$user    = get_userdata($user_id);

		// Once per year, shared with the plugin's own birthday flag.
		if (!$user || get_user_meta($user_id, '_wpgens_loyalty_last_birthday_points', true) === $current_year) {
			continue;
		}

		$coupon = WPGL_Coupon_Service::create_coupon([
			'user_id'              => $user_id,
			'amount'               => $discount_percent,
			'discount_type'        => WPGL_Coupon_Type::PERCENTAGE_DISCOUNT,
			'description'          => 'Birthday reward ' . $current_year,
			'usage_limit'          => 1,
			'usage_limit_per_user' => 1,
			'individual_use'       => false,
			'date_expires'         => gmdate('Y-m-d H:i:s', strtotime('+' . $valid_days . ' days')),
			'prefix'               => 'birthday',
		]);
		if (is_wp_error($coupon)) {
			continue;
		}

		update_user_meta($user_id, '_wpgens_loyalty_last_birthday_points', $current_year);

		// Send the email in the language of the customer's last order (WPML).
		$language = '';
		$orders   = wc_get_orders(['customer_id' => $user_id, 'limit' => 1, 'orderby' => 'date', 'order' => 'DESC']);
		if ($orders) {
			$language = $orders[0]->get_meta('wpml_language');
		}
		$previous_language = apply_filters('wpml_current_language', null);
		if ($language) {
			do_action('wpml_switch_language', $language);
		}

		$heading = __('Happy birthday!', 'wpgl-birthday');
		$message = sprintf(
			/* translators: 1: customer first name, 2: discount percentage, 3: coupon code, 4: number of days */
			__('Hi %1$s,<br><br>Happy birthday from all of us! Here is %2$s%% off your next order with the code <strong>%3$s</strong>. It is valid for %4$d days.', 'wpgl-birthday'),
			esc_html($user->first_name ?: $user->display_name),
			$discount_percent,
			esc_html($coupon->get_code()),
			$valid_days
		);

		$mailer = WC()->mailer();
		$mailer->send($user->user_email, $heading, $mailer->wrap_message($heading, $message));

		if ($language && $previous_language) {
			do_action('wpml_switch_language', $previous_language);
		}
	}
}

How It Works

The snippet runs on the plugin’s daily schedule, the same one that normally awards birthday points. For each customer whose birthday is today, it creates a coupon that is:

  • 10% off ($discount_percent)
  • valid for 30 days ($valid_days)
  • single use and restricted to the customer’s email address

Each customer receives one coupon per year. The coupon appears in WooCommerce → Marketing → Coupons with a code starting with birthday. The email uses your WooCommerce email template, so it matches your other store emails.

Keep the Birthday earning action enabled. It shows the birthday field in My Account → Account details. Its points value is ignored while the snippet is active.

Multilingual Stores

On WPML sites, the email is sent in the language of the customer’s last order. To translate the email texts, scan your theme or code snippets plugin in WPML → Theme and plugins localization, then translate the strings in the wpgl-birthday domain in WPML → String Translation.

To collect the birthday when customers register, see Add the Birthday Field to the Registration Form.

Browse our plugins

Lightweight WooCommerce plugins built for speed. No bloat, no frameworks -- just clean code that works.

View all plugins
Stay in the loop

Get notified when we launch new plugins. No spam, just product updates.