PayPal Payment Gateway Integration in Laravel

Recently I published an article on PayPal Payment Gateway Integration in PHP. In that article, one of our readers asked about integrating the PayPal payment gateway in Laravel. Though Laravel is built using PHP, they have their own standards to follow. You have to adjust your plain PHP code as per Laravel flow. In this article, I show you how to accept payment on your Laravel website using PayPal Rest API.

PayPal is one of the most trusted brands to accept online payment. PayPal provides different ways to integrate its payment system in web applications. One of the services is PayPal Rest API which we will use for this tutorial. For getting started, you first need to grab your client id and client secret.

Head over to your PayPal developer account and login into it. In the developer dashboard, click on the ‘My Apps & Credentials’ menu. Then click on the ‘Create App’ button under the REST API apps section.

Create PayPal REST API APP

Follow the steps as prompted and you will get your sandbox and live credentials. For now, copy the client id and client secret of sandbox mode.

PayPal REST API app Sandbox Client Id and Client Secret

Basic Setup in Laravel to Accept Payment using PayPal

When customers make the payment on your website you need to store the payment details for later use. Create a ‘payments’ table in the database to store the payment details. Create a migration for the ‘payments’ table using the command:

php artisan make:migration create_payments_table

Open the migration file and modify the columns as follows.

<?php
...
...
public function up()
{
    Schema::create('payments', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('payment_id');
        $table->string('payer_id');
        $table->string('payer_email');
        $table->float('amount', 10, 2);
        $table->string('currency');
        $table->string('payment_status');
        $table->timestamps();
    });
}

Execute the above migration using the below command.

php artisan migrate

This command will create a ‘payments’ table in your database. Next, create a model corresponding to the ‘payments’ table.

php artisan make:model Payment

After this, add the PayPal credentials in your .env file.

PAYPAL_CLIENT_ID=PASTE_HERE_CLIENT_ID
PAYPAL_CLIENT_SECRET=PASTE_HERE_CLIENT_SECRET
PAYPAL_CURRENCY=USD

Clear the configuration cache using the command:

php artisan config:cache

I have passed the ‘USD’ currency. The user can change it as per requirements.

Let’s define the routes which we will require in the next steps.

routes/web.php

<?php
...
...
Route::get('payment', 'PaymentController@index');
Route::post('charge', 'PaymentController@charge');
Route::get('paymentsuccess', 'PaymentController@payment_success');
Route::get('paymenterror', 'PaymentController@payment_error');

PayPal Payment Gateway Integration in Laravel

Integrating payment gateways API in the application is quite complex stuff. Fortunately, Omnipay library made developer’s lives easy. Omnipay is the most popular payment processing library for PHP. It gives an easy and clean code for integrating different payment gateways. Install Omnipay library using the command:

composer require league/omnipay omnipay/paypal

Now, create a controller PaymentController and define the methods mentioned in the route file.

php artisan make:controller PaymentController

PaymentController.php

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Omnipay\Omnipay;
use App\Payment;
 
class PaymentController extends Controller
{
 
    public $gateway;
 
    public function __construct()
    {
        $this->gateway = Omnipay::create('PayPal_Rest');
        $this->gateway->setClientId(env('PAYPAL_CLIENT_ID'));
        $this->gateway->setSecret(env('PAYPAL_CLIENT_SECRET'));
        $this->gateway->setTestMode(true); //set it to 'false' when go live
    }
 
    public function index()
    {
        return view('payment');
    }
 
    public function charge(Request $request)
    {
        if($request->input('submit'))
        {
            try {
                $response = $this->gateway->purchase(array(
                    'amount' => $request->input('amount'),
                    'currency' => env('PAYPAL_CURRENCY'),
                    'returnUrl' => url('paymentsuccess'),
                    'cancelUrl' => url('paymenterror'),
                ))->send();
          
                if ($response->isRedirect()) {
                    $response->redirect(); // this will automatically forward the customer
                } else {
                    // not successful
                    return $response->getMessage();
                }
            } catch(Exception $e) {
                return $e->getMessage();
            }
        }
    }
 
    public function payment_success(Request $request)
    {
        // Once the transaction has been approved, we need to complete it.
        if ($request->input('paymentId') && $request->input('PayerID'))
        {
            $transaction = $this->gateway->completePurchase(array(
                'payer_id'             => $request->input('PayerID'),
                'transactionReference' => $request->input('paymentId'),
            ));
            $response = $transaction->send();
         
            if ($response->isSuccessful())
            {
                // The customer has successfully paid.
                $arr_body = $response->getData();
         
                // Insert transaction data into the database
                $isPaymentExist = Payment::where('payment_id', $arr_body['id'])->first();
         
                if(!$isPaymentExist)
                {
                    $payment = new Payment;
                    $payment->payment_id = $arr_body['id'];
                    $payment->payer_id = $arr_body['payer']['payer_info']['payer_id'];
                    $payment->payer_email = $arr_body['payer']['payer_info']['email'];
                    $payment->amount = $arr_body['transactions'][0]['amount']['total'];
                    $payment->currency = env('PAYPAL_CURRENCY');
                    $payment->payment_status = $arr_body['state'];
                    $payment->save();
                }
         
                return "Payment is successful. Your transaction id is: ". $arr_body['id'];
            } else {
                return $response->getMessage();
            }
        } else {
            return 'Transaction is declined';
        }
    }
 
    public function payment_error()
    {
        return 'User is canceled the payment.';
    }
 
}

In the above controller, we grab the amount from the HTML form and send a user to PayPal for payment. On the successful payment, we store all the transaction details in the ‘payments’ table.

Finally, create a blade file called payment.blade.php and add code below in it.

<form action="{{ url('charge') }}" method="post">
    <input type="text" name="amount" />
    {{ csrf_field() }}
    <input type="submit" name="submit" value="Pay Now">
</form>

When we submit this form, control goes to the charge function in the PaymentController and controller processes the rest payment flow.

Send Product Information to PayPal

In the previous steps, we are sending the amount to pay on PayPal. You may also want to send product information. The user can see these product details on the payment page before making a payment.

To send the product information, you need to pass the ‘items’ array to the purchase method as follows.

$response = $this->gateway->purchase(array(
    'amount' => $request->input('amount'),
    'items' => array(
        array(
            'name' => 'Course Subscription',
            'price' => $request->input('amount'),
            'description' => 'Get access to premium courses.',
            'quantity' => 1
        ),
    ),
    'currency' => env('PAYPAL_CURRENCY'),
    'returnUrl' => url('paymentsuccess'),
    'cancelUrl' => url('paymenterror'),
))->send();

Here I am passing the product details statically. You should make it dynamic depending on your product.

I hope you got to know about PayPal payment gateway integration in Laravel. Please share your thoughts and suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

20 thoughts on “PayPal Payment Gateway Integration in Laravel

    1. try {
      $response = $this->gateway->purchase(array(
      ‘amount’ => $request->input(‘amount’),
      ‘items’ => array(
      array(
      ‘name’ => $request->input(‘category’),
      ‘price’ => $request->input(‘amount’),
      ‘description’ => ‘t-shirt’,
      ‘quantity’ => 1
      ),
      ),
      ‘currency’ => env(‘PAYPAL_CURRENCY’),
      ‘returnUrl’ => url(‘paymentsuccess’),
      ‘cancelUrl’ => url(‘paymenterror’),
      ))->send();

      if ($response->isRedirect()) {
      $response->redirect(); // this will automatically forward the customer

      } else {
      // not successful
      return $response->getMessage();
      }
      }

    1. I run the command
      php artisan config:clear

      but the error continue
      Authentication failed due to invalid authentication credentials or a missing Authorization header.

      Is the laravel or ommipay version?

  1. helllo I am getting error,

    Authentication failed due to invalid authentication credentials or a missing Authorization header.

    1. When you added new constants in the environment file, you may sometimes need to clear configuration cache. You can do this by running the command:

      php artisan config:cache
  2. Authentication failed due to invalid authentication credentials or a missing Authorization header.

    I am getting this error please help

        1. this is because the paypal credentials couldnt get from the .env file… try
          $this->gateway->setClientId(‘client id’);
          $this->gateway->setSecret(‘secret id’);
          directly on the PaymentController and comment the previous things..thank me later

  3. Tbis is the first time I subscribe for a newsletter !
    Your articles are always straight to the point!
    Can you please write an article on how to integrate Stripe with Laravel?

Leave a Reply

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