Recentemente eu participei em um projeto da empresa júnior InfoAlto na qual precisava de um módulo de pagamentos do tipo assinatura, o cliente tinha preferência por utilizar o PayPal como gatway de pagamento e isso me trouxe algumas dificuldades. Foi o segundo projeto que fiz na qual tive contato com meios de pagamento (realizei um anteriormente que tinha um checkout porém utilizando o pagseguro) e eu não tinha noção de como funcionava os pagamentos recorrentes, além disso, uma documentação um pouco confusa entre versões da API do PayPal e um SDK para PHP desatualizado serviram como dificuldades para eu conseguir seguir com o projeto. Como eu não consegui encontrar muito conteúdo em português que me ensinasse a fazer o que precisava, decidi compartilhar o que consegui aprender. Por isso vou criar um pequeno projeto de venda/aluguel de filmes (algo similar ao youtube movies) e assinatura (como a netflix) e compartilhar com uma série de posts.
Edit: código foi atualizado para a versão 8 do laravel. Isso não implica em nenhuma mudança grave do que foi feito nessa parte
Criando o projeto
O primeiro passo é criar o projeto com o comando laravel new com o nome do projeto, no meu caso vou chamar de laravel_paypal:
laravel new laravel_paypal
Configurando banco de dados
Após o projeto ser criado, vamos configurar o nosso arquivo .env para fazer a conexão com o banco de dados
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nome_banco
DB_USERNAME=nome_usuario
DB_PASSWORD=senha_usuario
Com isso, vamos criar 2 migrations novas para a nossa aplicação, sendo elas: movies e movie_user
Migration movies
A tabela movies vai ser responsável por guardar as informações dos filmes disponíveis na plataforma
php artisan make:migration create_movies_table
O código da função up fica assim:
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->string("title");
$table->string("image");
$table->text("overview");
$table->float("purchase_price")->nullable();
$table->float("rental_price")->nullable();
$table->timestamps();
});
}
- Campo title: é do tipo string (varchar no banco de dados) e guarda o título do filme;
- Campo image: é do tipo string (varchar no banco de dados) e guarda a URI da thumb do filme;
- Campo overview: é do tipo text e guarda o resumo ou sinopse do filme;
- Campo purchase_price: é tipo float e guarda o preço de compra do filme, se ele for nulo o filme não tem a opção de compra disponível;
- Campo rental_price: é do tipo float e guarda o preço de aluguel do filme, se ele for nulo o filme não tem a opção de aluguel disponível.
Migration movie_user
A tabela movie_user vai ser responsável por armazenar o relacionamento entre um usuário e um filme
php artisan make:migration create_movie_user_table
O código da função up fica assim:
public function up()
{
Schema::create('movie_user', function (Blueprint $table) {
$table->id();
$table->bigInteger("user_id");
$table->bigInteger("movie_id");
$table->dateTime("expires_at")->nullable();
$table->dateTime("acquired_in");
});
}
- Campo user_id: é do tipo big int e guarda o ID do usuário;
- Campo movie_id: é do tipo big int e guarda o ID do filme;
- Campo expires_at: é do tipo datetime e guarda a data de expiração do aluguel do filme, se for nulo indica que o usuário fez a compra do filme;
- Campo acquired_in: é tipo datetime e guarda a data que o usuário adquiriu aquele filme, sendo aluguel ou compra.
Migration user
Por padrão o Laravel já disponibiliza uma migration que cria a tabela users, por isso nós não precisamos criar-lá.
Agora que já temos nossas migrations é só rodar com o comando:
php artisan migrate
Criando Models e Seeder
Com as tabelas do banco criado está na hora de criarmos e configurarmos as Models e começar a popular o banco de dados
Model Movie
php artisan make:model Movie
E o código da model fica assim:
class Movie extends Model
{
protected $fillable = [
"title", "image", "overview", "purchase_price", "rental_price"
];
public function users() {
$this->belongsToMany("App\User");
}
}
- No atributo fillable colocamos todos os campos da tabela movies que é permitido inserir e fazer alterações;
- Na função users() criamos um relacionamento N:N com a Model User
Model User
Por padrão a model User já vem na criação do projeto Laravel, por isso a unica alteração que vamos fazer é criar o relacionamento N:N com a Model Movie, adicionando a seguinte função na model:
public function movies() {
$this->belongToMany("App\Movie");
}
Lembrando que por padrão, o Laravel irá utilizar como tabela intermediária para esse relacionamento a tabela que criamos com a migration movie_user
Populando o banco de dados
Para iniciar com a nossa aplicação, vamos popular a tabela movies com alguns filmes, para isso precisamos primeiro criar um seeder com o comando:
php artisan make:seeder MoviesTableSeeder
O código desse seeder fica assim:
<?php
use Illuminate\Database\Seeder;
use App\Movie;
class MoviesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Movie::insert([
[
"title" => "Homem de Ferro",
"image" => "https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Depois de ser mantido em cativeiro em uma caverna afegã, o engenheiro bilionário Tony Stark cria uma armadura única e armada para combater o mal.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "O Incrível Hulk",
"image" => "https://m.media-amazon.com/images/M/MV5BMTUyNzk3MjA1OF5BMl5BanBnXkFtZTcwMTE1Njg2MQ@@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Bruce Banner, um cientista em fuga do governo dos EUA, deve encontrar uma cura para o monstro em que se transforma, sempre que perde a paciência.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Homem de Ferro 2",
"image" => "https://m.media-amazon.com/images/M/MV5BMTM0MDgwNjMyMl5BMl5BanBnXkFtZTcwNTg3NzAzMw@@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Com o mundo agora ciente de sua identidade como Homem de Ferro, Tony Stark deve enfrentar tanto sua saúde em declínio quanto um homem louco e vingativo, ligado ao legado de seu pai.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Thor",
"image" => "https://m.media-amazon.com/images/M/MV5BOGE4NzU1YTAtNzA3Mi00ZTA2LTg2YmYtMDJmMThiMjlkYjg2XkEyXkFqcGdeQXVyNTgzMDMzMTg@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "O poderoso, mas arrogante deus Thor, é expulso de Asgard para viver entre os humanos em Midgard (Terra), onde ele logo se torna um dos seus melhores defensores.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Capitão América: O Primeiro Vingador",
"image" => "https://m.media-amazon.com/images/M/MV5BOGE4NzU1YTAtNzA3Mi00ZTA2LTg2YmYtMDJmMThiMjlkYjg2XkEyXkFqcGdeQXVyNTgzMDMzMTg@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Steve Rogers, um soldado militar rejeitado, se transforma no Capitão América depois de tomar uma dose de um 'soro de super-soldado'. Mas ser Capitão América tem um preço, enquanto ele tenta derrubar um traficante de guerra e uma organização terrorista.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Os Vingadores",
"image" => "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Os heróis mais poderosos da Terra devem se unir e aprender a lutar em equipe, se quiserem impedir que o travesso Loki e seu exército alienígena escravizem a humanidade.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Homem de Ferro 3",
"image" => "https://m.media-amazon.com/images/M/MV5BMjE5MzcyNjk1M15BMl5BanBnXkFtZTcwMjQ4MjcxOQ@@._V1_UY268_CR3,0,182,268_AL_.jpg",
"overview" => "Quando o mundo de Tony Stark é dilacerado por um terrorista formidável chamado Mandarin, ele inicia uma odisseia de reconstrução e retribuição.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Thor: O Mundo Sombrio",
"image" => "https://m.media-amazon.com/images/M/MV5BMTQyNzAwOTUxOF5BMl5BanBnXkFtZTcwMTE0OTc5OQ@@._V1_UY268_CR3,0,182,268_AL_.jpg",
"overview" => "Quando os Elfos Negros tentam mergulhar o universo na escuridão, Thor deve embarcar em uma jornada perigosa e pessoal que o reunirá com a médica Jane Foster.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Capitão América: O Soldado Invernal",
"image" => "https://m.media-amazon.com/images/M/MV5BMzA2NDkwODAwM15BMl5BanBnXkFtZTgwODk5MTgzMTE@._V1_UY268_CR1,0,182,268_AL_.jpg",
"overview" => "Enquanto Steve Rogers luta para abraçar seu papel no mundo moderno, ele se une a um colega dos Vingadores e da S.H.I.E.L.D, a Viúva Negra, para combater uma nova ameaça da história: um assassino conhecido como Soldado Invernal.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Guardiões da Galáxia",
"image" => "https://m.media-amazon.com/images/M/MV5BMTAwMjU5OTgxNjZeQTJeQWpwZ15BbWU4MDUxNDYxODEx._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Um grupo de criminosos intergaláticos deve se unir para parar um guerreiro fanático com planos de limpar o universo.",
"purchase_price" => 12.99,
"rental_price" => 40.99
],
[
"title" => "Vingadores: Era de Ultron",
"image" => "https://m.media-amazon.com/images/M/MV5BMTM4OGJmNWMtOTM4Ni00NTE3LTg3MDItZmQxYjc4N2JhNmUxXkEyXkFqcGdeQXVyNTgzMDMzMTg@._V1_UX182_CR0,0,182,268_AL_.jpg",
"overview" => "Quando Tony Stark e Bruce Banner tentam iniciar um programa de manutenção da paz adormecido chamado Ultron, as coisas saem terrivelmente erradas e cabe aos heróis mais poderosos da Terra impedir que o vilão Ultron decida executar seu plano terrível.",
"purchase_price" => 12.99,
"rental_price" => 40.99
]
]);
}
}
E antes de rodar nosso seeder temos que inserir ele dentro do arquivo DatabaseSeeder.php:
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(MoviesTableSeeder::class);
}
}
Com isso só rodar o seguinte comando que nosso banco estará populado:
php artisan db:seed
Criando a página inicial do sistema
Para criar a página inicial do sistema, vamos utilizar o módulo de login do Laravel. Se você está acostumando com a versão 5 do Laravel pode estranhar um pouco, pois antes bastava executar o comando php artisan make:auth e todo o módulo de login estava pronto. Porém na versão 6 isso começou a mudar, e agora na versão 7 é possível escolher entre 3 tipos de frameworks frontend para fazer a interface de sua aplicação. Como esse tutorial está mais focado em integrar o paypal com o laravel vou utlizar o bootstrap como framework frontend.
Primeiro, temos que instalar o pacote de interfaces do Laravel:
composer require laravel/ui
Após a instalação escolhemos a opção do bootstrap:
php artisan ui bootstrap --auth
Após esse comando, o laravel irá adicionar vários arquivos, como migrations, controllers, views, etc. Como ele cria uma nova migration é bom rodar o php artisan migrate novamente.
Para conseguir utilizar o pacote é necessário ter o npm instalado e executar o seguinte comando:
npm install && npm run dev
Para baixar o node e npm só acessar esse link
Configurando Controller E Views
Nesse inicio só iremos disponibilizar para view home todos os filmes salvos no banco de dados, com isso, o código do HomeController fica assim:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Movie;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$movies = Movie::all();
return view('home', ['movies' => $movies]);
}
}
A view home fica assim:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">Filmes disponíveis</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<div class="row justify-content-around">
@foreach ($movies as $movie)
<div class="card" style="width: 15rem; margin-bottom: 10px;">
<img src="{{ $movie->image }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ $movie->title}}</h5>
<a href="#" class="card-link">Alugar</a>
<a href="#" class="card-link">Comprar</a>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Resultado final da parte 1
Com isso, temos como resultado final dessa primeira parte a seguinte tela:
Referências
https://laravel.com/docs/7.x
https://laravel.com/docs/7.x/migrations
https://laravel.com/docs/7.x/eloquent
https://laravel.com/docs/7.x/eloquent-relationships#many-to-many
https://laravel.com/docs/7.x/seeding
https://laravel.com/docs/7.x/authentication
https://laravel.com/docs/7.x/frontend
https://laravel.com/docs/7.x/controllers
https://laravel.com/docs/7.x/views
Top comments (0)