Espera un momento ...
¿Te gustaría llevar mi curso de Laravel, gratis?
Sólo debes ingresar tus datos:
Hoy veremos cómo definir un Sistema de Referidos en Laravel.
Las características que vamos a implementar son:
Se dice que una aplicación incluye un sistema de referidos cuando sus usuarios pueden invitar a otros.
¿Por qué un usuario se tomaría la molestia de invitar a otros?
Generalmente se otorgan recompensas por cada registro conseguido, o por cada acción que realizan los usuarios que han sido referidos.
Por ejemplo:
En realidad, hay muchas formas de recompensar a un usuario que invita a otros a unirse.
Inclusive:
En nuestro ejemplo de hoy vamos a establecer las bases para un sistema de referidos.
Los beneficios a otorgar a los usuarios es un tema que podrás implementar tú, dependiendo de las necesidades de tu aplicación o proyecto.
Y si necesitas ayuda, recuerda que el servicio de asesoría podría ser conveniente para ti.
Esta es una captura del proyecto en el cual estoy trabajando:
Para mantener la identidad del sitio a salvo reemplacé el dominio.
Pero la idea es esa:
Brindar a los usuarios una URL que les permita obtener referidos.
A esta URL también se le conoce como "URL de afiliados".
Entonces nuestro primer paso será definir una ruta que respete dicho formato.
Eso lo logramos con esta línea:
Route::get('/r/{referralCode}', 'ReferralController@link')->name('referral.link');
Nota:
referralCode
una alternativa es tener un parámetro GET ref
que active la lógica.ReferralMiddleware
. En esta ocasión vamos a mantener las cosas simples.
Recuerda que esta es la base y que puedes continuar agregando características según tus necesidades.
La idea es que cada usuario tenga su propio código para captar referidos.
Para esto puedes ir al modelo User
y definir un método estático que genere un código aleatorio (de 7 caracteres en este caso).
El do while
nos permite seguir generando códigos en caso que el resultado ya se encuentre en uso:
public static function getUniqueReferralCode()
{
do {
$code = Str::random(7);
} while (User::where('referral_code', $code)->exists());
return $code;
}
Para generar la cadena aleatoria estamos usando el método random
de la clase Str
de Laravel.
Y en esta ocasión estamos considerando una columna referral_code
en nuestra tabla users
. No olvides de agregar esta columna en tus migraciones.
Si estás usando el sistema de autenticación que incorpora Laravel, entonces en tu RegisterController
vas a tener algo similar a lo siguiente:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'role' => $data['role'],
'referral_code' => User::getUniqueReferralCode()
]);
}
Y no te preocupes por caracteres extraños:
El método random
asigna un número o una letra, que puede estar en mayúsculas o minúsculas.
En mi caso tengo unas clases Factory
y Seeder
asociadas al modelo User
, por lo que he generado fácilmente miles de registros para confirmar ello:
Tampoco debes preocuparte de que no hayan códigos únicos suficientes para todos los usuarios.
58x58x58
códigos únicos. Es decir, se tiene abasto para 195mil 112 usuarios.Imagina el siguiente escenario:
Lo más justo es que seas referido del primer usuario que te invitó.
Incluso si no te registras el mismo día, pero lo haces durante los próximos 7 días, sería conveniente que el sistema te considere como referido por la persona que te invitó inicialmente.
Y si no te registras en 7 días y lo haces después de mucho tiempo:
referred_by
(referido por) quedaría vacío.Éstas son las reglas a considerar para el proyecto que estoy desarrollando.
Tú puedes guiarte del ejemplo que estamos viendo e implementar tu sistema de referidos con las reglas que consideres más convenientes.
En mi tabla users
tengo definidos los siguientes campos:
$table->string('referral_code', 7)->unique();
$table->unsignedBigInteger('referred_by')->nullable();
$table->foreign('referred_by')->references('id')->on('users');
Teniendo lista nuestra base de datos, es hora de escribir la lógica para la captación de referidos.
Empezamos creando nuestro controlador:
php artisan make:controller ReferralController
Y luego el método que atenderá las visitas a las URLs de invitación:
public function link(Request $request, $referralCode)
{
if (!$request->hasCookie('referral')) {
$cookie = cookie('referral', $referralCode, 60 * 24 * 7);
return redirect('/')->withCookie($cookie);
}
return redirect('/');
}
Este método indica que:
El helper cookie
recibe 3 parámetros, en este orden: el nombre de la cookie, el valor que tendrá la cookie, y la duración en minutos.
¿O debería decir "comiendo la galletita"?
A lo que voy es que, si ya tenemos una Cookie con el "referral_code" del usuario que hizo la invitación, lo siguiente es:
Leer el valor de la Cookie durante el registro.
En nuestro método create
de RegisterController
ahora vamos a tener:
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'role' => $data['role'],
'referral_code' => User::getUniqueReferralCode(),
'referred_by' => $this->getReferredBy()
]);
Como ves, he definido un método getReferredBy
:
private function getReferredBy()
{
$referralCode = Cookie::get('referral');
if ($referralCode)
return User::where('referral_code', $referralCode)->value('id');
return null;
}
De esta forma:
$referralCode
, devolvemos el id del usuario que hizo la invitación.null
.Por cierto:
Para que esto funcione no olvides indicar en tu modelo User
que ambas columnas son $fillable
:
protected $fillable = [
'name', 'email', 'password', 'phone', 'avatar', 'role',
'referred_by', 'referral_code' // <--
];
Todo bien hasta aquí pero, ¿realmente funciona?
Tanto como tú, yo espero que funcione a la primera.
Para estar seguros, empecemos mostrando a cada usuario su URL de referidos.
Para esto, en tu vista blade simplemente puedes imprimir esta expresión:
route('referral.link', ['referralCode' => auth()->user()->referral_code])
Ahora voy a darle click.
Y efectivamente, he sido redirigido a la página de inicio del proyecto.
¿Cómo sabemos si la Cookie se creó correctamente?
Si usas Chrome, una primera forma es ir a DevTools y dar clic a la pestaña Application. Debajo de Storage encontraremos Cookies.
Allí puedes verificar también cuándo caduca la Cookie:
El valor de la Cookie se encuentra encriptado. Esto lo hace Laravel.
Si gustas puedes deshabilitar la encriptación para la ruta que usamos.
Pero realmente no es necesario, porque Laravel sí puede leer el valor de la Cookie.
Si no me crees, simplemente define una ruta /cookie
que imprima el valor de la Cookie llamada referral
:
Route::get('/cookie', function () {
return Cookie::get('referral');
});
Y mira que funciona muy bien:
Ahora sí la prueba de fuego ?.
Vamos a registrar un usuario nuevo ...
Y unos segundos después:
Ya tenemos nuestro usuario registrado como referido.
Tenemos una clave foránea en la tabla de users
que hace referencia a la misma tabla.
Es interesante.
Pero la cosa no queda allí. También es posible definir relaciones de un modelo consigo mismo.
De hecho es un tema que ya he tratado anteriormente en el canal. Si te interesa, puedes ver el video haciendo clic aquí.
Para nuestro caso vamos a tener 2 métodos:
public function referredBy()
{
return $this->belongsTo(User::class, 'referred_by');
}
public function referrals()
{
return $this->hasMany(User::class, 'referred_by');
}
Entonces, si tenemos un usuario $u
:
$u->referredBy
podemos acceder al usuario que lo ha referido.$u->referrals
podemos acceder a la lista de usuarios referidos por $u
.De hecho acabo de comprobar que esto funcione bien a través de php artisan tinker
.
Te invito a hacer lo mismo.
Copiar un texto es muy sencillo. Sobretodo si se encuentra dentro de una caja de texto.
Basta con seleccionar el contenido con doble clic y luego presionar Ctrl + V
.
Sin embargo, si deseas facilitar aún más la vida a tus usuarios, puedes agregar un botón "Copiar":
Para esto simplemente define un id
para el input
y define un evento onclick
sobre el botón.
Si usas Bootstrap, tu vista se verá muy similar a la siguiente:
<div class="input-group">
<input type="text" class="form-control" id="referralLink" readonly value="{{ $referralLink }}">
<div class="input-group-append">
<button class="btn btn-sm btn-primary" onclick="copyReferralLink()">
<i class="fa fa-copy"></i> Copy
</button>
</div>
</div>
Cuando el usuario presione el botón, se llamará a la función copyReferralLink
:
function copyReferralLink() {
var input = document.getElementById("referralLink");
// Select the input
input.select();
// For mobile devices
input.setSelectionRange(0, 99999);
// Copy the text inside the input
document.execCommand("copy");
// Confirmed copied text
alert("Your referral link has been copied: " + input.value);
}
Con este código:
copy
.Puedes continuar adaptándolo a tus necesidades ?
Como ves, definir un sistema de referidos no es nada del otro mundo.
Si por algún motivo no te ha funcionado a la primera, recuerda que puedes eliminar las Cookies de tu navegador mientras haces pruebas.
Incluso puedes borrar Cookies con código Laravel (usando el método forget
).
Si tienes alguna dificultad puedes dejar un comentario aquí debajo. O si necesitas ayuda más directa puedes solicitar asesoría.
Comparte este post si te fue de ayuda 🙂.
Regístrate
Accede a todos los cursos, y resuelve todas tus dudas.
Cursos Recomendados
Aprende Laravel desde cero y desarrolla aplicaciones web reales, en tiempo récord, de la mano de Laravel.
Iniciar cursoActualiza tus proyectos desde cualquier versión hasta la última versión estable de Laravel.
Iniciar cursoDesarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho más.
Iniciar cursoEspera un momento ...
¿Te gustaría llevar mi curso de Laravel, gratis?
Sólo debes ingresar tus datos: