
How to Integrate PayPal Payment Gateway with Laravel Application Step by Step
Adding PayPal to LMS Using Laravel
Hello guys, thank you for all your support, in this tutorial I will be adding a feature called payment gateway and we will be using a PayPal payment gateway, I have so many requests from the audience, So I decided to write this article and create a separate video about how to integrate PayPal to your laravel project. I hope this article will help you to understand the steps.
So, in this Article, I will take you guys through a step-by-step process to integrate PayPal into any of your laravel projects as easily as it is.
So, to get started with this implementation we have to install two packages.
1. ( srmklive/laravel-paypal ). Which will help us to integrate PayPal in less than a few minutes.
To Install it is very simple let use the following commands to install it.
composer require srmklive/paypal:~3.0
To Publish the Asset let us use the following command:
php artisan vendor:publish --provider "Srmklive\PayPal\Providers\PayPalServiceProvider"
More About the Laravel-PayPal Read Documentation
2. ( jenssegers/agent ). Which will help us to get the users that are not registered or login to the system to able to add product to cart before checking out.
To Install it is very simple let use the following commands to install it.
composer require jenssegers/agent
More About the Agent Package Read Documentation
After installing the package, we will now have to create an account or login into our existing PayPal developer account to Retrieve our sandbox credentials.
The steps are as follows:
Open the browser and type (developer.paypal.com ) and I will leave the link in the video description below.
Create a new testing App. Inside the PayPal developer dashboard.
Open the .Env file and add the app credential:
App Client Id:
App Secret Key:
Create AddToCart Model along with the migrations by using the following command.
php artisan make:model AddToCart -m
The -m flag will create the migration file for the add to cart model.
Create Order Model by using the following command.
php artisan make:model Order -m
The -m flag will create the migration file for the order model.
Create OrderCourse Model by using the following command.
php artisan make:model OrderProduct -m
The -m flag will create the migration file for the order courses model.
Create a PaymentController by using the below command:
php artisan make:controller PaymentController
Open the Payment controller and define two new functions as follows:
-
Success Method.
Copy and paste the following code snippets inside the success function.
// Import the class namespaces first, before using it directly
use Jambasangsang\Flash\Facades\LaravelFlash;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
use App\Models\AddToCart;
use App\Models\Order;
use App\Models\CourseOrder;
public function success(Request $request)
{
$provider = new PayPalClient;
$provider->setApiCredentials(config('paypal'));
$provider->getAccessToken();
$response = $provider->capturePaymentOrder($request['token']);
// dd($response);
if (isset($response['status']) && isset($response['status']) == 'COMPLETED') {
$productInCart = AddToCart::where(['user_id' => auth()->user()->id,
'payment_id' => $response['id']])->with('course')->get();
$order = Order::create(['user_id' => auth()->user()->id,
'status' => \constPayPalStatus::SUCCESS, 'date' => now(),
'payment_id' => $response['id']]);
foreach ($productInCart as $key => $cart) {
CourseOrder::create([
'course_id' => $cart->course_id,
'payment_id' => $cart->payment_id,
'order_id' => $order->id,
'discount' => $cart->discount,
'qty' => $cart->qty,
'price' => $cart->course->price * $cart->qty
]);
}
AddToCart::where([
'user_id' => auth()->user()->id,
'payment_id' => $response['id']
])->delete();
LaravelFlash::withSuccess('Payment Completed Successfully');
return redirect()->route('home', ['cart']);
}
LaravelFlash::withError('Whops!! Something went wrong please try again');
return redirect()->back();
}
-
Cancel Method.
Copy and paste the following code snippets inside the cancel function.
// Import the class namespaces first, before using it directly
use Jambasangsang\Flash\Facades\LaravelFlash;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
use App\Models\AddToCart;
public function cancel(Request $request)
{
if ($request['token']) {
AddToCart::where(['payment_id' => $request->token])
->update(['payment_id' => '', 'status' => \constPayPalStatus::PENDING]);
LaravelFlash::withInfo('Payment has been Cancelled');
return redirect()->route('home', ['cart']);
}
LaravelFlash::withError('Whops!! Something went wrong please try again');
return redirect()->route('home', ['cart']);
}
Create two new routes inside the web.php file as follows:
Route::get('payment-success', [PaypalController::class, 'success'])->name('payment.success');
The PayPal success route will be the route that would redirect us to the PayPal endpoint.
Route::get('payment-cancel', [PaypalController::class, 'cancel'])->name('payment.cancel');
The PayPal cancel route will be the route that will redirect us back to our application when something got wrong or when you decide to cancel your purchase.
Create a Livewire Component and give it a name as Cart.php by using the following command.
php artisan make:livewire Cart.php
Add the follwing code snippets inside the componet as follows:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
use Jenssegers\Agent\Agent;
use App\Models\Course;
use App\Models\AddToCart;
class Cart extends Component
{
public $getUserAddToCartProduct;
public function render()
{
if (Auth::check()) {
$this->updateCartAfterUserLogin();
}
$this->getAddToCartProducts();
return view('livewire.cart');
}
public function removeCourseFromCart($id)
{
$addToCart = AddToCart::find($id);
$addToCart->delete();
$this->emit('updateAddToCartCount');
session()->flash('success', 'Product removed from cart !!!');
}
public function getAddToCartProducts()
{
$agent = new Agent();
$this->getUserAddToCartProduct = Auth::check()
? AddToCart::with('course')->whereUserId(auth()->user()->id)
->whereStatus('!=', \constPayPalStatus::SUCCESS)
->get()
: AddToCart::with('course')->whereBrowserName($agent->browser())
->whereStatus('!=', \constPayPalStatus::SUCCESS)->get();
}
public function addToCartButton($course_id)
{
$agent = new Agent();
// dd($course_id);
$course = Course::find($course_id);
// Sorry here is if the course is already inside tha cart
if (count(AddToCart::where(['browser_name' => $agent->browser(),
'course_id' => $course_id])->get()) > 0) {
session()->flash('info', 'The Course' . $course->name .
' is already available in cart');
return;
}
// Sorry here is if the authenticated users course is already inside tha cart
elseif (Auth::check() && count(AddToCart::where(['user_id' => auth()->user()->id,
'course_id' => $course_id])->get()) > 0) {
session()->flash('info', 'The Course ' . $course->name .
' is already available in cart');
return;
}
// Check if the user is not logged in add to cart with the broswer name
if (!Auth::check()) {
AddToCart::create(['browser_name' => $agent->browser(),
'course_id' => $course_id, 'price' => $course->price, 'qty' => 1]);
}
// If the user is logged in add to cart with User Id;
else {
AddToCart::create(['user_id' => auth()->user()->id,
'course_id' => $course_id, 'price' => $course->price, 'qty' => 1]);
}
session()->flash('success', 'The Course' . $course->name . ' added to cart');
$this->emit('updateAddToCartCount');
}
public function checkOut($course_id = null)
{
if (!empty($course_id)) {
$this->addToCartButton($course_id); // is a function
}
// if (!Auth::check()) {
// return $this->dispatchBrowserEvent('loginModal');
// }
$this->getUserAddToCartProduct = AddToCart::with('course')
->whereUserId(auth()->user()->id)
->where('status', '!=', \constPayPalStatus::SUCCESS)
->get();
$provider = new PayPalClient([]);
$token = $provider->getAccessToken();
$provider->setAccessToken($token);
// dd($provider);
$payPalOrder = $provider->createOrder([
'intent' => 'CAPTURE',
'purchase_units' => [
[
"amount" => [
"currency_code" => 'USD',
"value" => $this->getUserAddToCartProduct->sum('price'),
]
]
],
'application_context' => [
'cancel_url' => route('payment.cancel'),
'return_url' => route('payment.success'),
]
]);
// dd($payPalOrder);
if ($payPalOrder['status'] == 'CREATED') {
foreach ($this->getUserAddToCartProduct as $key => $cartCourse) {
$cartCourse->status = \constPayPalStatus::IN_PROCESS;
$cartCourse->payment_id = $payPalOrder['id'];
$cartCourse->save();
}
return redirect($payPalOrder['links'][1]['href']);
} else {
return redirect()->back()->with("Whoops!! Something got wrong");
}
}
public function updateAddToCartAfterUserLogin()
{
$agent = new Agent();
$coursesInCartByIpBrowserName = AddToCart::with('course')
->whereBrowserName($agent->browser());
if (count($coursesInCartByIpBrowserName->get()) > 0) {
$coursesInCartByIpBrowserName->update(
['user_id' => auth()->user()->id, 'browser_name' => Null]
);
}
}
}
Create another Livewire Component and give it a name as AddToCartCounter.php by using the following command:
php artisan make:livewire AddToCartCounter
Add the following code snippets inside the component as following:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Jenssegers\Agent\Agent;
use Illuminate\Support\Facades\Auth;
use App\Models\AddToCart;
class AddToCartCounter extends Component
{
public $cardCount = 0;
protected $listeners = ['updateAddToCartCount' => 'getAddToCartProductCount'];
public function getAddToCartProductCount()
{
$agent = new Agent();
$this->cardCount = Auth::check() ? AddToCart::whereUserId(auth()->user()->id)
->where('status', '!=', \constPayPalStatus::SUCCESS)
->count() : AddToCart::whereBrowserName($agent->browser())
->where('status', '!=', \constPayPalStatus::SUCCESS)
->count();
}
public function render()
{
$this->getAddToCartProductCount();
return view('livewire.add-to-cart-counter');
}
}
Add the following code snippets inside the add-to-counter blade view file as following:
<div>
{{ $cardCount }}
</div>
Add the following code snippets inside the component as following:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
class Payment extends Cart
{
public function render()
{
return view('livewire.payment');
}
}
Add the following code snippet inside.
<?php
use App\Models\Course;
use App\Models\Order;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('course_orders', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Order::class)->constrained()
->cascadeOnUpdate()->cascadeOnDelete();
$table->foreignIdFor(Course::class)->constrained()
->cascadeOnUpdate()->cascadeOnDelete();
$table->string('payment_id')->nullable();
$table->integer('price');
$table->integer('qty');
$table->string('discount')->nullable()->default(0);
$table->string('status')->nullable()->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('course_orders');
}
};
Add the following code snippet inside.
<?php
use App\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->string('order_number')->nullable();
$table->foreignIdFor(User::class)->nullable()->constrained()
->cascadeOnUpdate()->cascadeOnDelete();
$table->string('payment_id')->nullable();
$table->timestamp('date')->nullable();
$table->string('status')->nullable()->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('orders');
}
};
Add the following code snippet inside.
<?php
use App\Models\Course;
use App\Models\Order;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('course_orders', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Order::class)->constrained()
->cascadeOnUpdate()->cascadeOnDelete();
$table->foreignIdFor(Course::class)->constrained()
->cascadeOnUpdate()->cascadeOnDelete();
$table->string('payment_id')->nullable();
$table->integer('price');
$table->integer('qty');
$table->string('discount')->nullable()->default(0);
$table->string('status')->nullable()->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('course_orders');
}
};
Hello guys, welcome back to programming with Singhateh. In this tutorial, I will go back to the LMS project that was uploaded a few days ago. I will add a feature called "payment gateway" to it. And the payment gateway that I will be using will be PayPal. After uploading the project, I had so many requests from the audience. So I also decided to write an article and create a separate video about how to integrate PayPal into your Laravel project. I hope this article will help you understand the steps.
Let's get a recap of the LMS project before starting the integration. I will take you through the system to see when the user purchases a course it's directly enrolled without a payment procedure, So in this video, we will include a payment procedure to it.
So let's get started. I will be following the article that I wrote to make things easier. You can also go through the article for a better understanding of how to integrate PayPal into your Laravel project.
So, to get started with this implementation we have to install two packages.
The first package is laravel-paypal. and the second package is Jens Segers agent. these two packages will make things easier for us.
After installing the first package which is the laravel-paypal. now we have to publish the config file. so that we can able to customize things based on our needs.
Again, let's now install the second package which is the Jens Segers agent. this package will help us to get the users that are not login to the system and want to add courses to the cart before login into their account. So this package will give us the ability to perform such. To add a course based on your browser name and when you want to check out the browse name will be replaced with your logged-in ID.
You can read more about the package through its documentation. the link will be provided to explore more.
After installing both packages. Now we can move to the PayPal section. If you don't have a PayPal sandbox account make sure to create one and follow along. I will be using my existing PayPal sandbox account for testing purposes. After logging into our sandbox account. We have to create an App. You can give the app any name you wish. I will give mine LMS and press create button.
After the app is created successfully. We will now see our PayPal client ID and PayPal Secret Key. We will copy that Client ID and the Secret key into our Laravel project. To connect the project with PayPal through their API. To put these Credentials we have to open the .env file and place these credentials in. so that laravel will know the link between the framework and PayPal.
Now, Laravel will know that PayPal is part of the framework because we linked them using API. Now the next step we have to create the models. start with the Add to cart model along with its migration file. After that, we will create Order Model along with its migration file. again create CourseOrder Model along with its migration file.
Now, Let's create a Plain Payment Controller. Inside the Payment Controller, we will have two methods. the first method will be the PayPal success method. which will capture our payment and create order data inside the database. And the second method will be the Cancel method. which will redirect the user after canceling any purchase from their PayPal account when using our platform.
Now I will copy the Success method code snippet and paste it inside the Payment Controller and make some changes. Again copy the Cancel Method code snippet and paste it inside the Payment controller and make some changes.
We have to define PayPal Status as constants so that we can avoid using numbers everywhere in your project. Open the constant file and define the PayPal status values.
After registering the routes. now we have to create a livewire component and name it a cart.php. After creating the component copy the below code snippet and paste it inside and make some changes. make sure to import all the classes to avoid errors.
Again, let's create another livewire component and name it as Add to cart counter. and copy the below code snippets and paste them inside.
Now, let’s start defining the columns inside each migration file so that can able to start adding courses into the cart and perform PayPal Checkout. I will open each migration file and define columns based on what each need. So, follow along or you can get all the source code step by step on our website.
Thank you for reading this article, if you have anything that you wanted to ask leave your comment and we discuss it. I hope you understand a How to Integrate PayPal Payment Gateway with Laravel Application Step by Step by now.
0 Comments