The referral is going to work like this:
- A user signs up and a code gets auto generated as their referral code which they can give to others
- When a user registers, they're prompted to add a referral code
- 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 referred 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.
#. Creating a laravel referral app
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 the 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);
}
- 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 belongsTothe 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 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>
@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 , 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
In case you want to make the notifcation mail send faster, make sure to check laravel queue