A simple referral program awarding points

Warning! This tutorial will not work with myCred 1.4 or higher. If you are using version 1.4 or higher you should instead use the “Points for referrals” hook. This tutorial is for those using myCred 1.3 or lower.

Description

In this tutorial I will show you a very basic referral system where users are awarded points for visitors who use their referral link to visit your website. To avoid multiple entries, we will log the visitors IP address each time points are awarded.

All code snippets are placed in your themes functions.php file.

Requirements

  • myCred 1.2 or higher

A Referral ID

First we need to establish what we would use as a identifier for each user. The simplest solution would be to use their ID, which we know will always be unique or generate a custom token for each user.

So we start of by creating a custom function which will return the current users referral ID:

// Using the Users ID as referral ID
function mycred_get_my_ref_id()
{
	if ( !is_user_logged_in() ) return;
	return get_current_user_id();
}

// Generating a custom token for each user and save it to prevent
// new tokens from being generated each time this function runs
function mycred_get_my_ref_id()
{
	if ( !is_user_logged_in() ) return;

	$user_id = get_current_user_id();
	$ref = get_user_meta( $user_id, 'ref_id', true );
	if ( empty( $ref ) ) {
		$ref = wp_generate_password( 6 );
		update_user_meta( $user_id, 'ref_id', $ref );
	}
	return urlencode( $ref );
}

In the second example we use the wp_generate_password() function to generate a unique 6 character long token. This token is then saved as a user meta under the “ref_id” id.

Show Users Their ID

Next we will need to insert this function somewhere on our website where users can see it. For this tutorial, we will show it to users when they edit their profile in the admin area.

add_action( 'profile_personal_options', 'show_users_referral_id' );
function show_users_referral_id( $user )
{
	$ref_id = mycred_get_my_ref_id(); ?>

<p>Refer users to our website and earn points!</p>
<p>Your referral ID is: <?php echo $ref_id; ?></p>
<?php
}

Alternatively, we can create a custom function to automatically add this referral ID to your blogs home url:

function mycred_get_ref_for_home()
{
	if ( !is_user_logged_in() ) return;
	return add_query_arg( array( 'ref' => mycred_get_my_ref_id() ), home_url() );
}

We can then use this function to show the current user their referral ID attached to your websites home url. Using the above user profile example:

add_action( 'profile_personal_options', 'show_users_referral_id' );
function show_users_referral_id( $user )
{ ?>

<p>Refer users to our website and earn points!</p>
<p><?php echo mycred_get_ref_for_home(); ?></p>
<?php
}

The above code will output:

Refer users to our website and earn points!

Home

While our custom mycred_get_ref_for_home() function will attach the referral ID to our home url, we can create a new function to attach it to a pre-defined URL. You could then use this function anywhere in your theme to show your users the referral ID for any given page/post.

function mycred_get_ref_for_url( $url = '' )
{
	if ( !is_user_logged_in() || empty( $url ) ) return;
	return add_query_arg( array( 'ref' => mycred_get_my_ref_id() ), $url );
}

You could use this function for example for your store products, allowing your users to refer users to specific products and still being able to receive points for the referral.

Detecting Referrals

Now we just need to detect visitors who are arriving though one of these referrals. For this we will need two custom functions. First a function that hooks in to WordPress to do the actual detection and a function that will find which user the referral ID belongs to. This of course is not necessary if you are using your users ID as the referral ID.

Lets start with detecting. We will hook in to WordPress pretty early and check if the “ref” argument is set in the visitors URL. If it is, we will try and find which user it belongs to, make sure our users is not using their own referral IDs to try and get points, check the visitors IP address to make sure we do not award points multiple times and finally remove the ref argument to prevent multiple database queries.

add_action( 'template_redirect', 'mycred_catch_referred_users' );
function mycred_catch_referred_users()
{
	if ( !isset( $_GET['ref'] ) ) return;

	if ( !empty( $_GET['ref'] ) ) {
		$ref_id = urldecode( $_REQUEST['ref'] );
		$user_id = mycred_get_userid_from_ref( $ref_id );
		if ( $user_id === false ) return;
		if ( is_user_logged_in() && get_current_user_id() == $user_id ) return;

		$mycred = mycred_get_settings();
		$IP = $_SERVER['REMOTE_ADDR'];
		if ( empty( $IP ) ) return;
		if ( ! $mycred->has_entry( 'visitor_referring', '', $user_id, $IP ) ) {
			$mycred->add_creds(
				'visitor_referring',
				$user_id,
				1,
				'%plural% for visitor referral',
				'',
				$IP
			);
		}

		wp_redirect( remove_query_arg( 'ref' ) );
		exit;
	}
}

Next we will need to create the mycred_get_userid_from_ref() function which will do the actual database query:

function mycred_get_userid_from_ref( $ref_id = NULL )
{
	if ( $ref_id === NULL ) return false;

	global $wpdb;
	$user_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND meta_value = %s;", 'ref_id', $ref_id ) );
	$wpdb->flush();
	if ( $user_id === NULL ) return false;

	return intval( $user_id );
}

Now all together

All the functions together:

/**
 * Get Current Users Ref ID
 * Returns the current users ref ID.
 * @version 1.0
 */
function mycred_get_my_ref_id()
{
	if ( !is_user_logged_in() ) return;

	$user_id = get_current_user_id();
	$ref = get_user_meta( $user_id, 'ref_id', true );
	if ( empty( $ref ) ) {
		$ref = wp_generate_password( 6 );
		update_user_meta( $user_id, 'ref_id', $ref );
	}
	return urlencode( $ref );
}

/**
 * Add Ref ID to Home URL
 * Appends the current users refid to the sites home url.
 * @version 1.0
 */
function mycred_get_ref_for_home()
{
	if ( !is_user_logged_in() ) return;
	return add_query_arg( array( 'ref' => mycred_get_my_ref_id() ), home_url() );
}

/**
 * Add Ref ID to URL
 * Appends the current users refid to a given url.
 * @version 1.0
 */
function mycred_get_ref_for_url( $url = '' )
{
	if ( !is_user_logged_in() || empty( $url ) ) return;
	return add_query_arg( array( 'ref' => mycred_get_my_ref_id() ), $url );
}

/**
 * Insert Users Ref ID
 * Inserts the current users referral ID in the profile edit page.
 * @version 1.0
 */
add_action( 'profile_personal_options', 'show_users_referral_id' );
function show_users_referral_id( $user )
{ ?>

<p>Refer users to our website and earn points!</p>
<p><?php echo mycred_get_ref_for_home(); ?></p>
<?php
}

/**
 * Get User ID from Ref ID
 * Returns the user id of a given referral id.
 * @version 1.0
 */
function mycred_get_userid_from_ref( $ref_id = NULL )
{
	if ( $ref_id === NULL ) return false;

	global $wpdb;
	$user_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND meta_value = %s;", 'ref_id', $ref_id ) );
	$wpdb->flush();
	if ( $user_id === NULL ) return false;

	return intval( $user_id );
}

/**
 * Detect Referrer
 * Checks if user has been referred, awards points if it is
 * a unique IP and removed the ref query argument.
 * @version 1.0
 */
add_action( 'template_redirect', 'mycred_catch_referred_users' );
function mycred_catch_referred_users()
{
	if ( !isset( $_GET['ref'] ) ) return;

	if ( !empty( $_GET['ref'] ) ) {
		$ref_id = urldecode( $_GET['ref'] );
		$user_id = mycred_get_userid_from_ref( $ref_id );
		if ( $user_id !== false ) return;
		if ( is_user_logged_in() && get_current_user_id() == $user_id ) return;

		$mycred = mycred_get_settings();
		$IP = $_SERVER['REMOTE_ADDR'];
		if ( empty( $IP ) ) return;
		if ( ! $mycred->has_entry( 'visitor_referring', '', $user_id, $IP ) ) {
			$mycred->add_creds(
				'visitor_referring',
				$user_id,
				1,
				'%plural% for visitor referral',
				'',
				$IP
			);
		}
		wp_redirect( remove_query_arg( 'ref' ) );
		exit;
	}
}

Note If you are using this code in your localhost server, your IP might be an empty string, in which case you will be awarded points each time you use the referral id!

Done

Thats it. As promised this is a very simple referral system that awards 1 point for each unique visitor that visits our website using a referral link. If you have any questions please feel free to comment below.

Update

Several users has requested information on how to modify this tutorial and add points when users signup using this referral system. To accomplish this, we need to do two things. First we will need to adjust the detection script to set a cookie for the current user and hook into WordPress registrations where we check for this cookie and award points for successful signups.

Lets start with the detection script.

/**
 * Detect Referrer
 * Checks if user has been referred, awards points if it is
 * a unique IP and removed the ref query argument.
 * @version 1.0
 */
add_action( 'template_redirect', 'mycred_catch_referred_users' );
function mycred_catch_referred_users()
{
	if ( !isset( $_GET['ref'] ) ) return;

	if ( !empty( $_GET['ref'] ) ) {
		$ref_id = urldecode( $_GET['ref'] );
		$user_id = mycred_get_userid_from_ref( $ref_id );
		if ( $user_id === false ) return;
		if ( is_user_logged_in() && get_current_user_id() == $user_id ) return;

		$mycred = mycred_get_settings();
		$IP = $_SERVER['REMOTE_ADDR'];
		if ( empty( $IP ) ) return;
		if ( !$mycred->has_entry( 'visitor_referring', '', $user_id, $IP ) ) {
			$mycred->add_creds(
				'visitor_referring',
				$user_id,
				1,
				'%plural% for visitor referral',
				'',
				$IP
			);
		}
		// Set a cookie in case user signs up
		setcookie( 'signup_ref', $ref_id, time()+3600*24 );
		wp_redirect( remove_query_arg( 'ref' ) );
		exit;
	}
}

We give the user a new cookie called “signup_ref” which will be valid for one day. For more information on how setcookie work, please consult the PHP documentation.

Next we hook into user_register which fires when a new user has signed up on our website:

add_action( 'user_register', 'check_for_referral_at_signup' );
function check_for_referral_at_signup( $user_id )
{
	// Check for cookie
	if ( isset( $_COOKIE['signup_ref'] ) ) {
		// Get the referrers ID
		$ref_user_id = mycred_get_userid_from_ref( $_COOKIE['signup_ref'] );

		// Make sure ref_id is valid, if not delete the cookie to avoid further checks
		if ( $ref_user_id === false ) {
			setcookie( 'signup_ref', $_COOKIE['signup_ref'], time()-3600 );
			return;
		}

		// Load myCred
		$mycred = mycred_get_settings();

		// Make sure this is unique
		if ( !$mycred->has_entry( 'signup_referral', $user_id, $ref_user_id ) ) {
			$mycred->add_creds(
				'signup_referral',
				$ref_user_id,
				1,
				'%plural% for signup referral',
				$user_id,
				array( 'ref_type' => 'user' )
			);
		}

		// Remove Cookie by setting the expiration date in the past
		setcookie( 'signup_ref', $ref_id, time()-3600 );
	}
}

As you can see it is pretty straight forward. You would need to add your own log entry template and points amount and as you can see, I have added support for User related template tags in case you want to show the new users name etc.

Important There is one important thing to remember! The above example relies on the user_register action to fire. In case you use a plugin which customizes or adjusts your signup process, you will need to make sure that this plugin fires this action. If it does not, then no points will be awarded! In these cases you would need to check if your plugin offers some other action or filter you could use instead.

11