Laravel referral system using referral code
Tags: laravel, webdev, tutorial, beginners
Published: 2023-10-14 02:03:23

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
```
After installing laravel, we make the referral model, migration and controller

```
php artisan make:model Referral -mc
```
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();
        });
    }
```
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();
        });
    }
```
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
```
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);
}
```

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);
    }
```

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
```

In the web.php file add this👇

```
Auth::routes();
```

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

```
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');

```
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;

    }
```

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

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

Change from this:

```
    public const HOME = '/home';
```
To this:

```
    public const HOME = '/referral';
```

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');

```
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']);
    }
```
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
```
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 [
            //
        ];
    }
}

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

```
php artisan serve
npm install
npm run dev
```
You can check the code out on my github.
[https://github.com/hen8y/laravel-referral-system](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](https://x.com/hen8y)