DEV Community

Gabriel Maximiniano
Gabriel Maximiniano

Posted on • Edited on

Laravel + PayPal - Parte 1: Criando projeto

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 
Enter fullscreen mode Exit fullscreen mode

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(); }); } 
Enter fullscreen mode Exit fullscreen mode
  • 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"); }); } 
Enter fullscreen mode Exit fullscreen mode
  • 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"); } } 
Enter fullscreen mode Exit fullscreen mode
  • 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"); } 
Enter fullscreen mode Exit fullscreen mode

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 ] ]); } } 
Enter fullscreen mode Exit fullscreen mode

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); } } 
Enter fullscreen mode Exit fullscreen mode

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]); } } 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Resultado final da parte 1

Com isso, temos como resultado final dessa primeira parte a seguinte tela:
Imagem da parte 1!

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)