DEV Community

Ogbonna Henry
Ogbonna Henry

Posted on

Laravel referral system using referral code

So i was working on a project and decided... "heyy, why not add a referral system and encourage users to share the application". Searched the web but all solutions weren't what i wanted, I mean referral systems aren't new to me but this is going to be my first time building one with laravel and this is also my going to be my first blog post ๐ŸŽ‰. So lets get to it,

The referral is going to work like this:

  1. A user signs up and a code gets auto generated as their referral code which they can give to others

  2. When a user registers, they're prompted to add a referral code

  3. The user whose referral code was used would be notified that someone registered with their code

We are going to be creating 2 migration tables. The user table and the referral table.
Our eloquent Model should be a case where a user can be refered by another user and a user can refer many users but it's going to be (One to One) while we have a column that adds each time a new user uses an existing user referral code.
First of, we create our laravel application

 laravel new referral-app
Enter fullscreen mode Exit fullscreen mode

After installing laravel, we make the referral model, migration and controller

php artisan make:model Referral -mc
Enter fullscreen mode Exit fullscreen mode

Now we edit our migration table, first the users table ๐Ÿ‘‡

 public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('referral_status')->default('off');
            $table->string('referral_by')->nullable();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
Enter fullscreen mode Exit fullscreen mode

Now we edit the referral table

 public function up(): void
    {
        Schema::create('referrals', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('referral_code')->unique()->nullable();
            $table->integer('total_referred_users')->default(0);
            $table->timestamps();
        });
    }
Enter fullscreen mode Exit fullscreen mode

We are using foreignId cause of our Eloquent relationship with the users table One-To-Many.
Let's not forget our auth ๐Ÿ˜‰

composer require laravel/ui
php artisan ui bootstrap
php artisan ui bootstrap --auth
Enter fullscreen mode Exit fullscreen mode

Let's edit our models, starting with the User Model

protected $fillable = [
        'name',
        'email',
        'password',
        'referral_status',
        'referral_by'
];

public function referral(){
    return $this->hasOne(Referral::class);
}
Enter fullscreen mode Exit fullscreen mode

We did we just do?

  • First we added referral_status and referral_by to the $fillable in the User model

  • Then we specified the eloquent relationship hasOne

On the other hand the Referral model eloquent relationship should belongsTo the User model and we add user_id, referral_code and total_referred_users to the Referral model $fillable

 protected $fillable = [
        'user_id',
        "referral_code",
        "total_referred_users"
    ];


    public function user(){
        return $this->belongsTo(User::class);
    }
Enter fullscreen mode Exit fullscreen mode

Using MySql, we're going to create a database referral_app and link it to through our .env file.

Now we migrate and the add Auth route to our routes/web.php file

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

In the web.php file add this๐Ÿ‘‡

Auth::routes();
Enter fullscreen mode Exit fullscreen mode

Now let's add referral code to every user who signs up but first we need a page for users to enter their referral code after signing up. We would create a new file in our view/auth folder called referral.blade.php and place this code below in it

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Referral') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('referral.verify') }}">
                        @csrf
                        @method('PATCH')

                        <div class="row mb-3">
                            <label for="referral" class="col-md-4 col-form-label text-md-end">{{ __('Referral Code') }}</label>

                            <div class="col-md-6">
                                <input id="referral" type="text" class="form-control @error('referral') is-invalid @enderror" name="referral" value="{{ old('referral') }}" required autocomplete="referral" autofocus>

                                @error('referral')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Proceed') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Enter fullscreen mode Exit fullscreen mode

The form is being submitted to a patch route referral.store which we are going to add the web.php file later on, for now let's add this to the web.php

Route::get('/referral', function(){ return view('auth.referral');})->name('referral');

Enter fullscreen mode Exit fullscreen mode

Now we let's get back to generating a referral code to every user who signs up

Locate the RegisterController in App\Http\Controllers\Auth.
We're going to edit the protected function create(array $data)

Replace the function with this edited version

protected function create(array $data)
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
        Referral::create([
            'user_id'=> $user->id,
            'referral_code'=>Str::random(6),
        ]);

        return $user;

    }
Enter fullscreen mode Exit fullscreen mode

Also in your view/home.blade.php replace the existing code with this

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    <p>Your referral code is {{ auth()->user()->referral->referral_code }}</p>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Enter fullscreen mode Exit fullscreen mode

Now let's add the referral part. First locate App/Providers/RouteServiceProvider and edit

Change from this:

    public const HOME = '/home';
Enter fullscreen mode Exit fullscreen mode

To this:

    public const HOME = '/referral';
Enter fullscreen mode Exit fullscreen mode

Now it's time to add our route referral.store and verify referrals.
In your web.php file, add the patch route for storing the referrals

Route::patch('/referral/store', [App\Http\Controllers\ReferralController::class, 'store'])->name('referral.store');

Enter fullscreen mode Exit fullscreen mode

In the ReferralController add the store function

    public function store(Request $request){
        $user = User::find(Referral::where("referral_code", $request->referral)->first()->user_id);
        $total_referred_users = $user->referral->total_referred_users + 1;
        $user->referral->update(['total_referred_users'=> $total_referred_users]);
        DB::table('users')->where('id', auth()->user()->id)->update(['referral_by' => $request->referral]);
        Notification::route('mail', $user->email)->notify(new UserNotification());
        return redirect()->action([HomeController::class,'index']);
    }
Enter fullscreen mode Exit fullscreen mode

Let me explain the code

  • First we got the user using the referral code that was submitted then we added to it counts of user

  • We then proceeded to update the new user's referral_by column to add a referral code

  • Finally, we send a notification to the user who referred that someone signed up with their referral code

Don't forget to make:notification to generate the email notification

php artisan make:notification UserNotification
Enter fullscreen mode Exit fullscreen mode

Edit the contents and replace with this code

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class UserNotification extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     */
    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
                    ->line("A user just joined ".getenv('APP_NAME')." using your referral code")
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @return array<string, mixed>
     */
    public function toArray(object $notifiable): array
    {
        return [
            //
        ];
    }
}

Enter fullscreen mode Exit fullscreen mode

Our Laravel referral system using referral code is now done, don't forget

php artisan serve
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

You can check the code out on my github.
https://github.com/hen8y/laravel-referral-system
In case you want to make the notifcation mail send faster, make sure to check laravel queue

Follow me on X(Twitter) Twitter

Top comments (0)