Creating a simple webstore with PayPal integration in Laravel 6

Lars Wolters
6 min readSep 16, 2019

Before reading, please note that this guide was written a few years go and might not be up to date regarding your project and what you want to create. Using the PayPal API to receive payments isn’t required anymore and there are better ways to handle payments (such as Stripe and other providers).

For a long time, I’ve been looking how to make a reliable, simple but efficient webstore with PayPal integration in Laravel. After discovering how, I instantly presented mine to senior developers and the Laravel community, that granted alot of useful feedback. Now, I’d love to share with the world how to make what took me long to figure out.

We will cover a dynamic webstore, order-payment-product database schema, fully functional shopping cart and complete PayPal REST API integration.

Step 1: Getting started

Let’s start-off with creating our Laravel project. I assume you know how to do this, but just in case:

laravel new webstore

When your project is ready, make sure you configure your database credentials in the .env file. For this tutorial, we will be using MySQL. I’ll call the database ‘webstore’.

Front-end scaffolding

If you already have your own front-end ready, you can skip this section.

Front-end scaffolding used to be installed by default. However, this changed with Laravel 6. To get our traditional Bootstrap scaffolding, first run:

composer require laravel/ui --dev

We also want the authentication scaffolding in our project, so secondly, run the following command:

php artisan ui vue --auth

And finally, to compile our assets:

npm install && npm run dev

Step 2: Models & database migrations

Our database will be the big core of our application. We will start off with some theory and then the database migrations.

The theory behind invoices, orders and products

For programmers that are new to developing e-commerce systems, it may be somewhat confusing to construct an efficient payment-order-product schema. I personally like to use the following one:

  • An invoice has a ‘paid’ or ‘not paid’ status, depending on the checkout response.
  • An order is bound to an invoice (payment). The order is valid when the invoice is successfully paid.
  • An order can contain one product, but also multiple products (shopping cart). Therefore, an order contains ‘sub-orders’, which are the products of a certain order.

Let’s clear up some things with an example: an online store that sells phone cases would only send the customer the ordered product(s) when there is a valid order: the invoice was paid, therefore the order is valid. Same for a physical store: you pick your phone case, you pay for it, and then you leave the store without being jumped by security. Online stores and physical stores have more in common than you might think.

Database models and migrations

We will need some models and migrations. Let’s start off with the product. We won’t be covering the user, since this was already done by the scaffolding.

Product model & migration

php artisan make:model Product -m

Inside of our product migration file, we put:

Order model & migration

php artisan make:model Order -m

Inside of our order migration file, we put

Sub-order model & migration

php artisan make:model Suborder -m

Inside of our sub-order migration file, we put:

Finally: The invoice model & migration

This one is a bit different. When we implement PayPal, we get loads of information back from the response. For this tutorial, we will only save certain data into the database (you can add / remove columns). To see what data you get back from the PayPal response, check the Example Response on the API Documentation.

php artisan make:model Invoice -m

Inside of our invoice migration file, we put:

Step 3: Shopping cart & PayPal

Our webstore needs a shopping cart and PayPal integration to be functional. Let’s jump right into it.

Functional shopping cart

For the shopping cart, I like using one well-maintained package for Laravel that works very well with PayPal’s SDK. Let’s install it:

composer require bumbummen99/shoppingcart

Next, let’s add two things: the shopping-cart widget and the ability to add items to the shopping cart.

First, let’s create our WebstoreController.php file by running php artisan make:controller WebstoreController. We will add three functions for editing our shopping cart. Our controller will contain the following:

Good. Something is missing though: we must be able to interact with the shopping cart from the webstore page. I like to have a shopping cart button in the navigation bar after logging in, that shows a table with our cart contents. Let’s update the layouts/app.blade.php file (which was created upon scaffolding):

Webstore page & adding items to our shopping cart

Clicking a product on the webstore should add it to your shopping cart. Thanks to the package we use, this is really easy. For this tutorial, we use the home view for the webstore, so let’s update home.blade.php:

PayPal SDK

PayPal offers a cool SDK for PHP, including a composer package. Let’s install this one too:

composer require paypal/rest-api-sdk-php

Next, we need to create paypal.php file in the config directory. Create it manually and paste the put in it:

I’ve left out comments in this file, since the code is quite self-explanatory and you probably won’t touch it anyway.

PayPal Sandbox

PayPal offers a sandbox-variant for developers, making testing really easy and safe. To create a sandbox account, you will need a normal PayPal account.

Once you have logged in to your sandbox account, there are three things we need: a sandbox business account, a client ID and secret. These three credentials can be found under My Apps & Credentials > *Your application* at the sandbox dashboard.

Clicking on your application under ‘My Apps & Credentials’ shows the information above.

Updating our .env file

Since we now have our sandbox credentials, we can define them in our .env file by adding the following:

PAYPAL_CLIENT_ID=YOUR_APPS_CLIENT_ID
PAYPAL_SECRET=YOUR_APPS_SECRET
PAYPAL_MODE=sandbox

Creating our PayPal controller

We are almost there. All there is left is a controller for PayPal, so let’s make it:

php artisan make:controller PaypalController

Our controller should look like this (I’ve commented a lot in the file to explain the process). The code may look a bit chaotic, but works perfectly fine:

Routing

Finally, let’s update our routes/web.php file:

Wrapping up

Good! We got everything ready for testing. Migrate and populate your database by running php artisan migrate:fresh --seed and php artisan serve . The end result should look like this:

Adding products to the cart and then opening the cart modal.

Clicking checkout will take you to the PayPal transaction, and then redirect you back to your webstore with an alert.

Also, your database will get updated. An order will be inserted with the ‘initialised’ status. Upon completing the payment, the status will be set to ‘pending’ (which means valid, you can change this slug). An invoice will be inserted in to the database with the ‘approved’ status and the rest of the PayPal response data. Awesome.

Afterword

I also created a GitHub repository for this tutorial, containing the complete source-code.

Any feedback is appreciated and I’d love to get in touch with you. If you have any questions, feel free to ask them. Thank you for reading.

--

--

Lars Wolters

Back-end developer from The Netherlands — writing (hopefully) helpful articles for others 🙂