Building a referral system with laravel REST API

ยท

3 min read

Recently, I was tasked with building a referral system as a feature in an e-commerce application I was working on. I thought about different scenarios it could be done and even considered some laravel packages that could do the work. But I wanted to make it as simple and less complicated as possible, so I opted for building it from scratch.

Thinking about the fact that I was working on a REST API, the first instance I considered was that a user would have a referral code that can be shared and also another user would be able to input the referral code on registration to denote if he/she was invited by another user. Therefore, a user can be referred by another user and a user can refer many user.

Looking at the relationship between this; we have a One-to-Many relationship. So we edit create_user_table migration file.

$table->string('referral_code')->unique();
$table->unsignedBigInteger('referred_by_id');
$table->foreign('referred_by_id')->references('id')->on('users');

But in some instances, some users might not have a referrer, so we update the table schema to have it as;

 Schema::create('users', function (Blueprint $table) {
          $table->id();
          $table->string('name');    
          $table->string('email')->unique();
          $table->string('phone')->unique()->nullable();            
          $table->string('password');
          $table->string('referral_code')->unique();
          $table->unsignedBigInteger('referred_by_id')- 
          >nullable();
          $table->foreign('referred_by_id')->references('id')- 
          >on('users');
          $table->rememberToken();
          $table->timestamps(); 

});

So we migrate the database and make the following changes changes to the User model.


protected $fillable = [
    'referred_by_id', 'referral_code' 'name', 'email', 'password', 'phone'
];


public function referredBy()
{
    return $this->belongsTo(User::class, 'referred_by_id', 'id');
}


public function referrals()
{
    return $this->hasMany(User::class, 'referred_by_id', 'id');
}

So on registration of a new user, we update our registration controller: I have mine to be AuthController;

class AuthController extends Controller {
  public function register(Request $request)
    {

        $validator = Validator::make(
            $request->all(),
            [
                'name' => ['required', 'string', 'max:255'],
                'email' => 'required|email|unique:users',
                'password' => 'required',

            ],
            $messages = [
                'email.unique' => __('Email already associated 
                 with an account')
            ]
        );

        if ($validator->fails()) {
            return response()->json([
                "message" => $validator->messages(),
            ], 400);
        }
      $referrer = User::where('referral_code', $request- 
      >referral_code)->first();
        try {

            DB::beginTransaction();

            $user = new User();
            $user->username = $request->username;
            $user->email = $request->email;
            $user->phone = $phone;
            $user->password = Hash::make($request->password);
            $user->referral_code = "RF_" . \Str::random(4);
            $user->referred_by_id => $referrer ? $referrer->id 
            : null,
            $user->save();



            DB::commit();
         if ($user->referrer !== null) {
         //perform any logic to gift the referrer or update the               referrer wallet

          }
            //generate tokens
            return $this->authObject($user);

        } catch (\Exception$error) {
            logger("General error", [$error]);
            DB::rollback();
            return response()->json([
                "message" => $error->getMessage(),
            ], 500);
        }
    }
   private function authObject($user)
    {
        $user = User::find($user->id);
        $token = $user->createToken('new_token')- 
       >plainTextToken;

        return response()->json([
            "token" => $token,
            "type" => "Bearer",
            "message" => __("User Registered successful ๐Ÿ˜ƒ"),
        ]);
    }
}

In the above method; we validate the request and create a new user, with an autogenerated referral code of theirs and also update the user with the referrer id if there's any and you can also create any logic to gift the referrer or update their wallet if there is any ๐Ÿ˜ƒ.

ย