By default, every time a referral order is completed the advocate (the referrer) receives a brand new reward coupon. Some stores prefer the opposite behavior: keep a single coupon per advocate and simply increase its amount with every successful referral, so the customer always redeems the same growing coupon. This guide provides a code snippet that does exactly that, and explains an important limitation around percentage based coupons.
Before you start
This is a custom code snippet, not a built in setting. Add it through a child theme functions.php file or, recommended, a small mu-plugin. Always test on a staging site first.
The snippet
/**
* Refer a Friend, stack the advocate reward onto ONE coupon
* instead of issuing a new coupon every time a referral completes.
*/
add_action( 'gens_before_generate_user_coupon', function ( $user_id, $type, $order ) {
// Only the advocate (referrer) reward. Leave friend/registration coupons alone.
if ( 'referrer' !== $type || ! $order ) {
return;
}
$prefix = 'gens_raf';
$discount_type = get_option( $prefix . '_coupon_type' );
$amount = get_option( $prefix . '_coupon_amount' );
// "Percent of order total" is converted to a real currency amount per order,
// exactly like the plugin does, so it CAN be stacked safely.
if ( 'order_percent' === $discount_type ) {
$order_total = $order->get_total() - $order->get_total_tax();
if ( get_option( 'gens_raf_subscription_exclude_shipping' ) ) {
$order_total -= $order->get_total_shipping();
}
$discount_type = 'fixed_cart';
$amount = number_format( $order_total * ( $amount / 100 ), 2, '.', '' );
}
$amount = apply_filters( $prefix . '_coupon_amount', $amount, $order->get_id() );
// Only stack fixed-amount coupons. Stacking a straight percentage (10% + 10%)
// is meaningless and unbounded, so for those we just let a normal new coupon be made.
if ( 'fixed_cart' !== $discount_type && 'fixed_product' !== $discount_type ) {
return;
}
// Resolve the advocate email the same way the plugin does.
$email = '';
if ( is_string( $user_id ) && strpos( $user_id, 'ref' ) === 0 ) {
$db = new WPGens_RAF_DB();
$guest = $db->get_guest_referral_by_code( $user_id );
if ( $guest ) {
$email = $guest['email'];
} elseif ( $numeric = WPGens_RAF_User::get_id_from_referral_code( $user_id ) ) {
$u = get_userdata( $numeric );
$email = $u ? $u->user_email : '';
}
} elseif ( is_email( $user_id ) ) {
$email = $user_id;
} elseif ( $u = get_userdata( $user_id ) ) {
$email = $u->user_email;
}
if ( ! $email ) {
return;
}
// Find this advocate existing (oldest) RAF coupon of the same type.
$existing = get_posts( array(
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'numberposts' => -1,
'orderby' => 'date',
'order' => 'ASC',
'meta_query' => array(
array( 'key' => 'customer_email', 'value' => strtolower( $email ) ),
array( 'key' => 'discount_type', 'value' => $discount_type ),
),
) );
$master = null;
foreach ( $existing as $c ) {
if ( strpos( $c->post_title, 'RAF-' ) !== 0 ) {
continue; // only our referral coupons
}
$used = (int) get_post_meta( $c->ID, 'usage_count', true );
$limit = (int) get_post_meta( $c->ID, 'usage_limit', true );
if ( $limit && $used >= $limit ) {
continue; // already redeemed, do not top up a used coupon
}
$master = $c;
break;
}
// No existing unused coupon, let the plugin create one normally (first reward).
if ( ! $master ) {
return;
}
// Top up the existing coupon.
$current = (float) get_post_meta( $master->ID, 'coupon_amount', true );
update_post_meta( $master->ID, 'coupon_amount', $current + (float) $amount );
// Prevent a NEW coupon from being created for this generation only
// (self-removing so the friend coupon in the same request is unaffected).
$one_shot = function () use ( &$one_shot ) {
remove_filter( 'gens_raf_generate_coupon', $one_shot );
return false;
};
add_filter( 'gens_raf_generate_coupon', $one_shot );
}, 10, 3 );
How it works
- It hooks into
gens_before_generate_user_coupon, which runs right before the plugin builds the reward coupon, and it acts only on the advocate (referrer) reward. Friend and registration coupons keep their normal behavior. - If the advocate already has an unused
RAF-coupon, the snippet adds the current order reward to that coupon amount and cancels creation of a new one through thegens_raf_generate_couponfilter. The filter removes itself, so the friend coupon generated later in the same request is not affected. - The growing total appears automatically under My Account, Refer a Friend, because that list reads the coupon amount live.
Important: percentage coupons
Whether a reward can be stacked depends on the coupon type you use.
| Coupon type | Stacked? | Why |
|---|---|---|
| Fixed cart / Fixed product | Yes | Real currency amounts add up cleanly, for example 5 plus 8 equals 13. |
| Percent of order total (order_percent) | Yes | The plugin already converts this into a fixed amount per order before saving, so each reward contributes a real currency value. |
| Plain percentage (percent, recurring_percent, and similar) | No | Adding 10% plus 10% to reach 20% is unbounded and rarely intended. For these types the snippet keeps the default behavior and a separate new coupon is issued. |
A note about emails
When the snippet tops up an existing coupon, the plugin does not send a reward email for that top up, and the order _raf_coupon_generated flag is not set. The advocate sees the increased balance in their My Account tab. A reward email is still sent the first time the coupon is created. If you also want a notification on every top up, that requires a few extra lines, so reach out to support.
Will this work with percentage coupons?
Yes for the Percent of order total type, because the plugin converts it to a real currency amount per order before saving. It does not stack plain percentage coupons, since adding 10% to 10% is unbounded and rarely intended. For plain percentage coupons a new separate coupon is issued as usual.
Does it affect the friend (referred customer) coupon?
No. The snippet only acts on the advocate (referrer) reward. Friend and registration coupons keep their normal behavior because the filter that blocks new coupon creation removes itself immediately.
Where does the customer see the growing amount?
In their account under My Account, Refer a Friend. That coupon list reads the coupon amount live, so the new total appears automatically after each successful referral.