How to Add Referral Tracking System with Laravel

This tutorial was created with Laravel 5.5 on a fresh installation and could be considered outdated.

Referral affiliate tracking seemed like something that would be a pretty common development addition to Laravel, but I did not find much in the way of tutorials to guide me 100% of the way there.

This tutorial will walk you through creating functionality in Laravel that will allow your users to share an affiliate link that will give them credit for new users that register with your site. The principles described here should allow you to extend this tutorial to fit other referral needs.

Many thanks to Andy Brudtkuhl’s guide that brought me 85% of the way there; here is the extra 15%:

1. Setup the DB & Migrations

We’ll need to have at least the base auth scaffolding implemented

php artisan make:auth

Next, let’s generate a new migration that will add a new column to our User table.

php artisan make:migration AddReferredByToUsersTable

In this migration, just add a nullable integer called referred_by. We’ll just be setting the referrer’s user id as the referred_by value for simplicity’s sake.

Schema::table('users', function(Blueprint $table)
{
  $table->integer('referred_by')->nullable();
});

and make sure to drop it nicely

Schema::table('users', function(Blueprint $table)
{
  $table->dropColumn('referred_by');
});

Then, run your migration and check your DB to see that the columns are all set.

php artisan migrate

Protip: Make sure you add referred_by to the $fillable array in the User model (app/User.php), otherwise you’ll see some breakage.

2. Generate Referral Links

Easy peasy, just echo out the current logged-in user’s id appended to your url. The middleware we’ll build can catch it anywhere on the site, so feel free to customize this or build it into a helper function.

Stick this inside a view of your choosing.

@auth //only show for logged in users
  <input type="text" readonly="readonly"
         value="{{ url('/') . '/?ref=' . Auth::user()->id }}">
@endauth

The ?ref value will be what the middleware checks for.

3. Bake Cookies with Middleware

Now let’s create a new cookie if someone visits the referral link. We’ll later use this cookie to update the database during user registration.

For those that aren’t familiar with it, middleware basically runs as a filter for HTTP requests.

This means we can add new middleware that will check to see if we’ve added ?ref to the url and then set a cookie if we don’t have one already.

php artisan make:middleware CheckReferral

After we create our middleware, we need to register it in the kernel (app/Http/Kernel.php). We can specify certain routes or add it to a middleware group, but for this case a simple global registration is sufficient.

Add "\App\Http\Middleware\CheckReferral::class" to the end of the $middleware array.

Now, let’s create that cookie by adding some simple functionality to the new middleware file.

Replace the default handle() functionality with this:

$response = $next($request);

// Check that there is not already a cookie set and that we have 'ref' in the url
if (! $request->hasCookie('referral') && $request->query('ref') ) {
  // Add a cookie to the response that lasts 5 years (in minutes)
  $response->cookie( 'referral', encrypt( $request->query('ref') ), 525600 );
}

return $response;

Protip: By default, Laravel uses encryption in cookies. Use encrypt() to pass values to cookies, otherwise you won’t be able to retrieve them later on. Otherwise, you’ll need to add the cookie name to the $except array in the EncryptCookies (app/Http/Middleware/EncryptCookies.php) middleware.

Now, our registered middleware will check the url for ?ref and create a cookie.

Try it now: Navigate to a the referral url you generated in your view earlier. Then, check your developer tools to see if the cookie has been set. In Chrome, this is currently under the Application tab of the Developer Tools.

4. Assign the Cookie Value During Registration

So, now that our User model can have a referrer_id assigned to it and we have the referral cookie set, let’s finish this up by adding the referral cookie value to the referrer_id during user registration.

Fix up the default create() function in RegisterController (app/Http/Controllers/Auth/RegisterController.php) to look like this:

protected function create(array $data)
{
    $referred_by = Cookie::get('referral');

    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => bcrypt($data['password']),
        'referred_by' => $referred_by,
    ]);
}

If you’re feeling protective, look into validating that $referred_by is a real user id. Remember, this value can be null and by default Cookie::get() will return null if no value is detected.

You’ll need to import the Cookie facade here to use that function.

use Illuminate\Support\Facades\Cookie;

Try it now: After navigating through a valid affiliate url (and confirmed the cookie is set properly), register a new user and confirm that the referrer_id has been set in the database for the new user.

Now what?

Well, that’s all for the sake of this article. Getting into awarding referrals tends to split dramatically from here on out depending on what you’re trying to accomplish.

At the very least, you have a foundation where you at least know who referred who.

Let me know if you have any questions or improvements in the comments below, particularly if you:

  1. Know how to register the Middleware to automatically encrypt cookies without the use of encrypt()
  2. Feel strongly that we should use a hashed user id for referral links.
  3. Got lost anywhere along the way.