In this post, we learn Paypal payment gateway integration in Laravel step by step, Paypal Is a world-famous payment gateway and this is too easy with Laravel.
For this tutorial, we use omnipay/paypal package to payment integration in Laravel 5.7 we start with a fresh Laravel project so we need to create a new Laravel Project. To create a fresh project use this command.
We are going to integrate PayPal Express Checkout in this article below.
Step:1 Create a new Project
laravel new paypal
Step:2 install the package omnipayvia the composer.
composer require league/omnipay omnipay/paypal
And generate the default layout of Laravel using the flowing command.
php artisan make:auth
Step: 3 Create some routes
Now add new routes for the PayPal integration under app/routes/web.php
Route::get('/paypal/{order?}','PayPalController@form')->name('order.paypal');
Route::post('/checkout/payment/{order}/paypal','PayPalController@checkout')->name('checkout.payment.paypal');
Route::get('/paypal/checkout/{order}/completed','PayPalController@completed')->name('paypal.checkout.completed');
Route::get('/paypal/checkout/{order}/cancelled','PayPalController@cancelled')->name('paypal.checkout.cancelled');
Route::post('/webhook/paypal/{order?}/{env?}','PayPalController@webhook')->name('webhook.paypal.ipn');
Route::get('payment-completed/{order}','PayPalController@paymentCompleted')->name('paymentCompleted');
Step: 4 Create Order table.
Create a migration, modal, and Controller for an order using this command.
php artisan make:model Order -mcr
Adding the required models for this implementation.
app/Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
const PAYMENT_COMPLETED = 1;
const PAYMENT_PENDING = 0;
/**
* @var string
*/
protected $table = 'orders';
/**
* @var array
*/
protected $dates = ['deleted_at'];
/**
* @var array
*/
protected $fillable = ['transaction_id', 'amount', 'payment_status'];
}
Step: 5 Update migration table
We already generated a new migration table for order, now add some columns.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTableOrders extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('service_id');
$table->string('transaction_id')->nullable();
$table->float('amount')->unsigned()->nullable();
$table->integer('payment_status')->unsigned()->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('orders');
}
}
Step:8 Create new Migration table Service
Using this flowing command.
php artisan make:model Service -mcr
Now, add some columns in Service table.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateServicesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('services', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('amount');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('services');
}
}
then use this flowing command to migrate this service table.
php artisan migrate
Add some dummy data into the Service table.

Step: 7 Add helper
Adding a new helper class for generating gateway object and routes to interact with PayPal API.
app/PayPal.php
<?php
namespace App;
use Omnipay\Omnipay;
/**
* Class PayPal
* @package App
*/
class PayPal
{
/**
* @return mixed
*/
public function gateway()
{
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername(config('services.paypal.username'));
$gateway->setPassword(config('services.paypal.password'));
$gateway->setSignature(config('services.paypal.signature'));
$gateway->setTestMode(config('services.paypal.sandbox'));
return $gateway;
}
/**
* @param array $parameters
* @return mixed
*/
public function purchase(array $parameters)
{
$response = $this->gateway()
->purchase($parameters)
->send();
return $response;
}
/**
* @param array $parameters
*/
public function complete(array $parameters)
{
$response = $this->gateway()
->completePurchase($parameters)
->send();
return $response;
}
/**
* @param $amount
*/
public function formatAmount($amount)
{
return number_format($amount, 2, '.', '');
}
/**
* @param $order
*/
public function getCancelUrl($order)
{
return route('paypal.checkout.cancelled', $order->id);
}
/**
* @param $order
*/
public function getReturnUrl($order)
{
return route('paypal.checkout.completed', $order->id);
}
/**
* @param $order
*/
public function getNotifyUrl($order)
{
$env = config('services.paypal.sandbox') ? "sandbox" : "live";
return route('webhook.paypal.ipn', [$order->id, $env]);
}
}
Step: 7 updates config/service.php
Laravel comes with a config file config/service.php to be used with third-party API services. For this implementation add following credentials under the same file as below.
'paypal' => [
'username' => env('PAYPAL_USERNAME'),
'password' => env('PAYPAL_PASSWORD'),
'signature' => env('PAYPAL_SIGNATURE'),
'sandbox' => env('PAYPAL_SANDBOX'),
],
Step:8 Create a new controller
To create a new controller use this flowing command.
php artisan make:controller PayPalController
To handle and maintain the request coming into the application we need to pass information to the controller. We are update PayPalController.php
<?php
namespace App\Http\Controllers;
use App\Order;
use App\PayPal;
use App\Service;
use App\User;
use Illuminate\Http\Request;
/**
* Class PayPalController
* @package App\Http\Controllers
*/
class PayPalController extends Controller
{
public function form(Request $request, $service_id)
{
$service = Service::findOrFail($service_id);
$order = new Order;
$transaction_id = rand(10000000,99999999);
$order->user_id = 1 ; //user id
$order->transaction_id = $transaction_id;
$order->service_id = $service->id;
$order->amount = $service->amount;
$order->save();
// the above order is just for example.
return view('form', compact('service','transaction_id'));
}
/**
* @param $order_id
* @param Request $request
*/
public function checkout($transaction_id, Request $request)
{
$order = Order::where('transaction_id', decrypt($transaction_id))->first();
$paypal = new PayPal;
$response = $paypal->purchase([
'amount' => $paypal->formatAmount($order->amount),
'transactionId' => $order->transaction_id,
'currency' => 'USD',
'cancelUrl' => $paypal->getCancelUrl($order),
'returnUrl' => $paypal->getReturnUrl($order),
]);
if ($response->isRedirect()) {
$response->redirect();
}
return redirect()->back()->with([
'message' => $response->getMessage(),
]);
}
/**
* @param $order_id
* @param Request $request
* @return mixed
*/
public function completed($order_id, Request $request)
{
$order = Order::findOrFail($order_id);
$paypal = new PayPal;
$response = $paypal->complete([
'amount' => $paypal->formatAmount($order->amount),
'transactionId' => $order->transaction_id,
'currency' => 'USD',
'cancelUrl' => $paypal->getCancelUrl($order),
'returnUrl' => $paypal->getReturnUrl($order),
'notifyUrl' => $paypal->getNotifyUrl($order),
]);
if ($response->isSuccessful()) {
$order->update([
'transaction_id' => $response->getTransactionReference(),
'payment_status' => Order::PAYMENT_COMPLETED,
]);
return redirect()->route('paymentCompleted', encrypt($order_id))->with([
'message' => 'You recent payment is sucessful with reference code ' . $response->getTransactionReference(),
]);
}
return redirect()->back()->with([
'message' => $response->getMessage(),
]);
}
public function paymentCompleted($order)
{
# code...
return "Thanks! payment completed";
}
/**
* @param $order_id
*/
public function cancelled($order_id)
{
$order = Order::findOrFail($order_id);
return redirect()->route('order.paypal', encrypt($order_id))->with([
'message' => 'You have cancelled your recent PayPal payment !',
]);
}
/**
* @param $order_id
* @param $env
* @param Request $request
*/
public function webhook($order_id, $env, Request $request)
{
// to do with new release of sudiptpa/paypal-ipn v3.0 (under development)
}
}
Step:9 Create the view
Here we create two views one for send amount to Paypal and one for land after payment
form.blade.php
@extends('layouts.app')
@section('content')
<div >
<div >
<div >
@if(session()->has('message'))
<p >
{{ session('message') }}
</p>
@endif
<div >
<div >
<img src="{{ asset('images/paypal.png') }}" >
</div>
<div >
<img src="{{ asset('images/laravel.png') }}" >
</div>
</div>
<p><strong>Order Overview !</strong></p>
<hr>
<p>Item : Yearly Subscription cost !</p>
<p>Amount : ${{ $service->amount }}</p>
<hr>
</div>
<div >
<form method="POST" action="{{ route('checkout.payment.paypal', ['transaction_id' => encrypt($transaction_id)]) }}">
{{ csrf_field() }}
<button >
<i aria-hidden="true"></i> Pay with PayPal
</button>
</form>
</div>
</div>
</div>
@stop
Ok, Now We almost have done.
Step:10 Update .env file with PayPal credential details.
PAYPAL_USERNAME = your_user_mail
PAYPAL_PASSWORD = your_password
PAYPAL_SIGNATURE = your_signature
PAYPAL_SANDBOX = sandbox
Now, everything is ok, now visit this URL //localhost:8000/paypal/1 Here 1 is service in which you want to buy.

Here we store some record of failed and success payment payment_status = 1 show success payment and 0 show failed.
So here we complete tutorials Paypal payment gateway integration in Laravel 5.7 step by step

Brijpal Sharma is a web developer with a passion for writing tech tutorials. Learn JavaScript and other web development technology.