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)