Paypal Payment Integration With Laravel

Paypal payment gateway in laravel php#

In this post we will discuss about paypal payment gateway integration and account setup like business account and personal account.

Paypal is very popular payment gateway if you are not in india then definitely you have used paypal. but in todays day it is popular in india too.

For using paypal payment gateway in your website you have to create too account one is business account and other is personal account.

Business account will receive payment and personal account is like your individuals account for paying on any online ecommerce portal.

First create a account on paypal.com and after login in, go to developer.paypal.com

Now follow below steps

Get Api Credential

No you have option to create a app for which will contain both business and personal account as well as api credentials

Get Api Credential

Get Api Credential

Get Api Credential

Once you got you api Client ID and Secret you can start with integration

Now add three entries in you .env file of laravel project at the bottom.

PAYPAL_CLIENT_ID=paypal_client_id
PAYPAL_CLIENT_SECRET=paypal_secret
PAYPAL_CURRENCY=USD

Now add two packages which will require for integration.

  1. “league/omnipay”
  2. “omnipay/paypal”
composer require "league/omnipay"
composer require "omnipay/paypal"

Add one controller which will handle all paypal actions

php artisan make:controller PaypalController

we need two table one for recording users purchased product and one for keeping track of payment details.

so add below tables

  1. user_subscriptions
  2. payments

you can create a migration for these table but i am giving you a raw sql directly.

CREATE TABLE `user_subscriptions` (
  `id` bigint UNSIGNED NOT NULL,
  `package_id` int NOT NULL,
  `user_id` int NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `payments` (
  `id` bigint UNSIGNED NOT NULL,
  `payment_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `payer_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `payer_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `amount` double(10,2) NOT NULL,
  `currency` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `payment_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `user_id` int NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


now create a models for these two tables

php artisan make:model UserSubscription
php artisan make:model Payment

you also have to add routes and view for successfull and failed payment. create two file

success.blade.php

@extends('frontend.new.layouts.home')
@push('after-styles')
<style>
      

    


    </style>
@endpush
@section('content')



    <div class="container">
    <div class="row justify-content-center">
        
                <div class="col-md-6">
        <div class="thankyou_container">

            <div class="thank_icon_fst"><i class="fa fa-check" aria-hidden="true"></i></div>
            <h2>Congratulations, your payment was successful</h2>
            <h5>Your transaction id is {{$arr_body['id']}}</h5>
           
        </div>
        </div>
        </div>

    </div>

    @endsection


declined.blade.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment success</title>

    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="{{asset('css/font-awesome.min.css')}}">
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background: #f2f2f2 !important;
        }

        .thankyou_container {
            position: absolute;
            top: 50%;
            left: 50%;
            -ms-transform: translateX(-50%) translateY(-50%);
            -webkit-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
            text-align: center;
            padding: 48px;
            background: #fff;
        }

        .fa-check {
            color: #536bf6;
            font-size: 45px;
        }

        .thankyou_container h2 {
            font-size: 26px;
            padding: 30px 0;
            border-bottom: 1px solid #dad4d4;
        }

        .thankyou_container a {
            background: #3490dc;
            padding: 10px;
            text-decoration: none;
            color: #fff;
            border-radius: 5px;
            margin-top: 24px;
            display: inline-block;
        }

        .thank_icon_sec {
            width: 50px;
            margin: 0 auto;
            padding: 8px;
            background: #C54343;
            border-radius: 50%;
        }

        .thank_icon_sec .fa-check {
            color: #fff;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="thankyou_container">
            <div class="thank_icon_sec"><i class="fa fa-times" aria-hidden="true"></i></div>
            <h2>Something went wrong, your payment method was declined</h2>
            
        </div>
    </div>

</body>

</html>

you also have to add routes for those views create three routes

Route::post('/subscribe', [PaypalController::class, 'subscribe'])->name('subscribe');
Route::get('paymentsuccess', [PaypalController::class, 'payment_success']);
Route::get('paymenterror', [PaypalController::class, 'payment_error']);

Copy paste the below code in the controller

<?php

namespace App\Http\Controllers\Frontend;


use App\Http\Controllers\Controller;
use App\Package;
use App\Payment;
use App\UserSubscription;
use App\Models\Auth\User;
use App\Mail\Frontend\NotifyMail;
use Auth;
use Exception;
use Mail;
use Illuminate\Http\Request;
use Omnipay\Common\ItemBag;
use Omnipay\Omnipay;

class PaypalController 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 subscribe(Request $request)
    {
       
        $paymentAmt = 100;
        

        if ($paymentAmt > 0) {

            try {
                $itemBag = new ItemBag();
                $itemBag->add(array('name' => "Java_Course" . "-" . "342", 'quantity' => 1, 'price' => $paymentAmt));
                // dd(url('paymentsuccess'));
                $response = $this->gateway->purchase(array(
                    'amount' =>  $paymentAmt,
                    'currency' => env('PAYPAL_CURRENCY'),
                    'returnUrl' => url('paymentsuccess'),
                    'cancelUrl' => url('paymenterror'),
                ))->setItems($itemBag)->send();


                if ($response->isRedirect()) {
                    $response->redirect(); // this will automatically forward the customer
                } else {
                    // not successful
                    return $response->getMessage();
                }
            } catch (Exception $e) {
                return $e->getMessage();
            }
        } else {
        }

      
    }
    
    public function payment_success(Request $request)
    {
        $user = auth()->user()->email;
        // 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();
                if (isset($arr_body["transactions"][0])) {
                    $transaction =  $arr_body["transactions"][0];
                    if (isset($transaction["item_list"]["items"][0])) {
                        $product = $transaction["item_list"]["items"][0]["name"];
                        $product_data = explode("-", $product);
                        if (count($product_data)) {
                            $package_id = $product_data[1];
                            $userSubscription = new UserSubscription();
                            $userSubscription->package_id = $package_id;
                            $userSubscription->user_id = auth()->user()->id;
                            $userSubscription->save();
                        }
                        // dd(explode("-", $product));
                    }
                }
             

                // 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->user_id = auth()->user()->id;
                    $payment->save();

                  
                }


                // return "Payment is successful. Your transaction id is: " . $arr_body['id'];
                return view('success', compact('arr_body'));
            } else {
                return $response->getMessage();
            }
        } else {
            return view('declined');
        }
    }

    public function payment_error()
    {
        return view('declined');
        return 'User is canceled the payment.';
    }

    
}

you are all set now if you will run and visit the url /subscribe then it will redirect to paypal payment gateway and will show you 100$ payment to pay you can use your personal sandbox account from developer.paypal.com to login and pay.

after payment you can see the received amount at business login which you will get the credentials at same developer portal of paypal.

Thats it for this post. i hope it will work for you, if you find any problem you can comment or mail me.

comments powered by Disqus