Laravel Paypal Payment Integration

By | August 26, 2019

Hello Coders, Welcome to CodesCompanion easy way development tutorials. This tutorial is about the PayPal payment method integration in Laravel. Previously I had written about the other payment gateway’s such as Stripe, Instamojo and Razorpay that you can check in my other articles.

Currently let me tell you about the PayPal payment method integration in Laravel.

Step 1 : Create fresh Laravel application

If you know this step than you can skip this step.

Let’s create a fresh Laravel application using following command so first reach at your project directory and than run below command.

composer create-project --prefer-dist laravel/laravel paypal

After the installation it will look like below screenshot if you press “ll” it will list down all the files and folders.

After this just give the permission to directory by run this command.

sudo chmod -R 777 .

Step 2 : Database Setup

After the installation you will find the “.env” file in root directory just open it and write down the database connectivity parameters like below.

Step 3 : Install paypal package

Third party package

Run this command for install paypal package.

composer require paypal/rest-api-sdk-php

After Successfully installation we are login in to paypal and gather some keys like client_id and secret.

Step 4 : Create Account and App in paypal sandbox

Log in to your PayPal developer account something like this https://developer.paypal.com/ , you will see the “Login into Dashboard” click on it and login.

After login open “Sandbox > Accounts”. Create a new account from here.

Click on “Create Account” and fill-up the required fields and complete the process.

After creating an Account click on “My Apps & Credentials” and create an app. Add “App name” and “Buisness Account” and complete the process.

After creating an app you will see the client_id take it and generate secret keys if not available or old. Copy that both and paste it in your .env file

PAYPAL_CLIENT_ID=
PAYPAL_SECRET=
PAYPAL_MODE=sandbox

Step 5 : Create paypal.php

A paypal config file

Now, Let’s create paypal.php file in /config directory. And place the following code in that file.

<?php 
return [ 
    'client_id' => env('PAYPAL_CLIENT_ID',''),
    'secret' => env('PAYPAL_SECRET',''),
    'settings' => array(
        'mode' => env('PAYPAL_MODE','sandbox'),
        'http.ConnectionTimeOut' => 30,
        'log.LogEnabled' => true,
        'log.FileName' => storage_path() . '/logs/paypal.log',
        'log.LogLevel' => 'ERROR'
    ),
];

Step 6 : View File form

For testing purpose I am just adding form in welcome blade file that has created by default while installation and it will look like this now.

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Nunito', sans-serif;
                font-weight: 200;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }

            .links > a {
                color: #636b6f;
                padding: 0 25px;
                font-size: 13px;
                font-weight: 600;
                letter-spacing: .1rem;
                text-decoration: none;
                text-transform: uppercase;
            }

            .m-b-md {
                margin-bottom: 30px;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth
                        <a href="{{ url('/home') }}">Home</a>
                    @else
                        <a href="{{ route('login') }}">Login</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}">Register</a>
                        @endif
                    @endauth
                </div>
            @endif

            <div class="content">
                <div class="title m-b-md">
                    Laravel
                </div>
                @if(session()->has('message'))
                    <div class="alert alert-success" style="color: green;">
                    {{ session()->get('message') }}
                    </div>
                @endif
               <form class="w3-container w3-display-middle w3-card-4 " method="POST" id="payment-form"  action="{{ route('paypal') }}">
              {{ csrf_field() }}
              <h2 class="w3-text-blue">Payment Form</h2>
              <p>      
              <label class="w3-text-blue"><b>Enter Amount</b></label><br/>
              <input class="w3-input w3-border" name="amount" type="text"></p>      
              <button class="w3-btn w3-blue">Pay with PayPal</button></p>
            </form>
            </div>
        </div>
    </body>
</html>

After I refresh the home page it will look like this.

Step 7: Create Controller file

Now, let’s create the controller file by run below command in terminal.

php artisan make:controller PaymentController

This command will create the controller file in “/var/www/html/paypal/app/Http/Controllers” and it will look like this.

Now I will add some action that require for payment it will look like this now.

Below code you can write in your own controller if you have already have controller for payment.

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
/** All Paypal Details class **/
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Rest\ApiContext;
use Redirect;
use Session;
use URL;

class PaymentController extends Controller
{
    private $_api_context;
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        /** PayPal api context **/
        $paypal_conf = \Config::get('paypal');
        $this->_api_context = new ApiContext(new OAuthTokenCredential(
            $paypal_conf['client_id'],
            $paypal_conf['secret'])
        );
        $this->_api_context->setConfig($paypal_conf['settings']);
    }

    public function index()
    {
        return view('paywithpaypal');
    }
    
    public function payWithpaypal(Request $request)
    {
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');
        $item_1 = new Item();
        $item_1->setName('Item 1') /** item name **/
            ->setCurrency('USD')
            ->setQuantity(1)
            ->setPrice($request->get('amount')); /** unit price **/
        $item_list = new ItemList();
        $item_list->setItems(array($item_1));
        $amount = new Amount();
        $amount->setCurrency('USD')
            ->setTotal($request->get('amount')); //This amount should be in multiplication of $item_1's amount and quantity. 
        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription('Your transaction description');
        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(URL::to('status')) /** Specify return URL **/
            ->setCancelUrl(URL::to('status'));
        $payment = new Payment();
        $payment->setIntent('Sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));
        /** dd($payment->create($this->_api_context));exit; **/
        try {
            $payment->create($this->_api_context);
        } catch (\PayPal\Exception\PPConnectionException $ex) {
            if (\Config::get('app.debug')) {
                \Session::put('error', 'Connection timeout');
                return Redirect::to('/');
            } else {
                \Session::put('error', 'Some error occur, sorry for inconvenient');
                return Redirect::to('/');
            }
        }
        foreach ($payment->getLinks() as $link) {
            if ($link->getRel() == 'approval_url') {
                $redirect_url = $link->getHref();
                break;
            }
        }
        /** add payment ID to session **/
        Session::put('paypal_payment_id', $payment->getId());
        if (isset($redirect_url)) {
            /** redirect to paypal **/
            return Redirect::away($redirect_url);
        }
        \Session::put('error', 'Unknown error occurred');
        return Redirect::to('/');
    }

    public function getPaymentStatus()
    {
        /** Get the payment ID before session clear **/
        $payment_id = Session::get('paypal_payment_id');
        /** clear the session payment ID **/
        Session::forget('paypal_payment_id');
        if (empty(Input::get('PayerID')) || empty(Input::get('token'))) {
            \Session::put('error', 'Payment failed');
            return redirect()->back()->with('message', 'IT NOT WORKS!');
        }
        $payment = Payment::get($payment_id, $this->_api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId(Input::get('PayerID'));
        /**Execute the payment **/
        $result = $payment->execute($execution, $this->_api_context);
        if ($result->getState() == 'approved') {
            \Session::put('success', 'Payment success');
            return redirect()->back()->with('message', 'Payment Successfully Received!');
        }
        \Session::put('error', 'Payment failed');
        return redirect()->back()->with('message', 'IT NOT WORKS!');
    }
}

Paypal will return paypal_payment_id, token and PayerID that you can use to store in database for order history and payment status. This three things you will get in getPaymentStatus() action in PaymentController.php

Now, Add this routes in web.php file located at “/var/www/html/paypal/routes/web.php”

// route for processing payment
Route::post('paypal', 'PaymentController@payWithpaypal')->name('paypal');

// route for check status of the payment
Route::get('status', 'PaymentController@getPaymentStatus')->name('status');

After this just run the home page and enter amount and click “Pay with Paypal” your page will redirect to PayPal payment gateway.

Just login and enter the amount and complete the payment process you will redirect to your homepage with success payment message.

This one is the sandbox account of paypal we have used you can make it live while using it in a live mode.

Your PayPal payment method integration in Laravel has done ! Enjoy !!

Below is the GITHUB repository for this integration.

Leave a Reply

Your email address will not be published. Required fields are marked *