All language subtitles for [English (auto-generated)] Build and Deploy E-commerce Website with Laravel and Vue.js [DownSub.com]

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

hello everyone my name is zura and I am

the code public I have built e-commerce

website with admin panel with online

payments and deployed it on a custom

domain with custom business email

address I also deployed the vue.js admin

panel on a subdomain of the primary

domain let's have a look at the demo of

the project let's start our demo in the

demo starts on the website on the

website we output all the published

products we have pagination and at the

moment it is set to five products per

page and we have three more pages card

login and registration logging in

registration are pretty straightforward

we have a few Fields right here to fill

up and we have of course forward

password page and password reset Pages

as well we have card page which displays

all the items you have in the cart you

don't need to be authorized to add items

into the cart you just click those

buttons and the items are added into the

cart

when we go to the cart page we see all

items we have already in the cart we

have possibility to remove items from

the card or change its quantity and as

we see down below the total amount of

the items in the card also increases as

soon as we change the quantity adding

items into the cart removing items

changing the quantity and in general

managing items on the front-end side is

done using alpine.js we have also

product Details page when we click on

the item itself we see the details page

and we have the description right here

they said to card button and the

quantity so I'm going to add like four

more items into the card and now I

totally have 11 items into the cart as

soon as I hit this proceed to checkout

now I need to log in okay but first we

have to create an account

when you fill up the form right here and

click the sign up button you will

receive a conf email confirmation you

just accept this email confirmation

click the button in your email and your

account will be activated and you will

be logged in as soon as you create your

account or just log into the system and

if you don't have any items into your

cart the items which we are added into

the card when you were guests those

items will be moved and Associated to

your authorized users information so

basically you can add items into the

cart as guest

but whenever you log in those items will

move and will be Associated to your

authorized users account and after that

you can even check out from second

device I'm going to log in with an

existing username and password and I'm

going to scroll down below and hit the

proceed to checkout this will redirect

me to the stripe checkout page here I'm

going to fill up the information or

stripe checkout at the moment it is

configured to accept test credit cards

so feel free to provide the following

credit card information and test how

checkout process works and click the pay

button this will redirect us to our

website and we see the successful

message Surah your order has been

completed I'm actually authorized and I

can click this my account right here I

have my profile in my orders if I click

my orders I'm going to see all the

orders I have made all the orders

basically are unpaid except this one I

can click on the order number to view

the the details of the order if I want

to manage my addresses or my personal

information I just click on my profile

and from here I can manage my addresses

update my password or just change the

profile details now let's go to the

admin panel once you log in in the admin

panel you're going to see a dashboard

this gives you an overview the latest

orders orders by country total income

couple of useful numbers and the latest

customers

the admin panel is built fully on vue.js

as a single page application which

connects to laravel API and communicates

just like this so you're going to also

learn how to create a vue.js

applications and connect to any

third-party apis

let's go to the products this is the

place from which we can manage our

products we can edit the product

information change the image change its

description change the price or we can

add new products from the orders menu

item we're going to see all existing

orders we can see details of each

individual order and we can even change

the status of this order I'm going to

set this into shift for example when you

change the order status the customer

will receive an email that his order

status was changed also when the order

is made by by customer admin user

receives an email that new order has

been made okay let's click on the users

from which we can manage all admin users

we can change the passwords of these

users or create new user or delete users

from the customers menu item we can

manage existing customers if we click

edit right here we can see the details

of the customer we can see all addresses

and we can even change addresses of the

customer let's go only reports from

which we can see basically orders by day

for last one month and we have a drop

down right here here from which we can

update the period into last week last

day or last three months the same type

of date range picker we have also on

dashboard right here we can choose the

period we want

all right I think I showed you

everything about the project user

interface in this video you're going to

learn how to build full stack

applications with lateral vue.js Talon

CSS and alpine.js how to correctly

Implement stripe online payments how to

create vue.js applications and connect

to any third-party apis and how to

deploy your projects on a custom domain

with custom business email address even

though this is multiple hours tutorial

still it is a small part of the entire

course I recommend to check the

codeholic.com and have a look at all the

features of the premium course I also

plan to regularly create updates for the

course for additional features such as

having multiple images for the products

create categories having a corrosal or

so-called featured products add stock

Management on the products and there are

a few others those are the top features

I want to include my next update which

will probably be in December when I

started working on this project my

initial plan was to create six or seven

hours tutorial on YouTube how to build

and deploy laravel fewjs e-commerce

project

I had a list of the features and I was

following that list implementing all the

features at some point I discovered that

I already had much more hours recorded

then it was my initial play I tried to

simplify the project remove few features

and continued recording like this when I

recorded everything all the features I

wanted to implement I discovered that

the the whole content was about 23 hours

long I put so much effort in this course

and I spent so much time on this course

actually if you have a look at the

GitHub repository you're going to see

that the initial comment was made about

five or six months ago I put so much

effort in this project that finally I

decided to make it as a premium course I

tried to make the price of the premium

course very affordable but even after

that I knew there were some people who

were waiting this YouTube tutorial free

YouTube tutorial how to build and deploy

lateral view JS e-commerce project I

simply could not let them down so I

decided to take some parts from the

premium course as is without any kind of

editing and then feel the missing gaps

with quickly explaining what changes

have been made from section to section

so finally this several hours tutorial

includes the whole process as well from

start to finish and actually the first

section starts setting up the project is

unedited you're going to see the full

process as well as the last section

deployment is unedited you're going to

see the full process and in between

you're going to see also cart management

for example and online payments those

sections are unedited full flow but in

between several sections are created not

created but are explained very uh very

fast of course not every single line

written in this project is explained in

this VOR tutorial because as I mentioned

the entire content is about 23 hours

long but the most important sections is

unedited you're going to see full

process at the end of this course we're

going to deploy the project to any

custom domain with custom business email

address as a choice of Hosting provider

we're going to use hostinger which is

also a sponsor of today's video I have

been very skeptical to Shared hosting

Services years ago I tried it years ago

a few times but that was very

unconvenient for me I didn't have

possibility to control my PHP version my

databases I the only possibility to

deploy my project was FTP clients using

filezilla for example which by the way I

don't like to deploy my projects for and

like my previous experience working with

premium shared hosting Services was not

that good then I switched to Virtual

private servers so-called vpses and I

preferred vpss because even though it

was a little bit expensive I had all the

control on my web server I could install

the version I needed I could manage and

maintain as much as I needed but both

hosting types have their advantages

shared hostings are very easy to set up

but you're kind of limited in shared

hosting however vpses you have control

on anything you you are very very

flexible but it's hard to set it up when

I discovered hostinger about two years

ago and started working with the

hostinger I discovered that hostinger

has best of both hosting types it's very

easy to start with the whole singer but

you also have great control on whatever

you need you can control your PHP

versions your DNS records you have

possibility to connect with SSH create

up to 100 websites up to 100 databases

you can set up sub domains and pretty

much anything you might need I'm going

to also show you how you can register

with hostinger get the premium shared

hosting which will include domain and

SSL and SSH access and databases and

everything basically you you will need

but first let's talk about the

prerequisites of this course this course

is pretty much for everyone who wants to

learn building full stack applications

with the laravel and vue.js the only

recommendation for me is to have basic

knowledge of laravel know what is

controller what is model where are the

immigration files located for example

and have a basic understanding of vue.js

at least no words as a component this

course also uses Talon CSS and alpine.js

but no prior knowledge of these

Technologies are required but still if

you have hard time understanding what's

happening around Talon CSS or alpine.js

I have tutorials for both I'm going to

put links in the video description

building such type of projects editing

connecting different parts to each other

and offering you as a free tutorial

takes a lot of time your appreciation

will be if you hit the like button and

subscribe there are many people watching

this video right now who is not

subscribed you are not losing anything

if you just hit the Subscribe button

that gives me additional motivation to

create such type of videos hit the like

button and again if you want to see the

full working process with 23 hours of

content 140 videos check my website

thecold.com alright let's register on

hostinger get premium shared hosting and

then start building this awesome project

all right let's scroll down below and

right here we have this premium shared

hosting and they have unmetered traffic

you can deploy up to 100 websites right

there you have 100 gigabyte of SSD

storage you have free domain free email

address and you have unlimited number of

free SSL certificates and if we see all

the features there are much more you

have unlimited databases you have also

git support in SSH access you have 100

email mailboxes so when you take a

domain you can create up to 100 emails

which will be

um under the domain basically all right

so you get a lot for such a low price

and let's click right here add to cart

which will redirect us to their checkout

page so right here we have four options

we can purchase the hosting for one

month 12 months 24 months or 48 months

and when you purchase it for 48 months

you get an insane discount almost 500

okay so you can choose whichever option

you want then scroll down below provide

your email address right here or

authorize using Facebook or Google

scroll down below right here you again

get a little bit of Glimpse what you are

basically uh taking in this amount you

already have a great discount but

actually if you use my coupon code the

code holique you're gonna get additional

10 discount then you fill up the

information right here and submit secure

payment all right I recommend to take

these premium shared hosting at the

moment because they have Black Friday

insane sale use the link in the video

description or provide a coupon code the

code holic right here to get additional

10 discount once you fill up the form

and click submit secure payment you will

be redirected to the hostinger's age

panel from there we will be able to

claim our free domain

configure SSL create databases deploy

our project access to our hosting using

SSH and do much much more

before we start working on the project

let's set up working environment for

this we will need to install a couple of

applications the first one is example

which is a package and contains Apache

mariadb and PHP Apache is a web server

to run PHP Mario ADB is a database and

PHP B is just PHP

let's go on

apachefriends.org click on download in

the menu and right here we have exam for

all major operating systems download the

latest version for your operating system

and just follow the installation

instructions it is pretty

straightforward next we will need

composer which is which is a dependency

manager for PHP using composer we will

be able to create new laravel project as

well as install dependencies in existing

laravel project go to download right

here and download it for your operating

system next we will need text editor

slash ID my

primary choice for PHP is phpstorm it is

pretty straightforward pretty powerful

smart PHP ID the only disadvantage is it

is not free as a free choice I recommend

Visual Studio code and I also have a

video where I install 12 useful

extensions for PHP so if you're new to

PHP and vs code you can just watch that

video and install those extensions

because without the extensions basically

vs code is is not that intelligent

okay download whichever editor you want

and now let's create new larval project

but before that uh we as soon as you

install your exam uh let's open exempt

control panel

and when to start Apache in MySQL

Services just click Start buttons right

here and after that we will be able to

access p in a localhost slash PHP my

admin

and we need to create a schema from here

that's a Mario DB in client interface

just click new on the left side and

specify right here the database name I'm

going to call my database laravel view

Ecommerce and choose the encoding utf-8

MP4 Unicode CI that's where I'm going to

choose and according to my experience

that is the encoding which works best

for Unicode characters and just click

create right here okay now let's open

CMD

and I'm going to also navigate to the

folder

here's the CMD and I'm going to navigate

to the folder where the xamp is actually

installed and that is going to be under

Windows C drive

example the path and navigate using CD

hit enter and now I'm in the exam Pages

folder and I'm going to create new

laravel project right here for this I'm

going to create first laravel installer

install so composer Global require

laravel slash installer I'm going to hit

enter and this will download the alarm

installer and then we'll be able to

create new laravel projects using that

installer now I'm going to run laravel

new

in the project name I'm going to call

laravel View

e-commerce

let's hit enter

it's going to take few seconds or means

depending on internet and many other

things and until this is actually done

we have already folder right here I'm

going to open the laravel view

e-commerce in my text editor I'm going

to use phpstorm so right click on that

and open folder as PHP store on Project

you can open with vs code if you prefer

it and it's going to take few seconds

here it is already opening

and let's have a look in the CMD

and application is ready okay so we have

already successfully installed that I'm

going to actually close CMD because I'm

going to use later the PHP storms

integrated terminal

and we already have database so let's

open Dot en file and when to configure

the database so the connection is MySQL

the host is this is a local IP the port

is 3306 that is the default Port we

should leave that and the database is

called laravel view Ecommerce that's

actually correct name username is root

and the password

for Windows installation it is empty so

the database is actually configured

successfully now let's open Terminal

and I'm going to run PHP Artisan migrate

this is going to apply migrations in the

database okay migrations are files which

hold the schema information okay in this

case the migrations created users table

they created password results table they

created a failed jobs table and personal

access tokens table okay now let's open

PHP my admin and just reload right here

and we see larval view e-commerce inside

there we have five tables fail jobs

migrations password resets personal

access tokens end users and those are

tables which we are created from here we

will have to create our own migrations

in a moment

but let's test our application in the

browser so let's run PHP Artisan serve

hit the enter it's going to start the

alarms development server at a local IP

port 8000 so let's just click right here

or open localhost port 8000 and we see

laravel application up and running

all right

um perfect I think we should start right

now working on the database schema so

for this let's have a look at the schema

I prepared so we have the following

tables so the users table which already

exists in the laravel this one

so I don't have Fields described right

here so that's just for the referencing

other tables but let's understand and

start with the products so for products

we have title slug the slug will be

unique uh string generated from the

title image we have image mime and image

size as well we have description we have

status for the product we have price of

course we have created that and updated

it when the product was created and

updated we have created by and updated

by by whom the product was actually

created or updated we have deleted it

and deleted by that is for soft deletes

when the product will be actually

deleted by the Admin users it's not

going to be actually deleted from the

database but the deleted deleted add and

deleted by Fields will be set

then we have orders and Order items so

here we have the orders the order has

total price it has its status whether

the order is appending or completed it

has its created it updated it created by

an updated Pi then we have order items

which is a junction table between orders

and products we have the order ID here

product ID here quantity in the unit

price okay then we have payments which

is connected to the orders

and we have order ID here we have amount

we have status we have uh type right

here created it and created by we don't

have updated it and updated by because

the once the payment is made it's not

going to be actually updated

okay

down below we have card items now which

references to user and product and uh

quantity as well so that user added the

following product with the following uh

quantity in cart and that's the also

date when that actually happened okay we

can actually have right here updated it

as well if the quantity is updated

inside the cart

we have order details as well which is

connected to the orders and that

contains the first name last name email

phone address one address information

basically everything and country code

and create that and updated ad we have

countries table which references to the

audio details and finally we have

customers and customer addresses and the

order details basically is just a union

of customers and customer addresses

tables

okay just like that this is our whole

schema so we have possible we will have

possibility to add items into the cart

uh then make orders and then we have

order details and make also payments and

based on that information we can have a

minimalistic reporting as well which

products have been sold this month and

so on things like that okay now we have

to generate migrations and models for

the following schema

now let's open phpstorm I'm going to

open new terminal right here I'm going

to actually call this

serve

and in other terminal and right here

we're going to generate models and

migrations PHP artisan make model and

I'm going to call this product and I'm

going to specify right here Dash M for

migration as well

so we have to generate product

the next will be to generate

um

let's wait until this is actually

generated

then we have to generate

order model

well let's have a look in the schema

again so we should first generate tables

which don't have references to other

tables

okay until that other tables is already

generated for example when we generate

products then we can generate cart items

but we cannot actually generate for

example order details table until the

orders table is actually created so

that's why we need to keep that ordering

so maybe before the order model I'm

going to leave these as it is I can

delete that later

but before the order model we should

create a country which is which doesn't

uh

a reference to other tables itself so

let's generate

country then we can generate already

orders

and Order details as well or we can

generate cart items as well so let's

generate now cart item

then we need to generate order detail

then we need to generate uh order item

then we have to generate

uh maybe payment then we have to

generate customers and customer

addresses and we're done

so let's generate

customer model with migration

and customer address

okay now let's have a look in the

project under app

uh models right here we have cart item

country customer customer detail order

everything basically what we just

generated let's go in the database and

go under migrations and right here we

have now first products then orders then

we have countries cart items order

details so they are right now generated

in the order that they can run whenever

we create uh right here corresponding

content inside the schemas okay let's

start from the products table and

basically generate schema here we need

the product title we need slag we need

image we need image mime

we need image size and long text which

is going to be description

and decimal price we will need created

by which references to the user we need

updated by as well which references to

the user as well we need soft deletes

which will add those created at sorry

excuse me which will add those deleted

add and deleted by fields and we will

need foreign ID for the user as well for

the dldt to buy and finally at the top

right here we need to import the app

models user because we use it right here

for reference okay that is for the

product table let's open the second one

which is orders table okay for orders

let's first import app models user

because we're going to need that then

down below we need to add total price to

the order we need status on the order we

need the created by and updated Buy on

the order and that's that's all for the

order we can double check in the schema

as well we don't have anything else

right here we don't have timestamps but

we already have it

the next table is countries table okay

for countries we don't need ID and

timestamps so I'm going to remove both

and we're going to add a string code

which is going to be primary key we will

need name and we will need a Json B

which is going to be state so that's

going to be a Json column and it's going

to contain States a couple of countries

have States and we need to show States

drop down as well when you choose a

specific country for example United

States so we're going to save that Json

States information right here inside the

states Json

okay we have that let's open the next

one which is card items table okay for

cart items we don't need timestamps so

I'm going to remove that we will need

foreign ID for user with the user ID we

will need foreign ID uh on product ID

column it references ID on products

table okay we have a foreign key on the

products

then we will need timestamp created it

we actually don't need

um

updated it or we can actually add I

think we decided to add we don't even

though we don't have that in schema it

will be good to have that so uh yeah

that's it and we need uh quantity let me

actually change this into

time stamps so that we have both and I'm

going to move this down okay and just

like that we have cart items let's open

the other one which is order details

inside order details we need the first

name last name phone which is nullable

address 1 Idris 2 will need City we need

state

we need zip code and country code

and that's basically all so we need all

only those fields

okay in the down basically in every

migration down we already have drop if

exists and it drops the table okay so we

save that and let's open the next one

which is order items table here we need

uh order ID to be referenced to the

orders table

we need product ID to reference to

products table

we need quantity and we need the unit

price

and that's all for order items let's

open the next one which is payments

table or payments we will need the

reference foreign key to orders table

using order ID we need amount decimal we

need status of the payment we need type

of the payment whether the payment is

made by cash or credit card we need a

foreign key to create it by to the user

table and update it by and we need to

import that user model at the top okay I

think we don't have the type of the

payment in this schema now actually we

do have that we do have okay so fine

let's move on on the next one and which

is customer stable for customers we will

need first name last name we'll need

phone we need status and we need created

by an updated Buy

okay and let's import the user model at

the top here we have that so we have

customers table migration ready as well

and finally we need customer addresses

here we will need type of the address

whether that's a shipping address or

billing address we need address 1

address 2 we need CT we need state ZIP

code country code and we need customer

ID to which customer this address

references to and we need country code

to which country this address belongs to

and yeah I think that's it so that's all

what we need and we have our migrations

actually ready now let's open Terminal

let's clear up everything and I'm going

to run PHP Artisan migrate this will

apply just created migrations okay all

of them we created successfully now

let's open PHP my admin and reload the

page and here we see all our tables what

we just created

awesome now let's open Terminal

let's clear up everything and I'm going

to run PHP Artisan migrate this will

apply just created migrations okay all

of them we created successfully now

let's open PHP my admin and reload the

page and here we see all our tables what

we just created

awesome now we need to create vue.js

application

for this make sure you have node.js and

npm installed on your operating system

if you don't have just download for

Windows or for your operating system the

latest version which is at this moment

it is version 16 LTS just I'll always

try to download LTS version which is

long-term support

okay and just download that install that

and then you're gonna have npm command

available in your terminal and in this

case we're going to run npm create write

and just to make sure that we have the

latest version we can specify tag it

latest I'm going to hit enter and it's

going to take few seconds okay what's

going to be the project name the project

name will be backend I'm going to call

this backend and which framework I want

to choose I'm going to choose vue.js and

whether I want to use view or just view

in typescript I'm going to choose just

view and just like that it is generated

inside the backend folder okay right

here The View application is generated

now let's navigate inside backend and

I'm going to run npm install

and npm run Dev

that's going to spin up the white server

and now let's open a localhost port 3000

in the browser and we see Hello view 3

plus white and clicking on the counter

actually works so we actually

successfully created vue.js application

now we need to install Talon CSS in our

vue.js application make sure whenever we

have to do anything inside the vue.js

application make sure you are in the

backend folder okay if you write any

comments from the project root directory

which is larval view e-commerce in my

case it's not going to work for vue.js

applications okay just make sure we are

in the back end because we have to run

commands for the vue.js application

which is inside the backend in this case

we have to install Talon CSS so let's

open the browser and I'm going to just

type talwind CSS White

and the very first link will be guide we

have to basically install Talon CSS post

CSS and auto prefixer as a Dev

dependencies that Dash d means that we

want all of them as a Dev dependencies

and then we have to run npx Talon CSS

init Dash p so this will create talwin

CSS config Dash p will create config for

post CSS we can copy these two lines go

inside the backend

terminal terminal which is navigated

inside the back end and we're going to

paste this right here

first npm install and then MPX download

CSS init Dash p that's going to create

config files

right here we have post CSS config and

talent config.js those two files were

generated and the package.json was also

updated down below we see auto perfect

Surplus CSS and Talon CSS as added

inside Dev dependencies

all right so we have them now what do we

need to do here we can find the full

guide in the talid talent config.js we

need to copy content open talent

config.js and inside the content we need

to

oops we need to replace the content

and down below we have to do the

following things we need to create a

source index CSS and copy and paste that

right there let me actually collapse the

terminal

under Source I'm going to create Now new

file called index.css

and paste them right here and then we

need to open main.js and we need to

import that

import

index CSS

okay and the CSS is actually running

okay so we have created that imported

that and then when we run npm run Dev

the talent CSS will already work so

let's bring up the terminal again clear

up and run npm run Dev

and let's open now up view or hello

world

and where's the template right here and

let's actually give this one uh

background purple

500.

so we save that and let's have a look in

the browser here we see background

purple 500 so that actually proves that

Talon CSS is installed in our project

now I want to install Vue X in our

backend vue.js application so let's

bring up the terminal make sure you are

in the backend folder navigated into

your terminal and we're going to run npm

install S View X at next to install

basically the latest version for vue.js

I'm going to hit enter

it's going to take a few seconds

okay the view X is probably installed

let's have a look right here we see

viewix and now we need to create store

and use that in our application

in this Source folder let's collapse the

terminal in the source folder I'm going

to create a new folder called

store and inside the store I'm going to

create new file index and Js

okay so from here I'm going to actually

call const store equals create store I'm

going to hit enter and now phpstorm

automatically detects that there are

create stores created in the following

packages and if we want to import some

of them I'm going to import the very

first one create store okay hit enter

and Page control automatically Imports

that for me

okay so we have create store and we have

to specify right here object and we have

to specify state

which is an object we have Getters

object actions

and mutations

okay and we have to export default store

from here

now let's open main.js and I'm going to

import store from

store and down below I have to create

app we're going to run use store

okay and just like that we created the

store and we are using that store

Let's test how store is actually used so

let's go in the state and create test

property which corresponds to one two

three four

now let's open hello world component

and right here the hello world component

actually uses composition API and here

we need to import

computed from View and then Define a

property const test equals computed

which accepts a callback and returns I'm

going to import store from my store

store dot state DOT test okay basically

this test now will be available in the

template and let's actually output test

right here so we save that

uh actually when we format the code it

formats on four spaces and we have to

adjust this as well but let's run npm

run Dev

and now open the browser

and right here we see one two three four

okay if we delete everything because we

have to delete them in any case so we

delete everything from the template

oops

now we have one two three four okay

that's coming from the store if we open

again store index.js and change this

into five six seven we save that and

have a look here it is okay our store

was actually successfully used

okay let's continue and now we need to

install view rotor I'm going to just

stop the server and then we're going to

run AMPM install Dash uppercase s to add

that in a dependencies view Rotor at

next

by specifying it next we're sure that

we're going to get the latest version

okay we hit enter okay this is actually

done now we need to go in the

source and we're going to create a right

here folder rotor and inside there we're

going to create index.js okay so let's

create right here folder called router

and then inside there I'm going to

create new file called

um index

index.js

okay so from that we're going to create

a router and Export that okay let's

write uh const rotor equals create

rotor and when we hit enter page we're

showing detects that there are the

following create rotors existing and

it's suggests me to import I'm going to

import the first one and we're going to

specify right here object we need to

specify history to be create web history

and that should be also imported from

view router and we're going to specify

right here Roots the roads doesn't exist

yet so it's defined const roads equals

an array for rows so we have rotor with

create web history and roles as well

this create web history by the way

defines a history mode true so we will

have always normal URLs and we won't

have hashes like our users for example

endpoint will be something like

domain.com slash users not

uh hashtag slash users okay so this is

what create web history will do

um okay and finally we need to export

default uh router from here and we need

to open main.js and import

uh router from here

and then just like we are using store we

need to use rotor okay we already have

rotor actually ready we can start our

server npm run Dev now let's actually go

in the rotor and create two routes I'm

going to create one for uh dashboard

I'm going to give it a name also

dashboard and the component will be

dashboard component this component

doesn't exist yet and we're going to

create that so I'm going to actually

duplicate this and I'm going to call

this one uh login

and the component will be a login okay

the login component will be also created

now let's go in the source and we're

going to create right here folder called

views and I'm going to create new vue.js

file right here

view component that's going to be login

okay so here we have I'm going to create

H1 login form

and then I'm going to duplicate the

login and create a dashboard View

hit enter

and the dashboard view of course needs

to have different text

dashboard now let's go in the router and

I'm going to import dashboard from views

dashboard okay make a few uh your ID ID

editor doesn't support Auto Import make

sure you write the following code here

and make sure you also specify extension

let me actually change this into login

and we have to specify extension right

here Dot View so we save that now let's

have a look in the browser I'm going to

refresh the page

and we don't see anything because if we

open up that view uh we still have right

here hello world with that image okay

let's delete everything we don't need

the hello world we don't need that image

in the template however we need rotor

view this is what we need and this will

be the place where our views will be

displayed and I'm gonna remove that from

setup as well and let's go in the

components and let's delete that hello

world so we save that now let's have a

look in the browser we have an error

Source components hello world

uh where's the component actually used

let's search inside the project hello

world

we don't see that project probably uh

patreon didn't understand that I deleted

and saved that now let's reload the page

and we see login form now let's go on

the dashboard and we see dashboard okay

that actually proves that our routing

successfully works now let's start

working on the login form I'm going to

open login.view let's open the browser

and I'm going to look for Halloween CSS

um actually let's search for tilewind

components

and open the very first link

uh no that's not actually what we are

looking for I want to look for talent UI

let's go under components and right here

uh talwind

um offers couple of free and paid

components I'm going to use three

components only and I'm looking for

signing and uh registration forms where

are those let's actually search for

registration here it is so let's click

on that and this is how our form logging

form should look like I'm going to

actually change this into view and the

Italian UI components basically suggests

only HTML uh react and vue.js version so

I'm going to go in the view and go in

the code and I'm going to copy the whole

code and that gives me hint as well that

I need to install Talent CSS forms and

it gives me the following hint that this

template requires updating your HTML and

body tags and this is the whole form and

it also uses hero icons and we have to

actually use install that package as

well and it has template and script okay

we have that copied now let's go and

replace template and script

however as I mentioned we have to

install a couple of packages like hero

icons

let's actually look for edit list UI

because that template basically

is using in this case it it uses hero

icons only but couple of templates

mentioned right here which requires

JavaScript functionality uses headless

UI in this case there is no JavaScript

necessary in this form everything is

only HTML and CSS but if we want to have

for example if we want to copy a drop

down the drop down requires JavaScript

and that uses headless UI so it's going

to be good if we need in the future that

JavaScript

JavaScript activated components we need

to have headless UI so let's click on

this headless UI and

here we as I mentioned here are all the

components which uses JavaScript and I

want to go on the installation section

let's go here's the documentation so npm

install headless UI for view latest and

we will need hero icons as well

so basically we need to install the

following packages let me actually open

page for sure so let's bring up the

terminal close that npm run Dev

and clear up everything and I'm going to

run npm install Dash

Dash D we need to install them as a Dev

dependencies

and let's specify a headless UI slash

View

we need to install headless UI actually

uh sorry a hero icons

um excuse me hero icons slash View and

we need a Tailwind CSS

slash forms

okay let's hit enter so this one is as I

mentioned a JavaScript that's a headless

UI which means that we have only

JavaScript we don't have user interface

and we are installing that vue.js ready

JavaScript components we have these hero

icons which are just for icons and we're

going to look for the hero icons from

here hero icons.com where we can get

that icons from here

and then we install that thousand CSS

forms which is required by that login

template okay so we install all of them

now let's run npm and run Dev and let's

check in the browser

let's go on the login page and this is

our form so we have the icon we have

nice inputs and

I don't think we have nice inputs I

think something is missing here uh we

need to open Italian config and we need

to add the Italian CSS forms plugin

right here so let me actually copy the

following

require and paste that right here we

when we format the code it formats that

and two spaces according to editor

config and now let's have a look in the

browser reload that and now we see the

actual input how it should look like

awesome so we actually

um have that do we need anything else

here so we have the login form let me

actually delete the uh comment let's

remove that yeah we need to add the

following classes on HTML and body so

let's open index.html oops

let's open index.html

and on the HTML tag let's add

H4 BG gray 50 and on body let's add h o

oops

okay we can have this always added on

all pages so let's hit the enter now the

background is slight gray and the form

is like four inputs are actually fully

white we can test this by setting this

on 300 for example

look at this but it's too much so let's

set this on 50. okay so we have our

login form ready we made small

modifications in the login form such as

removed logo and some texts and we also

created forward password and reset

password pages so whenever you click

this forward password it's going to show

The Following page you enter your email

address and hit the submit button at the

moment only front end is implemented and

this makes requests to the laravel in

the future and the laravel will send

email to that specific provided email

address and then when user clicks the

link in the email it should open a new

view which is going to be reset password

and this reset password link should

contain some secret token in the URL as

well okay whenever this is opened this

whenever we type basically whenever we

click the email the following URL will

be opened and that's going to be the

view and user will provide new password

and click the submit that the request

will go back to the laravel and it will

reset the password okay now let's start

working on the layouts If You observe

those three vue.js components for

request password reset password and

login template looks very similar to

each other actually we copied and pasted

from each other right so we have to

Define it's going to be good to Define

layout for auth for guest users

basically and we can move certain

classes inside the layout and then we

can have only the main part inside the

components and of course we're going to

need to Define

primary layout as well which will be for

authenticated users so let's actually go

under Source

components and inside the components I'm

going to create a vue.js component and

I'm going to call this

out

um or maybe guest layout guest layout

hit enter on that okay we will need to

copy and paste certain things uh from

the login form so I'm going to paste

that and now let's identify what's going

to be the layout

the layout can be

basically and this one can be layout

this div can be also a layout but the

text is different so we can provide a

prop right here for that uh

text

and this form of course needs to come

from the form component itself

okay the only thing we need is text okay

let's do like this I'm going to actually

take this form and replace this into

slot that's where the default slot will

be outputted and right here I'm going to

Output title

that's going to be title property

okay so we have the layout out layout

let me think

um

we can have this in in two ways like we

can have this as a component normal

component or we can have this as a uh

nested rotor view component okay if we

have this as a guest layout normal

component that's actually fine we can go

in the logging and now I'm gonna let's

copy this text

and I'm gonna remove this portion

and just type right here guest layout

we have that I'm going to specify right

here title

title to be signing to your layouts

and down below this is for the guest

layout and the guest layout needs to be

actually imported so if we just start

typing uh in a pascal case like guest

layout and hit enter that's going to be

properly imported right here okay and we

can use this Pascal naming for

components as well however if we don't

have that imported and if we just start

typing normal dished version naming

well it sometimes is imported properly

sometimes it's not in this case I

actually prefer to have a pascal case

naming guest layout so I'm going to

write it like this and in this case if

we have a look in the login form

uh

where's that

components guest layout we need Dot View

always for view components so let's go

on the login page

okay we have the form we don't have the

title The only thing is didn't to go in

the guest layout and Define right here

title prop

for this I'm going to use view threes

built-in function called Define define

props

and we have to specify well actually we

can assign this to a variable

const props equals Define props

what's the problem sorry my bad I'm

writing this in the style we have to

change this I'm going to actually change

this into composition API because I

really like this approach and I'm going

to put right here setup

okay and then we can Define already the

probes we can destructure the probes and

get the title but in the object for

defined props we have to define the type

for the props I'm going to specify title

must be string okay and now we have the

title let's open the browser and reload

the page and now we see that sign into

your account that is the title given

from the login.view from from here

okay now we can copy that and paste that

into multiple places

uh let's actually think

if we can't even move this form inside

the layout

so we we cannot move

we cannot move anything except the form

inside the layout that's for sure

however the form actually can be moved

inside the layout

and we don't need action of course we

aren't going to actually submit that

form somewhere else instead we're going

to need a submit on submit

okay and that is something which can be

also triggered from the guest layout

okay I'm going to show you what I'm

thinking and maybe it doesn't work I

will think while I'm actually doing that

so we can take that form move into guest

layout and wrap the slot

with the form okay now we don't need

that form right here we have the inputs

everything right there if we just reload

the page we see everything if we inspect

the form

and just expand the div element we still

see form right here however inside that

login component we need to listen to the

form submission

whenever a form is submitted we need our

function to be called and let's call our

function let's create function function

uh submit or function login

and I'm going to actually write console

log statement right here login

okay and I don't have the form I don't

have the control to attach event

listener on that so I'm going to go in

the guest layout and for the form uh I'm

going to Let's actually remove the

action I'm going to add submit event

listener I'm going to prevent as well

and that's going to be login but I don't

have login right here so I'm going to

emit my event from here to the parent

and down below I'm going to Define

Amit const aim it equals Define emits

and we have to specify right here submit

okay we have to emit submit event from

here and whenever the form is actually

submitted I'm gonna call emit

with the submit event

okay that's how I can do that now if I

go in the login on the guest layout I

can add submit event listener which

we'll call login method

okay now let's actually open the form go

in the console and maybe hit enter from

inputs let's go in the info section and

we see login so when I hit enter inside

the input that actually triggers form

submission or whenever I click the

button that's going to trigger the form

submission as well okay this is the

approach I can actually do

I don't know if that's the better than

the other one I think the other one is

slightly better because the guest layout

is more generic the guest layout is just

for a showing user a guest layout it

should not have in my opinion form

information right there so form is not

necessary in the case layout so I'm

going to actually undo the changes just

so you already know how you can aim it

events from the S layout so I can undo

this change go in the login and I'm

going to undo this from here as well

so we have form and whenever we

Implement actually Implement login we

can attach submit right here and create

that login form again however now we

need to use that guest layout in

password a request password so I'm going

to actually put this right here specify

the title

that's going to be the title let's

finish the guest layout and let's delete

everything above and below let's format

the code however we need that guest

layout to be imported okay just like we

have right here we can write that import

manually or I'm going to actually delete

one letter in PHP storm and hit the

control space and phpstorm auto

completes that for me however the last T

right here is missing and it also

um this autocompletes and imports that

guest layout for me as well but the

extension is missing

okay we have that now let's go in the

reset password and let's actually put

right here guest layout that was Auto

imported we specify title the title will

be set new password

sorry quick pause if you enjoy this

tutorial why don't you pause the video

hit the like button and continue

watching please hit the Subscribe Button

as well if you are not subscribed

and let's wrap the form and I'm going to

delete everything before the guest

layout and after so we have a nice

correct and guest layout let's check all

three forms uh the extension right here

is missing so we save that this is our

login form forward to your password uh

remember your password and the last one

is reset password134 okay this is our

layout awesome so we have successfully

created the guest layout component

now let's understand the changes made in

this section we created up layout and

this is how our layout looks like we

have this header with this user profile

and Logo drop down and we have the

sidebar and we can navigate between the

products and dashboard dummy Pages at

the moment okay let's understand how how

these this layout was actually made so

for this first we updated the I updated

the rules file and right here we now

have a component app layout which has

inside meta that this layout requires

authorization so only authorized users

should be able to access that and all

the existing roads became the children

roles of the following Road and down

below also we configured on the rotor

that on before each basically whenever

we try to access to a page we check if

the page we want to try to access

requires out Authentication and we check

and inside the store if the user doesn't

have the token we redirect user to the

login page okay if we open the store at

the moment we have the token to be one

two three four if I remove these and set

this into null for example and I save

and open the browser we see that I'm now

on the login page okay let's understand

this router once again and down below we

have this else if statement and if the

URL we want to basically navigate to

requires guest user and the token

already exists we redirect user to the

dashboard page so basically if we have a

look in the browser we are on the login

page but if we just open the store index

and I'm going to set this one two three

four right here save that now if I open

the browser I'm on a dashboard page so

basically white server automatically

reloads the page and the view rotor

detects that I have a token and I need

to go to the dashboard page okay these

changes have been made and this is the

app you know layout inside which we have

a sidebar component we have this nav bar

inside which we have the next to the nav

bar we have this main with the rotor

view inside and this is how our number

looks like and this is the sidebar we

also created not found page so basically

if we try to access a url non-existing

url something we see not found page and

this is done through the router so right

here we have configured basically if the

path matches one of the following paths

mentioned above then it will of course

render the corresponding components but

if the path doesn't match then this

component will be rendered not found and

this is our new note found page that was

all that has been made in this section

now let's understand what changes we

made so far we have created immigration

and we added is admin column to the

users table so for admin interface we

want only those users to be able to log

in who has is admin flag to be true

I also created admin user Cedar and I

created one admin user with the

following email and with the following

password so now I should be able to log

in as soon as I implement the bacon side

I created alt controller which is for

logging in logout for the API so right

here we accept the user information we

validate that we try to login user if

the username or password is incorrect we

return with the proper message if the

user is not admin we also return with

the proper message otherwise we create a

token and return the token and we have

implemented logout as well and right

here we also have an endpoint to get the

current user information for this we

created user resource and we are just

returning ID name in email and we also

created admin middleware and this

middleware will restrict access only

will allow access only for admin users

okay so and we of course need to

register these middleware in the kernel

file so under the under the road

middleware we added this admin

middleware right here and of course we

modified the rules and we ate it right

here admin middleware and that's

basically all we did on the backhand

side on the front hand side of course we

implemented the actual login in the

login.view and we also created separate

files for actions for store actions and

for store mutations and we're going to

see that as well so right here in this

login view we listen let's scroll down

below we listen to the login button

click we set the loading indicator true

we call the action store action login

and inside the actions now we have get

current user information login and

logout actions which by itself calls the

mutations if we check mutations we see

we have set user and set token we take

the user information and save it in the

state we take the token information and

save that inside station storage as well

as inside the state and just like this

the user is basically authorized and

this is how we modified the store as

well so we created separate files for

actions and mutations and imported them

right here okay so now we have the full

flow of uh login and logout for the user

and we can even test this let's open the

browser and hit the login right here and

now we are authorized

in next section we created fully

functional products crud so let's have a

look in the user interface first we open

the table we have a nice animation we

have the products we have pagination as

well we have possibility of course to

add new products we have also

possibility to sort items by The Columns

mentioned right here by title or price

with ascending or descending and we also

have possibility to search products by

keyword okay all that has been

implemented in the following section and

let's not now see how those things have

been implemented okay let's start from

scratch we created the product

controller the product controller has

basic methods such as index which should

return all published all existing

products we have in the database we have

store method to to store the product

with the image I'm not going to go

through the old line right here then we

have the show method to get a single

single product we have update and delete

right here basically basic crowd methods

we have the product request as well for

a validation we have the product

resource and only those fields are what

is returned in the product resource and

we have product list Resource as well

one is used for the table second is used

for the form and we have products table

and right here in this table we created

the reusable table header cell component

as well which handles the some common

staff common logic such as sorting for

example and this is a standard UJS table

and we have installed also spotties

larval sluggable so whenever a new

product is added based on the product

title slag of this product is generated

and that slag will be used later and

inside the product PHP we configured the

model to use the title for slack

generation

okay so the next thing let's have a look

in the products view this is the general

component we have a button right here to

show the model and we have the products

table and product model nothing

um that like um

difficult okay and inside the product

model we of course listen to the button

click and make requests for update or

for

um for delete and we also added

animation using Talon CSS and we also

installed the Thailand CSS forms plugin

that's for the for the inputs okay

um I think we already have forms I think

we only added animation right here in

this and whenever we just reload the

page we see

a nice animation for each individual row

okay so it it looks like very simple but

actually like this dedicated section

this particular section I think has a

about two hours of

um of the full process how these

products cried is actually

fully built and if you're interested of

course to see this full process and

check the full course on my website the

code holique.com

in this section we have installed Talon

CSS eCommerce theme into laravel

application and outputted all the

products we have in the database and we

have also implemented the registration

page in the theme design the login page

as well as forward password page and the

password related Pages basically as a

theme the following themes used Talon

CSS eCommerce theme if you want to see

how I built these Talent CSS eCommerce

theme you can check my other videos it

is built in two videos first you're

gonna see several hours I think three

hours video how I built this using Talon

CSS and then you're gonna see additional

video how I edit alpine.js functionality

to that okay but if you don't want to

watch that no problem just hit the

download clone right here and grab the

source code you can get it is free and

you can use this and I'm going to

actually use this the following theme

okay so this is the theme we're going to

use but what we need to do so first we

installed laravel Breeze once you

install laravel breathe it's gonna

create the following controllers under

the HTTP controller's out folder it's

going to also generate views under the

resources folder and yeah we have

installed lateral Breeze and then we

integrated our Talon CSS e-commerce

theme and we have included our CSS files

as well as whenever we need basically we

open the theme and copy and paste HTML

files and just put them into views our

blade files and make them live integrate

with the laravel so if we go now in the

resources and Views and open product

index for example this is a template

which is available in the Talon CSS

e-commerce template we can actually have

a look under Source we have a couple of

HTML files and the index.html is what

basically outputs all the products

product HTML is for the product details

and so on so whenever we need to create

product Details page we're going to

basically open this product HTML grab

the following source code identify what

is layout what is not layout and what

needs to be part of the blade and just

like this we integrate in our project

okay so here we uh basically render

iterate over our products and render

them just it's a straightforward

operation let's open actually product

controller I have I think we have it I

have opened it somewhere okay if not

then I will go into

controllers in a controller so in the

index page we select all the products

and sort them by updated descending and

for the Simplicity I have a pagination

to five items and pass that to

product.index inside which as I

mentioned we iterate and render render

them okay that's for the products now

let's have a look in the

uh authentication so so basically we

modified all the existing views which is

offered by laravel Breeze okay let's

open now these views out and if we have

a look blade so this blade a login blade

PHP file basically contains the template

which is grabbed from our

template from the logging HTML okay so

we just took the HTML template as I

mentioned and make it active make it

integrated into into laravel and we also

implemented email sending so whenever

the user is authorized not authorized

but uh registered on the website he's

going to receive an email on

registration and user clicks of course

on the link and the user is activated

and this is done by adding if we go now

inside

up

models and open the user right here the

user model implements must verify email

okay and because of that basically uh

the user is not able to authorize into

the system if he doesn't confirm his

email address and if you open a webphp

right here we are using this verified

middleware which restricts the user from

accessing the dashboard if the user

doesn't verify his email address and we

created product product Details page

this is the product Details page we can

actually have a look right here click on

this and this is the product Details

page okay that is the changes that has

been made in this particular section and

now the most interesting thing the most

interesting task starts and that is

Implement adding the items into the cart

and this is just unedited version what

uh what is also included in this course

so I'm offering this right now it's a

like I think uh one and a half hour

one and a half hour section of the

entire course where we have these cart

management adding items into the cart

removing items from the cart having a

dedicated card page Etc so enjoy that

specific section now let's start working

on the cart management adding items into

the cart changing their quantities

removing items from the cart and we also

need to add one important feature

whenever you're a guest you can

basically add items into the cart but

after you log in or register your items

which are in the cart needs to get

Associated to it to your account so

before user is authorized we're going to

save the items into cookie

so that user can navigate between Pages

like close the browser come back later

and the cart items will still be in

cookies but if user decided to proceed

with the registration login and decided

to basically register and login and then

these items which are in the cart needs

to move into his account and in the

database we're going to have them of

course saved in the cart items table

okay so this is what we're gonna

actually do

we have to do a lot of things so let's

start step by step let's open our

project and I'm going to create

a couple of files like we will need

controller of course let's go in the

HTTP controllers and we have to create

card controller right here and also

create a helper let me actually create

this helper manually I'm going to first

create the helpers directory and inside

there I'm going to create a new PHP

class called cart so we're going to

create card helper

so far so good now let's create

controller PHP artisan make controller

and I'm going to create cart controller

okay the controller was created it's

going to be right here

and we will have to create also under

resources views I'm going to create a

cart folder and inside there I'm going

to create index view so let me just

create new file under cart folder

index blade PHP

okay here we have it

this index played PHP will use the

default layout so I'm gonna get this x

up layout and put this right here and

let's just print H1

my cart items

perfect and we're going to have right

here this one should extend

the controller extends

controller wears out to completion

this one extend the controller

up HTTP controllers controller and let's

create right here index function from

which we will simply return a view

index

now it should be cart index

okay

so we will need of course to update the

web files rules file and we're going to

do a lot of things basically but let's

start step by step and I'm going to

start with the card PHP

um where is that by the way

oops my bed my bed that is a helper

let's actually call this card helper no

let's leave it let's call this card and

I'm gonna uh remove this extends

controller because I mistakenly

tended helper I needed to do this in the

controller so let's open cart controller

here it is and we need this method right

here

okay but let's start from the helper as

I mentioned and we're going to create a

couple of methods right here

we will need five methods right here the

first is git card items account we're

going to display how many items we have

in the cart in the navigation in the

header navigation second method we will

need is get card items which will simply

return an array of cart items we have we

will need get cookie cart items which

will return the cart items we have in

the cookie okay the get cart items

basically will analyze we'll understand

if the user is authorized it's going to

return those cart items from the

database if not it's going to basically

call get cookie cart items down below

we're going to need a get count from

items which will accept the cart items

and return the count from there why do

we need this why can't we call like get

cart items or get cookie cart items and

then calculate how many items we have

right there so we will understand these

when we go in the controller because

whenever we update the counter in the

cookie this is not yet saved in the

cookie okay this will be saved after

response is sent to the browser so in

this case we will need to accept and

cookie items in the area and we're going

to use this in in the cart controller so

you will understand this okay and down

below we're going to need final method

which will be move cart items into DB

whenever user registers and logs in in

the system whenever user authorizes

basically we will need to take the cart

items which the user has in cookie and

move them into database okay so let's

start implementing these methods step by

step

foreign

so first we need to get the request from

the request we get the user data and we

need to check if the user is authorized

we need to call cart item we are

basically we're making query in the

database so this method is called get

cart items account so whenever user user

is authorized we query from the cart

item table and we sum all the quantities

for that user ID okay basically if the

user has two items in the cart the first

item has quantity two second item has

quantity three we sum all of them and we

say that user has five items in the cart

okay however if the user is not

authorized we call get card I get cookie

cart items and these cart items will be

simply an associative array and we call

array reduce on that okay and we pass

right there cart items and a callback

function and we basically sum the

quantities from those cart items which

are right here in this area okay and

this finally will give us the same

result five okay let's move down below

and implement the second method get cart

items so here we get the request as well

we get the user information and we check

if the user is authorized we query card

items all cart items basically for that

specific user and we call map so we

basically want to map eloquent model

into us into an associative array okay

why we need to do this because

we need to return the data in the same

format from this function and whenever

the user is not authorized and the data

is in the cookie there is an associative

array so basically right here We call we

give a callback function and return an

associative array where key is product

ID and and one key is product ID and

second is quantity okay so basically

this one this whole command will return

an array of associative arrays where

each element has product ID and quantity

whenever the user is not authorized we

simply call get cookie cart items and

inside the cookie we save items just

like this okay

so let's continue and inside get cookie

cart items we get the request and from

the request we call cookie with the key

card items if that doesn't exist we give

it a default a string which is an empty

array then we decode this as an

associative array and finally we return

that which will be an array down below

we have get count from items we accept

the items and call array reduce on that

okay so we pretty much do the same thing

as we did above right right right here

okay so we call array reduce we give it

a cart items we give it a function we

give it initial value and this one will

return the number of items in this card

items array and finally we have move

card items into DB we get the request we

get the cart items from cookie because

those items needs to be moved into the

database okay

we assume that whenever this method is

called the user is already authorized so

we get the request user ID make a query

in the card items and get all of them

and we index them by product ID okay

let's assume the following case that a

user has some items in the cookie and

some items into the cart

into the database okay let's say that

user has item one two and three let's

create a scratch file scratch text file

for example and let's say that inside a

cookie

user has items 1 2 and 3 with id12 and

3. however in the database in the DB

user has items one

and

three or or four let's do like this okay

so whenever user is authorized we need

to take those items which are in the

cookie and not in the database and move

them into database so basically after

the user is authorized in the database

we're gonna have one

two three and four okay this is what

we're gonna have and in this case we

basically don't care uh quantities so we

basically move uh those items into uh

the database but if the item is already

in the database we leave with the

quantity it was there let's say that the

first item in the database has quantity

two and the fourth item has quantity one

however in the cookie the first item has

quantity three okay and the second item

had quantity like one and the third item

hit quantity one as well

so in this case we aren't going to sum

up the quantities of the items from the

cookie and from the database we will

simply leave the quantity whatever was

in the database so finally we're going

to have the first item two second item

one

third item one and fourth item one okay

this will be the final result in the in

the database and that's what we are

going to do so we basically

um get select all cart items from the

database and index them by product ID so

finally we're going to have an

associative area of eloquent models

where key will be the product ID

so let's continue and we create an array

of new card items and we start iterating

over the card items from the cookie and

we check if the cart items from the

cookie exists inside the database okay

by this check we check if the cart items

from the cookie exists in the database

we continue we don't do anything if it

doesn't exist we push this new item

which is inside the cookie but not in

the database into new cart items array

and we give it a user ID product ID and

quantity okay and finally we check if

the new cart items is not an empty array

we call cart item insert which will

finally save those cart items in the

database

okay so we we have done

um writing those methods and the only

thing we need to do is to import the

cart item so let's move at the very top

and right import uh cart item model okay

so far so good

okay now let's move in the cart

controller and let me actually delete

this index and create all the methods we

need right here

we will need four methods right here the

first will be index which we already had

second is ADD whenever we are gonna add

item in the cart

then we're going to have remove and

we're going to have update quantity okay

which will simply change the quantity of

the item in the cart

let's start implementing these methods

step by step and let's start with the

index so first we're going to call get

cart items to get all the cart items we

have no matter if it is in the cookie or

if it is in the database and we have the

cart items array then on the these cart

items I'm going to call array helper

plug method on the product ID so I

basically want to get a single

dimensional array of product IDs in this

case the IDS simply will contain it's

going to be plain array with the IDS of

the products okay then I'm going to make

a query in the database to select

products by those IDs and these products

will be now eloquent models then on

these cart items

basically I'm gonna index those cart

items which were taken from the either

cookie or from the database I'm going to

index them by the product ID and all

these card items will be associative

area where key will be the product ID

and the value will be the cart item

itself then I'm going to create a

variable total I want to calculate what

is the total

sum of all the cart items we have in the

either cookie or in the database because

we want to display this total to the

user in the interface then I start

iterating over my products and

basically I'm gonna sum up the product

price Multiplied on the card items

quantity and save that in the total okay

you get the idea

in the products array we're going to

only have those items which we have in

the cart so we start iterating those

products and multiply the product price

into the quantity of the cart item and

we save that in the total and finally

we're going to have total which will

have the value and finally we're going

to return the cart index View and we're

going to pass right there cart items

products in total there's a second way

to display the total which can be done

using alpine.js okay let's see which one

we can go with like this is a one way to

do I'm going to show you a second way as

well to display the total

um by alpine.js okay so let's move on

and implement the admit add method so we

get the quantity from the request if the

quantity wasn't given we assume that the

default is one then we get the user

information and check if the user uh

does exist we're gonna uh select the

first cart item with the given

uh with a given product ID and the user

ID so basically assume that there

already is a cart item

uh with this product ID okay we need to

check if there exists this cart item

then we're going to update its quantity

okay and

um add the quantity which we what we

received in the request and then we're

going to call update on the cart item

however if the cart item doesn't exist

this means that user is adding this cart

item the very first time in his card and

we're going to create data as an

associative array give it a user ID give

it product ID and quantity and save that

in the cart items table in the database

okay

however we need to handle the case if

the user is not authorized so right here

we need an else statement uh but before

else we need to return okay whenever

users successfully added the item in the

cart and the user is authorized we're

going to return the associative array

where we will have only count key and

the count will be from the card to get

items count okay which will understand

basically if the user is authorized it's

going to get the items count from the

database again have a look right here

get cart items count basically the code

will come right here and return the

total count

okay so and we need these counts to

update the number of items in the header

navigation

okay now now let's handle the else case

in else case basically we read the items

from the cart we can even use right here

we can't even use the method get cookie

cart items okay it's going to basically

do the same thing we might replace it

later okay and then we we have products

found variable which is by default false

and you will understand why we need that

then we start iterating over card items

and I get the each individual item by

reference okay that's also important

thing

and I check if the item's product ID is

the same as the given product ID which

comes on the request so we have to

update we have to do an update in this

case item quantity and this is the case

where I need it by reference because I

update this item quantity and add the

given quantity which comes in the

request okay and I also set the product

found equals true and I break this Loop

because I updated the product quantity

in the cart and there's nothing to do

anymore in this Loop so I and I set the

product found equals true however down

below I check if the product was not

found if we checked all the cart items

with what we have and there was no

product with the given product ID it

means that we have to add additional

item into cart items so in this case

cart items we push a new item in the

cart items which will have user ID Now

product ID quantity and price and

finally we're gonna save those updated

cart items in the cookie and we're gonna

give it a duration expired date for one

month and we return

um the same type of response what we

return right here with get count from

items this is the method what we created

in the cart helper get count from items

we give it cart items and it basically

calculates and returns a number so this

we need because the new cart item If the

product wasn't found or if the product

was updated the change is basically made

in the cart items is not saved yet in

cookie so right here we queue cart items

to be saved in the cookie but it is not

yet saved okay and this method is what

we need in this case

okay let's move down below and we have

to implement remove

for remove we first get the user we

check if the user does exist then we

make a query in the database by user ID

and product ID we select the first cart

item we check if the cart item exists we

simply delete that and we will return

new

response with the updated account

because that card item was deleted we

need to send to the user what is the

current count okay we need to handle the

else case in this case we read the cart

items again from the cookie and again we

could use the method get cookie cart

items we might replace this later and we

start iterating over our cart items

again we get the item from the reference

not sure if we need bioreference right

here or not but we check if the item

product ID is the same as the given

product ID we call array splice which

works internally on this card items and

modifies it and on that position which

is the index in this case it's going to

remove one item so basically if our

product was the second item it's going

to remove the second idea item from the

cart items and finally we're going to

have cart items updated and down below

we're gonna again call Q uh on the

cookie and we set this duration give it

the expired date one month and we return

the new count again we call git count

from items given the updated cart items

array and let's implement the last

method which is update quantity so here

we get the quantity again we get the

user information again we check if the

user is authorized and if user user is

authorized we select the cart item by

user ID and product ID and we call

update immediately on that okay if that

exists it's going to call update on that

okay if it doesn't exist simply it's not

going to do anything

and down below we return a response with

the updated count in the else statement

we select the cart items from cookie we

start iterating over those card items

and we select we find the cart item with

the given a product ID and we set its

quantity okay update quantity basically

means that we need to set new quantity

for that okay we don't we we don't have

Plus in equal right here like we had

whenever we were adding item in the card

instead we set the given quantity okay

and we of course save this in the queue

with the expired date one month and we

return the response okay I think that's

it right here do I miss anything

now that's it right here and the only

thing we need to do is to import all

those classes like I'm going to hit alt

and enter to import the card helper

let's import the cart item let's import

the cookie HTTP or I think it's

illuminate support facades cookie and

what else do we have we have to import

the product

it's a app models product not API but

app models product

and

at the top I think we have to import

this array helper as well

okay I think we have imported all of

them and I think the controller is fully

ready

now let's open web PHP and configure our

roads okay what do we have right here we

have the index we have the product view

page and we have the dashboard which has

Alton verified not sure if we need this

dashboard

however we need this verified

and how we're gonna do this so basically

a guest user can add items into the cart

remove items into the cart or basically

guest user can do card management

and authorized user can also do card

management but if the user is authorized

and not verified

we basically need to force the user to

verify his email address and he won't be

able to do anything okay so let's do

like this I'm going to create

a new middleware so

root

uh

middleware while Auto completion doesn't

work in my page store

okay and I'm going to call this

middleware

um yeast or verified okay the user

either needs to be guessed or verified

okay and let's create

group

okay let me restart my Facebook store

I restarted my PHP storm I think now it

can how to complete my code so let's

just create a group right here we're

going to of course accept a function

right here and inside that group I'm

going to put basically all my code so

this needs to be moved right here I

think we can completely delete this

dashboard we don't need that however

we're going to create a couple of routes

for the cart and let's start first

making a group I'm going to first give

it a prefix so all my rules needs to

have a prefix card and I'm going to give

it also a prefix name like cart Dot and

then I'm going to create a group

right there

and then we're gonna have Road get or

slash we're gonna have a cart controller

uh index method and let's give this name

to be

index and let's duplicate these three

times we're gonna have

ID and we're going to pass right here

product

with slag and this cannot be this is

going to call add method and the name

will be Ed as well right here we need

remove

for product with slug

and we need remove right here and the

last one will be update quantity

of course we accept right here product

as well

and select by Slug and right here we

have the update quantity method and the

name should be update Dash quantity

okay so we have the rules ready

we have the index method inside which

we're going to render all the cart items

we have the add method we have the

remove and update now it should not be

updated quantity should be update

quantity let's actually change this into

use so instead of writing namespace

replace qualifier with an import and

we're going to have at the top import of

card controller okay now I think we have

to create this guest or verified

middleware and Implement that so I'm

going to create I'm going to open the

terminal and write PHP artisan

make middleware

and let's call this guest or verified

guest or verified hit the enter

okay let's open guest or verified

middleware

and basically this uh middleware is very

familiar to email verified middleware so

I'm going to extend this from email

um

ensure email is verified that's the

correct name ensure email is verified

middleware and I think right here this

has a additional argument redirect to

root so we have to add this additional

argument

uh or no we don't need this is optional

basically uh we just need to remove

requests from here

okay

and we basically need to take this as an

optional as well so we get this optional

argument and

we need to check so if the user if the

request user does not exist

okay the user is guest basically and in

this case we allow users to proceed and

open the page so we call next otherwise

we call Parent

handle and the parent handle is the

ensure emails verified handle so we pass

request we pass next and we pass

redirect to root okay and we have to

register this middleware so let's open

open kernel PHP and let's duplicate this

line and let's call this guest or very

fight

and the middleware name should be guest

or verified

okay and comma so we have created

middleware we have added in the root

middleware so it should be properly used

now and I think the root file is all

also ready and maybe we need to go now

to the front end and Implement

JavaScript

so let's open up Js

and have a look what do we have right

here we have the toast data

we have the header related data I think

we don't need the header so we can

completely remove this we have the

product item

uh watch list I think we are not going

to implement watch list so I'm going to

remove all watch list related methods

I think we don't need the quantity here

as well we don't need the ID because

uh we can use we're going to use slug

okay to make requests we don't we don't

actually need the ID so we need a two

cart which

uh we can clear up because we're going

to implement from scratch and make

requests to the backend and remove from

watch list this can be actually changed

and one additional method we need is

um change quantity so let's create this

change quantity

and we have to implement all of that so

quantity

okay I think this looks good even even

ID is not necessary right here so we

have the method stops ready what is this

this is a sign up form which we don't

need that comes from the Alpine Jes

Talon CSS template so we have the toast

which we need we need to display a

successful message whenever user adds

something into the cart and yeah I think

we can already Implement these methods

but before that I'm going to create a

helper file inside the JS and I'm going

to call this HTTP Js

okay this will have this will have a few

methods like getting post methods we

aren't going to use any third-party

package I'm going to use axios in this

case I'm going to use a fetch API so I'm

going to create right here two three

helper methods for the fetch API

okay so let's create one function and

Export that function and call this

request this will accept the method URL

and some data and I'm going to create a

getmith get function and Export that and

post as well so git will accept only URL

and post will accept URL and data and

now we can Implement those methods

request get in post get in post

basically will call the request the main

thing right here is to implement request

so let's Implement gate impulse first

the they are very simple we're going to

call request past the method in the URL

for post we do the same thing however we

give additional data variable now let's

Implement request

first we're going to make a call of the

fetch method and pass it URL and we're

going to also give it a additional

object with the method in headers inside

headers we will need content type to be

application Json and accept Topic

application Json as well we will need

csrf token as well so we're going to

pass it ex csrf token to be document

head query selector and take these CSF

token from The Meta text and take its

content and give it right here without

that basically whenever we make post

requests we are it's not gonna work okay

we will get an error and right here if

if you just want to change this into

application X www.form URL encoded you

can easily do it okay

we need to pass an additional uh

property called body whenever the method

is post whenever the method is not get

basically and right here we check if the

method is guessed we take the empty

object and the structure it and the

structuring will not do obviously on

empty object however if the method is

not get we take the body right here we

take the data a stringify that and give

it into the assign it into the body and

then with the structure that and just

like this we will be able to give the

data to the request then we need to give

it a because this one will return a

promise fetch we call then on that we

get the response and we check if the

response status is more than 200 and

it's less than 300 which means that the

response was successful okay we return

response.json

because on the fetch API you have to

call

then two times to get an actual result

returned from the server okay so we call

then one time

then we return

response.json this one will still return

a promise and whenever we want to get

the actual result of this request we

have to do an additional then on that

okay which will be done later in the

app.js probably okay so if for some

reason uh the response was not

successful we throw the error whatever

we throw basically whatever comes from

the result right here because this one

returns also promise we await on that

extract the actual value from that

promise and throw that value okay so I

think we have everything ready right

here and we can now go in to app.js and

Implement these methods

in the add to cart method we make a post

request to the given URL what is this

URL so this Edge to cart URL doesn't

exist yet and we're gonna create that

we're going to generate that URL using

root laravel's root function we can have

hard-coded URL right here slash cart

slash Ed and specify maybe a slug but

this is not a good approach we want the

URLs to be generated on the larval side

so we're going to do that there and we

simply take that URL which will have a

string right there and make a post

request on that okay and we of course

need I need to pass the quantity as well

and

then inside then we get the result and

here's the interesting thing so we

trigger we dispatch the alpine.js event

card change

and we give the result count so from the

response from the card controller

whenever we change something eight item

into the cart remove item into the cart

we return a response which has count

right there okay so this is this is the

ad method and we return response with

count in both cases where the user is

authorized or not authorized and right

here we take the result count and

Trigger the card change and pass that

count and basically

inside the header we're gonna have

alpine.js component which will listen to

this card change and update the value in

the header I mean in the header right

here update the value whatever is

result dot count okay and we're gonna

also dispatch another event notify and

toast our toast basically listens to the

notify and it will simply display this

message if we want to see we can open up

blade PHP is scroll down below here's

the toast component alpine.js component

and here's the notify so notify on

windows so this one listens to notify

event on window and calls the show

method with the event detail message in

this case this is the message we give

and the show method is available right

here inside the toast component okay so

this one basically will show alpine.js

toast

okay and Inside the Cage we can simply

print console log response if there

isn't any error error let's print what

is the actual error let's Implement no

remove item from cart we make post

request on the remove URL the remove URL

will be generated in the same way like

a2card URL and we call then we get the

result we call notify we trigger we

dispatch to notify the item was removed

from cart and we dispatch also card

change and we give it a result count

okay and the last thing we need to do

after remove is to remove the cart item

from the cart items array okay what is

these cart items we don't have this

mentioned anywhere but we will have this

card items mentioned in the card page in

the blade so when we will move into

blade files and Implement those we're

going to have card items basically there

and

in the cart page whenever we click right

here on the cart page the items cart

items will be rendered using alpine.js

okay and

we simply these cart items will be

whatever will be rendered on the cart

items page and we simply remove the cart

item from the cart items array

okay now let's move on and we have to

implement the change quantity we call a

post method on the update quantity URL

we give it a new quantity we'll listen

on then we call dispatch card change we

give it new quantity and we dispatch

notify as well the item quantity was

updated

okay and I think just like this we have

implemented all the primary methods uh

we needed right here we have to import

this post function from the HTTP so I'm

going to hit alt and enter import post

from http.js and it's going to be

imported at the very top okay the only

thing missing right here is add to cart

URL remove URL and update quantity URL

phpstorm for some reason doesn't

understand this what is this dispatch

but it should work because that's a

alpine.js dispatch function okay I think

now we can move into blade templates and

modify a few things right here there as

well as create the cart page

okay let's open product index blade PHP

index

blade PHP and we're going to make a few

modifications right here for example in

the app.js we are using this Aid to cart

URL which is available on the product

and this product basically is what we

are passing right here on the product

item okay so this object is the product

right here so on that product we're

gonna add add to cart URL

and that basically will be to call root

and give it cart add as a name and the

product will be the parameter okay it

will automatically take the slug laravel

will automatically takes slug from here

even right here we don't need to provide

slack slack I believe

let's check the web PHP

uh yeah we don't need to provide because

we are selecting by the root key name

and we already have the root cane key

name changed in the model so we can

specify product right here let's scroll

down below and have a look I think we

can completely remove this Edge to watch

list button we don't need that

however in H2 cards we don't need this

ID as well because the N2 card is

available on the product itself okay so

we save this and let's open the browser

and let's

let's

the developer tools doesn't seem to be

working

okay ensure email is a verified not

found okay

now let's test everything

I think we need we need to import that

what's that Azure email is verified not

found it doesn't exist okay let's

import

um

ensure email is verified date comes from

up HTTP middleware do we have it

no we don't have this right here we need

to import that from illuminate out

middleware

ensure email is verified so we save that

and refresh the page

and here is our index let's now inspect

this and have a look in the network

let's zoom out slightly okay here's our

Network and let's click the edge to cart

button okay so the first thing is

successful the request was made

let's click on this

and we have an error post method is not

supported on this route okay I think we

know the reason so let's open web PHP

and right here we have all get requests

so this one this and this should be post

okay we save this

and let's check in the browser and click

add to cart once again okay we see the

toast item was added into the cart and

the request was successfully completed

let's now open the application by the

way let's see what is the response okay

we see count one so this means that the

item was added in the cookie well so

let's click once again now count is two

let's go in the application

and here are the card items of course

the actual cookie value is encrypted but

I think we have successfully added item

into the cart

we don't see this

um outputted right here so let's open

uh navigation blade PHP

and by the way we need to change this

into card as well so let's set this into

root cart

card.index

and let's scroll down below and this is

the place where we need to make some

changes

okay so previously in the template we

were using store header but I'm going to

remove this store header and right here

as well let's move up and at the top in

the header we have the six data mobile

menu open true or false so I'm going to

create one additional property right

here and I'm going to call this cart

items count

and as an initial value I'm going to use

the cart Helper and I'm going to call

get cart items count

okay so card items count corresponds to

the following value and let's move down

below

and if

the cart items count exists then this

will be displayed using Geeks show

and we need to Output in X text as well

let's move down below we have the

desktop version as well I think we made

changes on the mobile version only

let's remove the watch list

let's

have a look this is a different thing

okay here is the responsive or I think

this is the desktop the above one is

responsive so we set these roots oops

approach to be card dot index we scroll

down below

we set this into cart items count

right here as well let's move down below

and we have to remove

the watch list from here as well

okay now let's have a look in the

browser we reload the page and we see

two already immediately right here which

is awesome one additional thing we need

to do on the component so this one

header is already already alpine.js

component okay whenever we get the

response we dispatch the cart change and

we need to listen to the card change so

right here we're going to listen to card

change on window

and basically I'm going to set card

items count

equals to event

detail count okay whatever we pass right

here the whole object is detail event

detail and we need to take the count

from this event detail so I save this

and let's have a look in the browser I'm

going to add one more item in the cart

and we see three right here okay let's

add more items into the cart and we see

the counter increases magic right no

it's not a magic

it's just the correct implementation

all right so we have now six items into

the cart and I think we didn't need to

do anything on this page we need to

implement the cart page so I click on

this and we see my cart items now let's

open cart slash index blade PHP and this

is the place we need to work in

okay let's now open the Talon CSS

alpine.js

template the front-end template

and we have to copy and paste the card

template so basically what do we need to

do

let me actually copy the whole container

this container

and let's put this in the PHP store and

let's format the code

and save this and have a look in the

browser

okay so images are missing but the

template I guess is what we want

okay now let's make some changes we

don't want of course so many items

because we're going to iterate over our

items so let me actually delete all the

cart items and leave only one

okay how we're going to iterate

so from the cart controller I think we

are passing

where is that we're passing the cart

items

uh we're passing the products and total

okay

we get those variables and they are

available right here so

you know what I'm going to do so on this

div element which is the

wrapper of the card items I'm going to

make these is an Alpine JS component so

I'm going to specify X data right here

okay just like this and I'm going to

specify cart items right here which will

be the cart items given from the

controller but I'm going to modify it

slightly

and I'm going to do this and I'm going

to also

create a getter get cart total

okay

and this will be a calculated property

so and we are going to return

um something from here

so basically I'm going to run on the

cart items reduce and I'm going to

delete something something similar I'm

doing on the backend side calling reduce

on the cart items to calculate the total

so I'm calling reduce on this uh the

initial value will be 0 and we multiply

the product price on the quantity and

then add it to the accumulator so

finally this will give me the total sum

of all the card items but what are the

actual card items I'm going to run here

a PHP code so using blade curly braces

I'm going to call Json encode so I'm

going to take the products products

array which is given from the card

controller okay and the products are

basically eloquent collection okay so

I'm calling map on this and we accept

each individual product and I'm gonna

return an associative array which

finally will be Json encoded and

inserted right here so Json encoding

will give us a Json which is also an

array and right here we're going to have

an array okay so what do we have we have

ID slot image title and price we give

all of them inside the cart items plus

we give the quantity the quantity is not

available on the product instead the

quantity is available on cart items and

let's have a look in the controller once

again cart items is indexed array so

it's indexed using Key by so the cart

items is an associative area where key

is the

product ID

so right here based on the product ID we

get the quantity from the cart item okay

and additionally I'm going to give the

href which will be the product view page

and I'm going to give it the cart remove

URL which is going to be the remove URL

used in app.js

right here and we're going to have

update quantity URL which is going to be

used also in app.js right here okay so

I'm basically mapping the eloquent model

into an associative array each

individual model and then finally this

will be Json encoded so I'm going to

save these

uh we're going to save this and let's

have a look in the browser so far so I'm

going to reload the page and let's view

page source

okay let's scroll down below

and where is

where is that here it is

okay it has a lot of

quotations

should it be like this

I don't know

let's see okay let's see next

right here on that div basically

um

think we need to do this

on the div I'm going to create template

and I'm going to run the for Loop

alpine.js for loop on that but first i'm

going to make a check if

uh using X if if the cart items length

exists so if there are at least if there

is at least one cart item so and I'm

going to wrap

uh everything maybe using the checkout

button

think I'm going to wrap everything in

this template

okay if there are new items we this one

will not be displayed

uh however we will need another template

uh alpngs doesn't have else so we're

going to write X if

if a cart

items I think we need to do it vice

versa so

if Carta no we're doing it correctly

excuse me so if the cart items exists

then this will be uh this condition will

be satisfied if card items length does

not exist let's put exclamation mark

right here then let's create one div

with Talon scissors classes let's give

it a text Center and padding y

padding Y8 maybe text Gray like a 500

okay and let's write you don't have any

items in cart

okay perfect now we need to write a for

Loop and I'm gonna do this for Loop

uh right here so template

X4

product of cart items

okay let's format the code product of

cart items and now I can access this

product and this product

uh is something I can pass to another

component and I'm going to create X data

just like I have the

product index blade let's move up so we

have the product and this is the product

and this product is passed to the

product item so I'm going to do

something similar right here

and I'm going to call product item and

I'm going to pass the product right here

okay and what does this give me this

give me the functionality

that inside this component I can use the

methods defined in the component like

remove item from card and change

quantity and this is what I want let's

go in the cart this is exactly what I

want now let's let's save this and first

have a look in the browser we should see

a few items

okay we see only three let's inspect

this and have a look maybe we have an

error

uh no we don't have any error we have

three items

I think this is logical because we have

three different items but the quantities

should be

um should not be one for all of them

anyway let's Implement now this

uh the source will be it should be bound

using a colon product Dot

how do we call this image product dot

image save this and have a look so we

have now different images which is good

let's output the

X text that's going to be product dot

title

now let's remove these

save and have a look we have different

titles now let's take here of the price

the price will be

product No it should not be like this we

should basically give this pan X text

and

if we simply write product.price this

will print the price without the dollar

sign so I want dollar sign to be

prefixed with that so I'm going to use

string literals tactics right here

and I'm outputting the product price

which will do the same thing so we see

the product price but I'm going to put

additional Dollar in front of that

so now I refresh the page and we see

dollar sign right here the CSS is

something that needs to be adjusted and

fixed and we're going to fix that

however we have to I think

take care of the quantity

here we have it so on that select I'm

going to give this one X model to be

product dot quantity

now let's have a look

and voila we see that this item is added

twice this is a three times this is I

did just once

okay and I'm gonna listen to change of

this drop down and I'm going to call

change quantity on that

okay so far so good we can test this but

let's add

um right here

click

remove

um remove how it's called the method

remove quantity or

remove item from cart okay this is what

we need to call and I'm going to call

also modifier prevent

just to call the payment default

let's format this input

okay so we have added the remove event

listener we have added the change uh I

think we need to add right here minimum

needs to be one

on this

um by the way do we need

um select right here maybe this should

be an input and we can set whatever we

want so let me change this into input

uh let's give this one the same classes

and let's

give it a X model and change

we give it type number and let's give

this one minimum one in this case

and let's remove the select

uh okay I don't like the width of this

input so maybe we can give it a width of

16.

okay this is good let's go in the

network and see if the update quantity

or removed from the card works fine so

let's reduce the quantity request is

made we see the toast item quantity was

updated

and in the header we also see five I

decrease the quantity this changes into

four I decrease the quantity changes

into three as soon as I keep increasing

the counter in the header increases as

well

which is awesome so we have implemented

the quantity change now let's remove the

item from the cart let's remove the

first one it was removed the item

disappeared from The View which is

awesome exactly what we wanted let's

make a few changes right here a few CSS

modified modifications so that this

needs to be on the right and the height

of this item should not be that large

let's go in the blade template

and have a look so we need to adjust the

image Dimensions first let's actually

wrap this

in

anchor tag let's put image inside there

let's give this one it needs href

so in the href will be product dot href

we specified right here in this product

View

and we're going to provide some classes

what classes do we need let's give it a

fixed width like with 32 and 832

let's give this one a flex items Center

and justify Center and let's give this

overflow hidden as well and on that

image I'm going to give this one

object cover

so let's save these and have a look

okay

this is more or less okay so at least it

doesn't have that much hate there

and every row will have the same height

which is good

however

this one has different width and this

one has different width so width needs

to be adjusted as well

and maybe I can set

mean with

mean with something

okay I can set this um you can set this

later I know how to spend too much time

on the CSS

and this is the place which probably

needs to have a flex one

see

let's give Flex

one right here and remove from here

to have a look in the browser and yes

this is what we needed

okay so now this this one

where's that so the whole div the whole

right side so this div element the right

div has the flex one and stretches fully

and then we have the uh two divs with

justify between right here and justify

between right here okay this gives us

exactly what we want

okay so we have implemented adding item

into the cart

uh updating the quantity

removing item into the cart and I think

we haven't implemented the

total quantity on the card so

basically

we created a getter car total and this

is something what we need to use right

here so

maybe I will use x text right here

and use cart total and

let's have a look

by the way this is not outputted why

X if

let's collapse this we have the if

card items length

and this one is inside if

that should work

isn't it

okay why this is not displayed let's

observe this once again so let me

inspect and see

Where is the

so we have a template

okay this is something we don't

need

to see if cart items length

this is displayed those items are

displayed

and this is not displayed to have any

error in the console

no we don't

then why this is not displayed

I'm on a card page

okay let's delete the

whole template

we have data then we have cart item

do we need to clear the cache level

cache maybe let's remove this

okay here's the here's the subtotal

strange so we say that I think the

reason

might be overflow hidden

so in fact it might be

displayed

no don't be honest I don't see that

by the way let's give this one

key

product dot ID

and let's remove this again

and now this is displayed

this is outside of the if statement if

Court items length

is it so

no

it is actually in sight

also the button is not visible

PHP artisan

cash

clear

view clear

why I don't see the button

I know I'm making some stupid mistake

right here

and that's why the button is not

displayed which is

very annoying

when you make such mistakes

okay I think the reason might be that

inside the template it only displays the

first element

so if I wrap this in a div

and format this

let's save this and have a look in the

browser

here it goes

it was it

okay

um now right here we are outputting the

car total let's actually use the back

ticks and usually use the taller sign

and now we have the total price

formatted nicely so when you increase

the number of items in the card this one

also changes and this is what we wanted

and that happens through alpine.js

basically this re-evaluates and finally

we have the updated price

okay now I think what we need to do is

first test

adding items into the cart when the user

is authorized and also implement the

functionality when user logs in or

registers and then logs in

to move the items from the cookies into

the database

okay so I'm going to log in

and let's log in using zura and click

login

okay it redirects to dashboard and the

dashboard doesn't exist so we have to

find the root service provider and

change the home into slash

reload

okay now I'm authorized and my number of

items in the cart basically is zero

that's because nothing was moved in the

cart so I'm going to open

authenticated session controller

and right here in the store after the

session regenerate basically I'm going

to call cart helper move cart items into

DB and I'm going to do the same thing

in the registered user controller

after store after out logging

okay so we save this and now I'm going

to log out

now let's log in when I log out you see

I have something in the cookie so it

shows two right here

now I

log in

and now I have two items in the cart the

advantage of these is that it saves

those cart items in the database and if

I log in from another device I will have

those two items as well in my cart

okay

now let's say that I have those two

items the chair and the PlayStation in

the cart so I log out

I go in the cart I remove all those

items

and I see this text also which is nice

and I'm going to add

um Mouse in the cart okay I have one

Mouse in the card and two

items for the authorized users now I log

in and they should be merged and I

should have three items in the cart

okay and look at this

this is this is Handy and very important

feature by the way if you're building a

production ready e-commerce application

user experience is the most important

thing you have to give to to your users

all right and maybe we need to test the

registration I have a user John which

doesn't have email verified so as soon

as the user logs in we get the following

uh message even if I try to open the

cart or basically any other page it asks

me to verify my email

address so if I go right here and let's

actually resend the verification email

and here it comes I click verify email

address and now I am probably authorized

and verified and I am able to see all

the pages I need now let's log out

I have Mouse in the card and I'm gonna

register with another user Mary Mary it

example.com

[Music]

let's provide the password

okay and now pay attention Okay I have

one item in the cart the items from

cookie was moved into the database for

recently I did user Mary and I guess

Mary has id4 and I of course get the

verification email right here as well as

soon as I verify my email address I will

be able to access everything so I think

this finalizes the

cart management

no we actually missed one important

thing adding items into the cart from

the product inner page this is something

we haven't done

okay whenever I click this add to cart

button it should add the item into the

cart and I should also be able to change

the quantity and click it to cart yeah

this is something we haven't done

okay let's open resources views

product in View and right here

okay what do we have here let's search

for Aid to cart and on this button

we have the set to cards it accepts an

ID

let's remove this ID

and it takes the value from the quantity

from this input which has a reference

quantity L I think this is good so this

one takes the value and sends it to the

backend so let's save this and test this

go in the network

clear we have this on six and click it

to cart

maybe we need to reload the page first

and click add to cart and it doesn't

work and I think I know why

because we don't have the product

component in the app.js

this is a this is a data and this data

is not added on product

so maybe

what do we have right here this is a

gallery this is image gallery

and this one can be product section but

I'm going to actually create X data

right here

and I'm going to call product

item

and we're going to accept product right

here so right here basically I'm going

to run

blade template expressions and thing

called Json encode

uh we need to pass right here an array

and then

let's open

cart index

and I'm going to copy the following

or maybe we need to open product slash

index blade PHP and we copy the

following code we need to add to cart as

well so and go in the view and paste

that

now let's

format this

okay

here it goes so now we have product data

and whenever

we call into cart we should call the up

JSA to cart let's refresh the page

clearing Network and click it to card

for five items

okay it made request and now we have six

right here

okay this is as easy as like that

so we have the collapse working

we have we can set this into okay we

need to give this one some minimum value

minimum equals one

reload the page you can't go below one

so click and now it's seven now let's

say three

there are 10. we click on the card we

see nine items right here we reduce the

quantity

and I think we finished the cart

management so we have implemented the

adding items into the card from the list

as well as from the inner page we show

the notification we implemented the

moving items from the cart into the

database if the user is authorized we

haven't tested this probably but if the

user is authorized and we click

it took art it should create records in

the database immediately how many

records we have in the database we have

totally

uh which user I am I am the second user

I guess and there are four items four

rows

uh in the database let's create so let's

add

the laptop into the card so click right

here

and it doesn't work here we found the

bug a user ID to fillable property to

allow Mass assignment I think yeah we

missed that okay now let's open cart

item

you need to test your code carefully so

we put fillable right here and what

attributes do we need

we will need

user ID we will need

product ID

we will need what else do we need

user ID product ID and quantity I guess

we don't need

oh we don't need anything else

in the quantity

and by the way the created it and

updated it is not populated so we have

to fix this one as well so let's save

this and first

trigger it to cart again okay now this

was added in the cart and we should see

one more record in the database for the

second user product id1 and now we have

created that and updated it

in this section we have implemented the

profile details update as well as the

password update and the HTML right here

the template basically is taken again

from the following theme so right here

we have

profile HTML so that was grabbed and

integrated into larval and let's

understand how this process was actually

done and we have right here this

checkbox as well so whenever you modify

something in the billing address and you

hit the checkbox it's going to copy that

into shipping address as well so let's

Now understand how this was actually

made so we first created the immigration

and that migration basically changed

these states which was a text column

into a Json column because inside the

stage we're going to basically save

um array of states for a specific

country okay states are relevant for not

for all countries like you for USA it's

really

um very relevant and that was done like

this so we have also created country

Cedar inside there we just

um save in the database few countries

and for USA we save um like four how

many states we have we have five states

for USA and we have four countries so

these are just for the implementation

purposes uh I didn't spend time to save

all the countries and all the states and

we have the database leader inside which

we registered our country Cedar and the

most interesting part starts in the in

the controller basically so in the

profile controller so we basically

render The View for the for the customer

customer details we get the customer

addresses uh and if the addresses

doesn't exist they are created the first

time and we have right here store method

which basically runs all the checks if

the shipping address exists it's going

to run an update if not then it's going

to be created now we have a password

update right here as well and we have

created password update request with the

validation rules as well as the profile

update request with all the fields and

validation rules and the most

interesting and tricky part is the

component's input that is that input

became a very reusable input it has a

support for select right there as well

which accepts

uh which accepts

options and renders basically like this

and it has also validation support and

few other good things have been added

inside this input component and of

course the view blade itself which as I

mentioned is just copied and pasted uh

from this theme and we just tweaked a

little bit so we are using the alpine.js

to display the flash messages so as a

result when we click on this update

range here we're going to see these nice

um with progress bar message success

message box that the profile was

successfully updated and this is done

through this alpine.js flash messages

and it's going to time out of after this

amount of time we are using a

combination of alpine.js and laravel

right here to achieve the best possible

result and the result is actually

achieved so if I just remove the one

field that's going to make the field

required and this is done through both

as I mentioned laravel and alpine.js

okay and just like this we have

implemented the profile update as well

as well as the password update and now

let's start working on the stripe

checkout process and I'm offering you

the full process of the stripe checkout

which is I think about two hours or even

maybe more the full process how to

correctly correctly Implement stripe

online payments stripe checkout online

payments in your project and how to

configure web hooks as well so enjoy

this particular section now let's start

working on payments and we're going to

do payments using stripe

make sure to have an account on stripe

first I already created an account the

process is very straightforward like you

we can Google stripe uh sign up it will

give you registration page you just need

to fill up the form and as soon as you

fill up the form you will be redirected

and you will have test mode enabled okay

when the test mode is enabled you can

actually Implement your functionality

use the test publishable keys and secret

keys but as soon as you want to go to

live you have to provide bunch of

information to stripe and here are like

five step activation process which needs

to be completed to get the permission to

go live basically but as far as we are

in the test mode we should be fine to

implement stripe

all right

I'm going to look for

PHP stripe GitHub package

I believe this is the one let's open the

second one as well I think the second

one is for reals is

okay and let's move down below you know

let me actually log into change the

theme into dark mode

all right okay let's first install the

stripe package so I'm gonna get this and

open my terminal and paste this

then I think the readme doesn't describe

every step every step that is necessary

so of course tripe is a huge service and

they have a lot of payment uh a lot of

different types of payments like

recurring payments one-time payments and

few others of course subscription type

and so on so what we're going to look

for is a stripe let's first open stripe

documentation

and we are interested in to accept

accept a one-time payment

um accept a payment okay let's find

these

I went dark theme

think I don't hacked okay I think this

is what we want so we have to set up the

stripe

um this is what we have already done

then we have to redirect customer to the

stripe checkout page and we have to

create a button actually we do have the

button if we go in the home page and we

add a few items in the cart actually I I

already have two items in the cart so I

click this procedure to check out

whenever I click this we need to submit

to our laravel root and basically

generate uh stripe checkout session

let's scroll down below and we will find

more examples

I think this example uses the slim

framework which we don't need however

this is what we need Okay so this

generates a session

and then we have the session URL okay

and we can redirect user to the session

URL let me actually grab this

and let's open also

let's open cart index play this is the

cart page and here we have the proceed

to checkout so I'm going to generate

form with action

root will be cart checkout we're going

to create the root and then we're going

to have method to be post

okay we will need

um csrf

and let's move this up

Oops I did something wrong

uh I I have something copied and I

didn't want to cut these I didn't want

to lose

the copied script but I think I have

already lost that so that's fine now

let's open a web PHP

and let's put this right here user needs

to be authorized so post request needs

to come on cart checkout

uh we're gonna use cart controller

class checkout oops checkout

will be the method and let's give this

name cart dot checkout

awesome now let's open card controller

scroll down below

and create public function

checkout we're going to accept request

of course right here

and let me now copy

um what do we need to copy so first we

have to set this set API key and that's

going to be the secret key so I'm going

to put this we have to put the secret

key in the enf of course so let's open

enf

and and let's look for secrets

let's remove this

AWS Pusher stripe secret key

okay so we have some secret keys

uh which is fine but I think mine will

be different because I I haven't set

this secret Keys probably that came out

of the box

okay so let's search for API

or I think I have it right here for

developers okay this is the publishable

key and this is the secret key so I'm

going to click the secret key

and I'm going to copy this and then I'm

going to put this right here

okay I think this is mine I I think I

have said this

um maybe before when I was actually

experimenting

okay now I have to copy the uh

publishable key as well and I'm going to

put this right here as well all right so

we have them now let me take the stripe

secret key in the card controller and

replace this with the

get

EnV

stripe secret key okay so now we have

that let's open now documentation

and we have to take and create the

session and then redirect user to the

specified

session ID okay so what line items we

have to pass the line items are

basically whatever we have right now in

the cart okay because we are on the cart

page we click proceed to checkout and we

have to be redirected to the stripe

checkout page and we have to take those

line items and pass it to stripe

okay so we have

um helper I think it's called cart

helper

uh cart

uh get cart items we have those

cart items

and let me actually die in dump

cart items

okay let's reload the page

let's click proceed to check out and we

see two card items right here and we

have product ID in quantity and I think

we don't have anything else however we

want the whole product information

so maybe we need to get the get the IDS

and then make a

make a keyword in the database to get

the products I think I have done this

above

I think I'm sure I have done this

uh this is not add probably index yeah

we get the cart items then we get the

IDS then we cure it to get the products

and then we have the cart items as well

which is indexed by product ID

okay

I can copy this

and this will give me the products

let's go down below

and let's put this right here okay so

now I have products and let me down

these products

let's reload the page

here we go I have two

um two products and let's go in the

where are the attributes here it is okay

and we have everything what we need and

let's now create line items array so I'm

going to create line items empty array

then I'm going to iterate over my

products and inside each line item I'm

going to push

um the following object

okay let's remove tie and dump and we

will also need

cart items to be indexed by a product ID

because we're going to use that for

quantity so I'm going to get this

actually you know what

now I see that I have code duplication

okay

so whenever I put this now I have these

four lines duplicated in the first

method and right here as well so I'm

going to extract this into a separate

method and I'm going to call this get

uh get products

um

kit products and cart items just like

this

okay I'm going to extract this

okay it found out that there was a

second occurrence

um with the same code and I'm going to

replace this one as well however right

here I need cart items as well so this

one probably returns products but I'm

gonna return an area where we have

products and cart items

okay

I think a little bit formatting is

necessary okay let's remove this

now we have products and cart items and

I'm using this right here and let's call

list and take out products and cut items

from here

awesome let's move up and modify this

part as well so we get list

and cart items okay I don't like code

duplication okay perfect let's actually

render the page to make sure that

rendering works fine right here I mean

it should be just cart page

okay here are mark my cart items which

is fine now let's scroll down below

uh right here

and now I'm going to set the currency to

be USD because I I have only USD uh

currency I don't have like anything else

well then we have to specify uh specify

line items right here

we have the product data and we can

specify right here name

to be

product

title or name oh it's called

um yeah tight or a title and we have

unit amount which is

product price

so we have product price I'm recording

this tutorial like on weekends because I

don't have time

um

for like every every day and then it

keeps forgetting me how my schema looks

like so apologies for this

and then cart item from the cart items

for the given product ID we have to take

quantity

now it's going to be an array so we have

to take quantity with the area notation

okay we have cart items let's actually

die in down card items I like to be sure

that everything is okay

say we have two items we have price

okay we have quantity

perfect let's actually test one more

thing I'm going to increase the quantity

and then proceed to check out

now let's see the first one has quantity

four all right so far so good

um we can we need to redirect user to

the checkout page and we can actually do

this

um let's

return redirect

uh we have to specify

huh

we have to specify right here probably

session

URL

and let's see let's reload the page

invalid integer

okay

it expects the unit amount

unit amount of integer okay what is the

unit amount I I think that should be

price right

is there any explanation about the unit

amount

same Tunes unit amount but that accepts

unit amount decimal a high C so we have

unit amount decimal as well

like I found this right here somewhere

you need to mount is an integer

but we have unit amount there there

should be a unit amount decimal let's

try if it doesn't exist we'll find

something

okay here we go so we see

this right payment page

um

we have this element as quantity four

and it has price for each and this one

this one has

I think the prices are too small and I

think I know why because this accepts

expects

um I'll specify this unit amount this

expects incense probably

so we have to multiply whatever we have

right here we have to multiply this 100.

okay let's go back below the page

and let's click procedure checkout

yeah okay here we go that's more like it

okay I want images right here so there

must be possibility to specify image

right here so let me actually explore

this session now this one accepts line

items

uh validate problems we have an array

we have problems

this one just validates then the

problems is given into static requests

we have problems right here and the

requester request we have problems right

here request rule

um we have parents right here prepare

request okay this one just makes

requests to the API it doesn't have any

kind of a model dto type object which

would show me uh what other properties

does the products product data supports

but I guess it should support something

like image so let's try product

um how it's called product image

okay let's now go back

and click proceed to checkout

okay it

did you mean images okay probably it has

images array

and let's convert this into an array

not a bed

okay let's see

okay this one

um

it should work

let's actually get the image in open

okay maybe because this is coming from

the localhost

it simply doesn't work

okay

maybe that's the reason

um

Dell laptop let me actually get one

image from the Google to easily pass

that to stripe

not this one

thing copy image address let's open

and I'm going to put this right here

okay let's go back now

and click proceed to checkout

and here we go yeah because the image

was coming from localhost it didn't show

up but this looks this looks good and we

can make a payment and then we need to

handle the success and failure okay let

me just go back and return to the

product image this is how it should be

and we have to specify right here

success URL and cancel the URL let's

actually create

let's create

different methods I'm thinking maybe we

need to create a different controller

not the card controller but it should be

probably checkout controller inside

which we will have the checkout as well

as the success and failure let's let's

create PHP artisan make

controller

checkout controller hit enter

let's open checkout controller

let's create public function success

and we accept request

and I just want to dump whatever comes

from here

and then let's create Baylor

we accept request and let's dump request

all here as well

now let's open web of PHP and I'm going

to change yeah we have to create

probably checkout as well

check out

and let's move this

let's move this into checkout

however now we don't have these get

products and cart items because that's

that was left in the card controller so

I'm going to actually take this and move

into card helper

scroll down below

and put this right here I'm going to

change this into public and it should be

static as well

Okay so

self get cart items then array plug we

get the IDS then we make query we and we

return what we need okay let's go in the

card controller and at the top change

this into cart

get card get products and cart items and

we have to do the same thing right here

I'm using card helper get product in

cart items

all right let's again test the

card page make sure we didn't break

anything so far so good

uh card control checkout doesn't exist

that's sphere we have to change this

into checkout controller let's change

this into use

and we have card checkout and now let's

specify two more one will be

actually let's change this into

check out

like this and it's going to be check out

slash success and that's going to be

check out slash failure and let's

specify right here success and failure

as well

all right now let's go in the checkout

controller

and let's

modify this so we have to use

root but I want absolute

so I'm going to specify

where's the root name and it's going to

be check out success we don't have any

parameters so I'm going to specify empty

array then the third is whether it

should be absolute or not and I'm going

to specify true right there

and let's do the same thing for uh

failure

right here

well before I test again

uh let me die in term which is this URL

uh and what is the other URL

failure

okay

now let's go back

click proceed to checkout

okay that wasn't found let's reload the

page proceed to checkout

okay check out success not defined

okay

and it should be check out success and

it should be checkout failure and let it

be card check out no problem

okay so we have checkout success and

checkout failure this looks good now

let's go again in the checkout

controller and comment out this die and

dump

and let's have a look

okay we have to provide

uh let's click proceed to checkout and

let's actually use test card

um I'm not sure what is the

test card

okay let's check the testing section

okay I think four two four two four two

is the test card let's specify it

okay

I think this anything in the future will

make sense

and save my info okay I don't want this

let's click pay

I have to specify

email so let me write to write

example.com name on the card just Surah

let's try this click on pay okay let's

see so we see success and now the get

method is not supported for this road

support methods post that's fine that's

my mistake this should be get

all right now let's go in the cart again

whenever the user makes payment of

course the items in the cart should uh

simply like disappear and

um

yeah but but right now we haven't

finished yet

let me actually test if the payment was

made in the

in the dashboard

okay here I see and most of them are

incomplete and one of them will

succeeded I think this is the latest one

okay so far so good uh let's proceed now

I want to disable the email and

name if possible I can find all this out

later

okay

that should be in the future

okay let's specify and click pay

now let's see what information we have

in the success

okay we don't have anything what just

happened

was the payment made

okay the payment was made but we are

we are still on this page which is weird

okay let's try this once again

okay something

um something doesn't work I think the

problem is in the

success URL

let's try to access to localhost

what is the actual URL that is checkout

success

check out

success

okay and we are redirected to the

payment page again

that's my bet we have right here check

out always that should be success it

should be failure

okay it's good it's good that it was my

mistake and not something else

okay let's now access to our application

once again

and click proceed to checkout

okay how many payments we already have I

think like four

maybe three three successful recent

payments

okay let's

make payment once again

okay

now let's see

I want to see some kind of result and

the result is empty it's good that

um we got this

um

it actually called our action however we

need to make sure that the payment was

actually successfully completed

okay we need to

there must be something in the

documentation about this all right let's

start from the top

okay we have implemented this

this is fine then we redirect to this

page

okay

so far it's good

show success page

let's go on the server side

okay this is for two-factor

Authentication

this is something which fails

create production

prices up front this is something we are

not interested we don't want our

products to be sent to the stripe up

front fine we don't own existing

customers to be there or anything like

this

and we don't also have discounts and

taxes

however what I'm interested in validate

whether the payment was successfully

completed or not like it was redirected

to the checkout success but I don't know

actually whether someone else redirected

this here or striped it there so

basically we have to validate

the

transaction

in the stripe all right let's go in the

third section again and we must have

something okay so here we have the show

success page it's important for your

customer to see a success page after

they success I'm in the payment form

um Host this success page on your site

okay that's clear but we want to

validate next to the checkout session

creation endpoint to use the new page

okay this is our success URL if you want

to customize your success page read the

custom success page okay let's have a

look

modify this and the checkout section ID

template variable I think yeah I think

that that's what I was looking for so we

basically need to put a session ID in

the success URL and on the success page

itself

uh right here we need to get that

session ID and retrieve this session

from the stripe API okay and then from

the session we can read through the

customer and we can show things for your

order John Smith however we don't have

information about the customer because

we we haven't don't have customers and

products pre-added inside stripe so we

just need to validate if the session is

actually valid or not and the session is

a random random ID so

like this is what we want to do all

right now let's go in the PHP storm

let's go in the checkout and I want to

print

um session ID

uh by the way should be down below now

let's open our cart page and click

proceed to checkout

and this is our session ID this is

something which is random and no one can

guess this so we have to provide

parameter right here session ID let's

actually go to the web and specify right

here uh session ID

all right and then we have to specify

right here session ID that's going to be

that's going to be what that's going to

be something which is mentioned

right here

okay check out session ID

check out session ID let's copy this I

think we can specify this using question

mark as well

uh if we just remove these

if we just remove these

well I was thinking yeah like we can do

it in both ways like if we leave this

parameter right here and then I will

specify this is the session ID and then

as we can see if we just die and dump

this access URL

we will see how the URL looks like let's

reload the page

okay the parameter wasn't replaced that

is something I hoped it would be

replaced but the easy solution will be

to just remove this from here

and at the end we just concatenate

session ID

equals to till this

whatever

is this

okay now let's let's comment this time

dump

and we have the session ID

and let's go in the

let's go in the success and let's get

session

ID from here let's actually

scroll down below find this portion so

I'm going to get this

paste it right here

and from request we get the session

underscore ID let's change this into

underscore ID

and we have a session okay retrieved

from stripe and I'm going to die and

down

session

and let's have a look

so let's reload the page

we must be redirected to the stripe

we are not redirected because we didn't

dump something

session ID

all right

let's continue

all right on specifying

example.com

let's click on pay

all right now what do we have so we have

a session ID no API key provided that's

absolutely correct so we have to

we have to take this

and put it right here as well

and just reload it and here we have a

session okay if we try to get the

customer

this is just the customer identifier

okay on the demo right here it tries to

get the customer name but I think we

don't have a customer name at least I

haven't tried so let's try to get this

session and customer so we just reload

the page

and now let's scroll down below so we

have the customer and what is the name

of the customer name is test okay with

whatever I provided that's fine so we

can display success message to test that

hey your payment was successfully

completed and we need to remove the

items from the cart as well okay let's

now create success page we're going to

go in the resources views

Let's find let's create new folder

called

check out

and inside there I'm going to create new

success blade PHP

and we will need

failure as well

Taylor played PHP okay let's include x

app layout

or is it called Excel yeah it's it's

called the xap layout and let's just

write a simple message right here with

some Talent CSS classes BG

um PG Emerald 500 padding Y2 padding X3

takes white rounded

and let's put right here message

uh thanks

for your or your order has been

completed

Mr or Mrs someone let's just write name

we have customer

name

comma your order has been completed

uh by the way we did this in the failure

we should have done this in the success

for the failure

we should give some a message to the

user let's actually change this into BG

red 500

and

Baylor

and let's remove this style and dump

and we just return View

checkout

success and we pass

we pass customer

so far so good we'll reload the page

and we see test your order has been

completed test obviously is the customer

name let's go and give this one

with of

like 400 pixel

and let's give it also margin X Auto

so we save this put load the page

okay here we have your order has been

completed

and the only thing which is remained

right here in the checkout we have to

clear cart and we have to make order as

well whenever the session exists

okay let's try to provide in invalid

session ID let's put additional one at

the end hit the enter

okay now we have problem invalid string

must be at most

66 characters okay

uh let's just delete the last B in type

c let's hit the enter

that that error comes from

stripe no such checkout session which is

valid okay right now we try to the the

error basically was produced from this

line session let's scroll down below we

need to find the place where the error

came from because we have to put this in

the try catch

let's search for checkout current

checkout

controller here we have this

okay yeah from there comes from this

line so we basically put this in the try

catch

we try to get the session

um after this we try to get the customer

if for some reason they didn't work

uh we get the exception right here

and we know that the uh session ID is

not valid

and that's it

okay

how every everything is successfully we

need to render let's just render it

properly

and right here we need to render failure

and we have to render failure also if

the stripe return with a failure

obviously if the session ID is wrong

someone else is accessing it's going to

come right here and the failure and if

inside the failure we show uh like your

payment was not successful

okay this is the message we can show but

we aren't able to test the case when the

session ID

um comes right here but the session

actually wasn't fetched from the stripe

or or something like this okay just in

case this happens let's put right here

if session does not exist for some

reason then we return

failure

okay we return with failure and

otherwise if the session exists we get

the customer and we Rin render success

success page

okay so right here we get the customer

so we need to do a few things we have to

create an order let's go in the

localhost and we have to find

orders

okay right here we need to make requests

when the

payment was successfully done we have

the total price we have the status

and we have also payments inside the

payment we have the order ID amount

status and type and probably we should

save session ID as well

inside the payments so I'm going to

create the payment basically is the

transaction which happened in stripe so

I'm going to create new migration to add

the session ID to payment so PHP artisan

make migration add session ID to

payments

table

now let's open add session ID to

payments table and right here we're

going to create

this we have to create string not this

sorry but the table

treeing

let's make it

oh let's give it name session ID

and let's give it length 255. okay and

it basically must not be null

or it should be now let me think so the

payment should be made whenever success

page happens whenever stripe accesses to

the success URL in this case if we make

um

if we make a payment we have to provide

session ID otherwise it's it's doesn't

make any sense

so but if we make the session if we

insert the session in the database right

here

on the checkout page

we can get decision ID from here and

insert

into the database this is also something

good to do I think this is this is uh

what we need to do okay actually we need

to make an order right here as well so

we make order right here you make a

payment right here order will have an

status unpaid payment will be will have

status of pending and then whenever on

success page we get the session ID

now let's extract this into a variable

called session

session ID we get this we make cure in

the database

so we need to make sure that the not

only session ID is a valid session ID

coming to us but this session also

exists in our database created

previously somewhere right here okay if

we make sure that this is the case then

we proceed so let's create order data

and

what information do we need inside the

order we need the let's open first order

we have the total price and Status like

nothing nothing that important

and we need the total total price of the

order

it's going to be Zero by default so

right here we get the product price

so let me sum up to

uh total price plus equals product price

and the total price comes

right here

we have to specify status as well

for the statuses let's create an enum

so let's go in the app

enums and I'm going to create let me

actually duplicate address type that's

much easier order oops order status

let's hit the enter

um this is going to be

order status

and I think I have a typo in the address

type

yes I do

okay inside the order status we have

unpaid

unpaid and

we have paid

orders either on paid or paid of course

we can have like more granular statuses

like pending and processing and so on

and maybe we need that the order

needs to have

let's

write paid maybe we need completed or

complete completed is better

uh complete so whenever user makes

payment

the user will turn into paid okay and

and then the vendor the administrator of

the e-commerce website can take care of

the shipping which is not handled in in

the in our application at the moment and

shipping will be handled outside of the

application and when this happens then

simply we will

um

I just I just noticed that

and then I just noticed that I have the

editor zoomed out

and that distracted me

okay let me actually zoom zoom in

so basically uh when the admin of the

website will handle the shipping the

user the admin can turn the status into

completed and just like this we we're

gonna have the completed orders

okay so this can be just unpaid or draft

both of them will be uh the same and

let's create another enum which will be

payment status

let's change this into payment status

and the payment will be unpaid

or let's call it pending

and we're going to have

Aid

and failed

all right

so now let's go in the HTTP controllers

checkout controller and we have to take

here creating orders so we're gonna take

order status

and it's going to be unpaid

okay so what information do we have

total price status like created at

and updated that will be managed

automatically but we can specify created

by an updated buy which will be in any

case authorized user so we'll specify

created by

it's going to be user but we don't have

the user right so let's get the user

actually let me take this from

from card controller or from a profile

controller so let me copy this

and put this right here so now we have

the user ID let's duplicate this for

updated by

and now let's open order model

order PHP and let's add right here

fillable to be status

we have total price we have created it

and updated it

okay I think we created immigration and

we wrote but we have not actually

finalized it

the session ID this can be nullable by

the way so I'll specify we decided that

it can be nullable and in the down let's

just drop the column

drop column session

ID

all right

so

let's let's have a look again so now we

have the order data and we are going to

create order equals order

create we don't need to validate the

data because we know what we are

inserting right we have the prices and

we have the unpaid and IDs okay we don't

need to run any kind of validation in

this case and we're going to have order

and I'm going to Simply vote down let me

actually hit the dump and I'm going to

power down the order then I'm going to

create the payment data

and for the payments

we're going to have

oops order ID amount

and Status the amount will be the same

as the total price

so let's specify first let's specify

order ID

order ID that's going to be just created

order ID then we have to specify amount

that's going to be total price

we're going to have status

which will be

payment status pending

and we have type as well by the way is

the type required

no no yeah the type is required but

in this case

um like the payment type can be uh

credit card or cash or Checker Etc so I

think in this case we can just always

specify a credit card

and

we have created it

um no created by and create that will be

managed automatically so we have to

specify created by let me actually take

this code

and paste this right here and we have

the payment data and let's create now

payment

create

with payment data and let's now dump

payment as well and maybe exit right

here

okay

it's getting interesting

now let's go in the cart enter

okay and click proceed to checkout

okay

we have

order ID to okay we didn't I think the

order was created we can check this

yeah the order was created we have the

total price I'm not sure if the price is

correct by the way

uh created by updated by

is not presented

not sure why

let me actually dump the

user ID

the user must exist

I was thinking maybe I was doing

something wrong but the user must exist

so you have to have created by an

updated Buy

however I have specified something else

right here

okay

now let's open payment model

payment.php

okay let's open from here

and let's add a fillable to be

order ID

potatoes

um what else type

and created by and updated by

all right now let's reload the page

and now let's have a look among doesn't

have a default value into payments okay

we haven't specified amount here

let's reload once again

and we have something looking successful

int 8. 8 I guess is the authorized user

ID

let's reload the page

okay now we have the user ID for orders

and we have one payment this is looking

good so we have three orders because for

two of them it was simply failed we can

delete the first and second

even we can delete this

but we have to delete first payment I'm

curious why amount is five eight seven

so

I think I know I think I know

because I didn't multiply this on

quantity right

exactly so right here I have to multiply

this on quantity so let me actually

extract this into a variable called

quantity

and then move this up and use quantity

right here so I save this

and

I reload the page

all right now let's have a look so we

have the total amount inside payments we

have the order ID we have the payments

type and everything that is necessary

however we don't have session ID because

we haven't run migration so PHP artisan

make uh no me great

okay now let's see what happens

there's no column with Name ID on table

customers what

rename customer ID column

okay I think while I was testing uh I

broke something that will not be a

problem on your

on your case

so I think I have some migrations down

and it is not marked in the table

so let's check the migrations

the last migration

rename customer ID into user ID

let's see

let's see

database migrations

okay that should be the name

that should be the name uh that's gonna

that's not going to be a problem on your

uh machine because like uh I was first

preparing and doing the project and then

recording and I gave it slightly

different name while I was recording and

I guess that is the problem so I will

simply take the name of this migration

and put this

right here

no this is something wrong

let's go in the migrations

at least one the last one

rename customer ID into user ID is what

is in the database however we just have

rename customer ID column let's go

and change countries states column into

Json this is something which needs to be

run right

let's see but again I think that is

already run

and simply we have to add a new record

let's try to migrate

change country State cone into Json okay

so far it worked so I think there is no

problem let's go in the countries again

that was problem on my computer there's

not going to be a problem on yours

however if we open now payments we

should see session ID right here okay

this is something we need to also

consider

right here when creating let me remove

the user ID let's remove order and let's

specify right here session ID

that's going to be session ID and let's

add session ID into fillable as well

session ID

all right

let's remove this and now I have session

already created okay I have a payment

and Order already created so let's

scroll down below right here

and we have to now grab the payment okay

payment

equals payment

let's get

query

where

session ID equals to session ID and

we're gonna get one

okay this is going to be the payment

let's actually do this

we get this session ID we get this

session

okay if the session doesn't exist that's

fine

then we get the payment

okay and then we can do one more check

if the payment doesn't exist

if the payment doesn't exist or if the

payment

uh status

uh does not equal to payment status

pending dot value not dot but value

then we return to checkout failure

otherwise we give the customer

and we show the success page as well as

we have to update the payment

and the order

and we have to mark them as paid like

payment

status

or still like this payment status equals

payment status

uh pale paid

uh

value I think the value is not necessary

let's see without the value

and what else you know we have we can

what else do we need

I think nothing like we have updated by

but that's going to be the same one

status we just need to change the status

okay we change the status then on

payment we call update

and we have to do the same thing for

order so we get the order from

payment actually we need to set up the

relation so let's open

payment

and now let's create public function

order

which should return as one

return lease as one

order

and I think that's it so the payment has

order ID so that should have a correct

reference to the order and that should

return order

let's get the order

and let's

let's far dump

order

um let me actually dump this

I I need the pre-tags as well so I have

the order now I'm going to change the

order

status

to be order status

paid

and

what else do we need to update

we have the status to be paid

and nothing else so we change the status

then on order we call Save not save it

update

and just like this

we finish the success page so we get the

session ID we make here in the stripe we

make sure that the session exists if

that doesn't exist we return failure

then we cure a payment from our database

and we can put this status by the way

here

the session ID

needs to be these in the status

should be equal pending

right so payment status

pending

if the payment doesn't exist with the

following criterias then we again return

with failure if the payment exists then

we mark it as paid in update and we take

the order of this payment and Market as

paid and update

perfect

all right now let's test this

let's reload the page

let's provide

correct information

let's write John Smith

and let's click pay now let's see

your payment was not successful and

there must be reason for that

okay either payment doesn't exist didn't

exist or sessions didn't exist

let's start

typing everything let's start let's type

print session

and let's print

payment

s also

um throw

exception

let's reload the page

okay

collection update does not exist

let's look for checkout controller

and payment update didn't work because

right here I called get

okay I need first

I think Laro is right I hear another

let's reload the page

and now let's see

orders payment ID okay that's

orders payment ID and we're close Okay

that's something

which I didn't expect so payment

has one order

a single payment cannot have multiple

orders right so basically payment should

have

this has one order

strange

so I have to specify right here foreign

key will be ID and the local key will be

order ID if I specify this it's going to

work

but yeah I didn't expect that

um

I'm going to find out more about this

but let's reload the page

okay we don't have any error that's good

so we have the session

scroll down below

uh we don't have payment however

and then we have a problem now why don't

we have payment

let's click on payments

and we have the session ID right

and yeah this status is already paid

that is the problem

which is logical because we had an error

right here so let me update this and

change into

unpaid

and click go now let's

let's go in the checkout controller and

remove our dump statements

I'm going to leave order let's reload

the page

payment wasn't successful again we have

problem let's undo

and reload

what is the payment status

it should be pending

ending

yeah so like we are debugging and we're

testing and we're making sure that it

doesn't break so we don't have a

security hole here

now what happens so we have session and

we have everything in John Smith your

order has been completed

this is the most satisfying message

um so far

so let's remove this

let's save and if we just reload the

payment wasn't successful obviously

because our session ID was already used

and payment was already marked as

completed

let's go in the

failure blade and give it also width

just like we gave to success

so that we show this in the center

we reload

okay so far so good

of course the design of this accessor

failure message can be improved

um but yeah I'm Gonna Leave This as this

and now I'm going to do final thing in

the checkout process which basically

will remove the items from cart

so we can leave this throw no we

shouldn't leave that

so probably in the checkout failure I'm

going to pass

message

and message in this case will be e and

get message

and we need to accept the message in

failure

let's put this in the H1

and then we have a paragraph inside

which we output message

If the message exists we output that

otherwise we output empty string

and from the other failures like we can

specify

message

payment

does not exist

and right here we can

specify message

um invalid session

ID

okay fine

now let's delete the items from the cart

so I think the cart

has

remove

D item from the card let's open cart

controller and remember how we do remove

now we do remove for a single item in

this case we have to remove items

completely from the cart and if the

checkout happens we know that they are

the cart items are definitely in the

database not in the cookie or somewhere

else so why don't we simply run

um

delete

on cart

item delete

and we have to specify I think uh user

ID user ID

not sure if I'm doing correct so let me

actually search for this laravel

bulk delete

I want bulk delete

something find and delete something find

and delete

is that correct

find each delete

the question I think

the question is slightly different

probably the user probably wants to

trigger the events as well

I just want bulk delete I don't care

events so let me try uh cart item find

and then delete

so let's run

where's the find let me actually copy

find and delete so let's run query

do we have find here

bind specify a user ID corresponds to

current user ID do we have the user I

think we don't have the user so I'm let

me actually get the user from request

and put this right here

and then call delete

okay let's see if this works so we have

file items in the cart

then proceed to check out

provide

email

John Smith

and let's save this

so you may info I have to provide my

phone number

okay let me make sure that this

now let's see

your payment wasn't successful method

okay delete collection delete does not

exist

okay

so let's go back and find another

another example

something find

and delete

okay this one gives you

an error

this one looks

like correct

product Destroyer okay I it's not a

problem I can iterate over my products

and just delete them

if there is

I don't want to just lose

um much time on this I'm going to go

back and then find out and fix that

seems like we're in should work

let me actually just search for into

laravel documentation

um

eloquent

delete

let's look for

delete

ing modals

don't we have like bulk delete

help

okay fight weird delete that should work

where

delete

now let's

I think

I think it's not going to work because

the payment would be marked as paid so

let's actually change the last payment

into pending

and now let's reload the page

the order has been completed and I don't

have items in the cart

congratulate me

or I will congratulate you so we have

successfully implemented a now checkout

process the whole process I wasn't

actually prepared for this process you

probably noticed that now I just had a

very very minimalistic uh research where

was the stripe documentation and things

like that

so yeah we we made it so now we have

order

in the orders we have actually few

orders two of them are paid and of

course in my account we have the my

profile and my orders page and the next

step will be to have my orders page

inside which we will see what items we

have purchased in this order as well as

see whether the order is paid or not

even if we just add items into the cart

and go to the stripe page this is the

interesting thing go in the stripe

payment page and then I close this or

just cancel or do anything else the

order is made and the order is unpaid

and that will now we have how many one

two three four we have four orders I

reload and we have now unpaid one more

order and this will show up in our my

orders page for sure and we can we can

probably implement to pay it later

okay we can start working on my orders I

think

now let's create new route for orders

page

I'm going to Define right here root

get

slash orders

and let's consider there is order

controller for this

maybe you can create controller first

PHP artisan

make controller order controller

okay controller

okay let's hit the enter and now let's

use order controller class and the

method should be probable index

then we have a name orders dot index

okay we we might have one more

URL is going to be orders view with the

order specified order let's replace the

qualifier with an import

in in this case that's going to be View

okay we have the in we have the roots

ready now let's go in the order

controller

and let's define

index

we get request

and we're going to make query into

orders so orders

equals order

uh query

well we have to specify where

the current user I think I have copied

somewhere the current user information

so I'm going to paste this right here so

Theory

where

user ID corresponds to

user ID

and I'm going to call paginate on that

returning 20 orders

and then we're going to return View

with orders

index

in posterior

orders

okay let's create now view resource

we have car check out layout product so

let's name it into singular form order

index

and we have the product so I want to

actually duplicate this product and call

this order

and then I'm going to clear up

everything inside

index

I'm going to get right here orders

and I will not clear up everything from

view as well I just duplicate because

like my PHP storm when I have scaling

increased

then the right click opens in the second

screen

the context menu basically anyway so we

have the

uh we have the view ready so in fact if

we now go and open navigation and find

orders

and change these I think we have a

second match for this and let's change

into both

now I have multi-cursor one is about

somewhere one is here root

order dot index

so we save this and reload the page

order index not defined I think we

called it orders

so let's call it order index order View

okay what just happened on the home page

homepage doesn't work

where are the

products

we have the products

what did we do

I I did what I shouldn't have done so I

modified the product index and product

View

okay so I'm going to revert this using

git

and this is what I should have modified

okay it should be

orders

and

should clear up everything right here H1

order

H1

order View

and that is H1

orders we have template for this but

let's have a look

so let's click now my orders

a known calm user ID in wear clause

I think it's called created by right so

let's open

order controller

created by is the user

okay we have orders now let me open vs

code

because we have

somewhere orders

okay and I'm going to copy now

copy this container

and put in my

order index

right here

and let's have a look in the browser

okay this is my orders

and we have

what do we have so we have the order

number

we have the date when the orders was

made we have status we have subtotal and

few actions like we have view invoice or

pay if the order is paid of course we

aren't going to show this we just have

view invoice okay let's actually try to

implement this and output actual data so

here we have TR I'm going to use PHP

no actually we can use blade why should

I use PHP for each orders is

order

and right here we have aim for each

and let's just output

view information let me actually

um

delete the

other

TRS

all of them

leave only one and it's going to have

the

root to

order Dot View we have to specify right

here order as an argument and let's

output number whatever is the order

number so order ID is the number in this

case

now let's output date

it's going to be order

created it

we're going to Output the status

order

haters

and let's output price

order

thing it's called total price

and then this is view invoice and this

is pay okay we will take care of these

buttons but let's have a look so far we

have unpaid and paid

let's

let's modify this so we have the status

and

we have to conditionally add classes

okay so right here

we are going to add if order

status

equals order

status

paid

we're going to make these let's move

this down we're going to make the screen

um PG

okay I think

we have this like green color or it was

called Emerald

where was that

uh let's search for paid

here it is PG Emerald 500. okay let's

give it PG Emerald 500

if the order is paid otherwise we don't

give anything

okay but we output the order status for

sure

uh no let's see

let's remove this PG Gray

we can put this in the else

okay

let's specify right here maybe value

okay if the order status equals

paid we have bgmoral 500

else we have something else well it

doesn't seem to be working let's check

this

oops that should be

that should be right here

isn't it

yes it is

okay here we go we have paid in unpaid

actually and let's try to change this

into small

yeah I think better

okay so we have the date we have the

subtotal and we have the buttons let's

disable the pay button if the order is

actually already paid

so that is the button we can completely

remove or like disable it let's actually

remove so if

uh order

status let's actually do like this so

I'm going to open order PHP and I'm

going to create public function is paid

which will return this

status if the status

equals to order status

paid

value

okay and I'm going to use right here is

paid

if the order is paid

let's do like this if the order is not

paid in this case we show

the link

and we can do something similar right

here

if the order

is paid that's much shorter let me show

um Emerald color so now we don't see the

payment button for two of those but

because those orders are not actually

paid we can actually click and pay

that's also really useful

we can implement this however

um

let's first

implement the order inner page

now let's actually implement this

now let me think

so the order needs to have its own

session ID let's check

not the order but the payment

and order has a single payment

okay like in complex applications a

single order can have multiple payments

but in our application order has a one

payment only it could be even in this

like we could even combine orders and

payments in single table that would not

be a problem however let's check

payments so we have four payments

but we have five orders

like three and four let me actually

delete three and four because I think

they don't have

yes they don't have um payments so I'm

gonna delete this fourth we only leave

five six and seven all of them have

session ID so if we go in the payments I

delete all of them and not all of them

but uh third and

with the ID

come on and fourth

okay now we have three orders two of

them is paid one of them is unpaid

however whichever is unpaid we also have

information about

uh its session ID

okay

and we can get this session from

from stripe and redirect user to the

payment page let's do this so

I'm going to open now

again checkout controller

and let's create

one more function

by the way we don't do anything in the

fail right

so let's put this right here

however the message will be

um your payment wasn't successful or

something like this okay let's give it

an empty string because we also have a

message inside the failure view itself

all right let's create

um

function called

checkout with

session

ID

we get the request

and I'm going to get this session ID

uh we're gonna get the session ID from

the URL right

so let's open web of PHP and configure

wrote for this

uh check out

but with session ID

and check out with session ID

check out

with

session should be the view name so I'm

going to get this

now let's go in the order

and we have this

payment button

however I'm going to turn this into

button

and I'm going to create form right here

with action

root

check out with session and provide right

here

session ID however I need to get the

session ID and I'm going to get this

from the order so let's open order

excuse me and I'm going to create right

here public function payment

now which is one

so order has one payment okay in in

theory it can have multiple but in our

case it has only one payment and we're

gonna return these his one

payment

Plus

okay

and right here I'm going to get order

payment

session ID

I passed the session ID

let's change the method into post

and let's give it csrf as well

and let's close

let's close the four then format the

code okay now we have this form if the

order is not paid

now let's go in the checkout controller

and we are going to get session ID right

here

session ID

that's coming from

web PHP from here we should get this

okay so now we have a session ID

and I'm going to get this session

and here is the method to get the

session

and we have to take this as well so I

copied both right now and I'm going to

paste first this and second using

multiple cursor I'm going to pass the

session ID right here

the session might even be expired

and in this case you have to generate

new session okay I'm thinking maybe

it's good idea to always generate new

session

um when you click

when you click pay

I think it's gonna be

it's going to be good in this case check

out with session I'm going to rename

this and call this checkout

checkout order

and in this case I will get

I will get the whole order

okay no need let me actually delete this

and let's change this specify order

checkout order was renamed and check out

order right here let's open

this part

and that should be changed into order

and I'm going to pass right here

order as well

okay

now

whenever it comes here I'm going to die

in damp

entire order

let's save this reload the page and

click pay

here here is the place where order comes

but what is this

okay what is this

let's go in the orders

and click on pay

and we see these which is fine

now let's go right here and find the

basically we have to copy uh the code

from checkout but maybe not just direct

the copy and paste but we have to do

something similar what we are doing in

the checkout so first we need to have

the user information and the we have to

set the API key

for stripe so we do this next we have to

take the order items by the way we don't

create order items

yes we don't do that

so we have to make records in the order

items as well so let's go in the

checkout page where we create uh orders

and payments and all of that

and let's create order items

so order items needs to be created for

sure after order is created because we

will need the order ID

and we have to create as many other

items as many products uh we have in the

cart

uh we can directly create right here

because we will need the order ID as

well so I'm going to create

uh by the way we have line items

but that's not that's not what we want

so let's create order items array

and we're going to push

inside order items

we will push the following information

uh we will push the product ID

product

ID

we're going to pass quantity

and unit price

product price

okay now let's take the order items and

after the order is created let's leave

comments also

uh create order

items

we have to iterate over our order items

and I'm going to call order

item create

and I'm going to give each order item

needs to have order ID as well

it's going to be just created order ID

and then we pass

order item

to the order item create

okay let's leave comment create

order

and

create payment

okay now we have order items we should

test this once again

now but let's now select the order items

okay I think we don't have order items

so we're going to delete everything

every order what we have

or at least unpaid order

let's actually delete all because they

need to have order items

so let's click delete

yes no first we need to delete payments

then orders

okay now let's go on the card page

we have only one let's increase the

quantity and let's add

second product

keyboard

now we have totally three items we're

going to proceed to checkout

okay we have to open order item and add

right here

billable

we need order ID

we need you need price

we need

order items

product ID and quantity product ID and

quantity

so we save this let's create by the way

here Order

return this

is one

order

Plus

not sure if this this will work without

specifying right here for in key and

anyway let's leave this

let's reload the page

I think it will create no second order

because it should have created order

previously as well this one has id8

let's check order items so we have now

two items with order right nine so I

think we can go in the payments

uh not payments but in the orders and

delete the eighth one

by the way I think everything right here

in this checkout controller whenever we

create

order and Order items and payments

should go in a single transaction

because if one of them fails all of them

should be protect

okay so now let's specify

okay your order has been completed and

now we have all the items right here

let's go and add now two more items in

the cart

Mouse and PlayStation

and I'm going to go to the checkout page

but don't pay that

not a valid URL

trench really strange

okay I think this problem is coming from

the images as I found out because we are

giving right here images from a

localhost domain and that is not

accessible by stripe we get this error

it's strange why previously we didn't

get this error previously images simply

we are not displayed but now we have

this problem so let's open and comment

up this line we don't pass images at all

and simply reload the page and have a

look

I spent quite a lot of time on finding

out what the problem was and that was

actually the problem so now let's

proceed

and let's have a look now we should see

basically right now at this moment the

order must already be created I think we

want to create unpaid order so here one

order which is order nine and I guess

this is paid or the nine is paid order

10 is unpaid actually we don't need to

like populate anything so imagine the

case that the user opened the payment

page but simply close the tab didn't do

anything okay so we have to show that

order in the let's leave this

in the my orders and here we go here we

see that okay and we have view invoice

and pay whenever we click pay now this

should trigger the same type of payment

process let's now scroll down below so

it should come right here and the same

thing should start but now let's

actually copy and paste uh some code so

we have to basically we're doing this

uh let me actually copy this part

down below and now we have order we have

to take the order items so let me create

right here line items called an empty

array then we start iterating over order

items and the order doesn't have items

so let's define it right here public

function items this

has

is many

okay we return this is

many order item

specify class

and I think we don't have to specify

anything else let's have a look at least

so we have the order items is item

inside line items we push

the same type of array we have

okay here we go and we have the item

quantity

we have item

we don't have item title but the item

every item has access to product and we

can go to the product and take the

product title so let's open order item

and just like we have has one order we

need to duplicate this and return has

one

that should go to product

Okay order item has one product

uh let's put this has one here as well

and now from the item we go to product

and the product has title

also for the price we have this price in

the

as a unit price in the order items table

so we just take unit price okay now we

have live items array and we are passing

these

into the session create

okay let's move up uh so whenever we do

this then we take the session

URL and redirect user we don't need to

do anything else right here

so we simply redirect user we already

have order the order is obviously unpaid

so we simply a redirect user to the

session URL

okay now let's reload the page let's

click on pay and let's have a look so

unknown column products order item id

this is really strange I need to find

this out so laravel

has

has many

okay let's quickly find out as many

okay post has many comments

and this assumes that the comment has

post ID

okay now how do we do this so if we go

in the order

we see that the order

has many

items

and the order item as many as order ID

okay now let's open

order item and talk about the product

has one

so it's clear for his many and I guess

um for the

let's go in the checkout for the

iterating over the order items that

should work okay we should be able to

get the items

let's now search for his one

okay as many comments know we need has

one

let's see here's one example

a latest order

that's probably coming from the

product okay let's just order and test

order

let's see in other examples

okay the throw is basically using a

junction table mean to many

relationships

uh we need this one like user user has

one phone

okay the first argument passes to his

one okay that's clear we get the phone

and it is assumed that the phone models

automatically assume that have a user ID

okay so it's it means that the phone

should have user ID

okay not

not

understood now okay not the user should

have phone ID

but if we want from phone to access to

the user

belongs to user

now inside the phone we would put

belongs to

okay this is something I was missing if

we open now order item

right here

for the order I'm going to put that

the order

belongs to the order item belongs to

order and we can leave these because I

think it will assume that the order item

should have

um order ID and we will do the same

thing it's not going to return has one

in this case

and let's put this right here

all right

so I think we can add

belongs to

to be returned from here

belongs to all right now we should be

able to get the product and now let's

have a look so we reload

and we don't have any errors it looks

like and it's going to redirect us to

stripe

okay attempt to read property title on

now okay it wasn't able to basically get

the product because right here we need

product

sorry so we reload the page

and here we go so we are on the stripe

page now let's

um if we proceed and

if we proceed and pay then we have to

handle the payment successfully now we

have the checkout success but the

checkout successes uh URL which is for

checkout for from cart but now we are

actually making payment of an existing

order

so does it actually make sense so if we

go in the checkout success

in any case

we will get the session ID okay this is

what we have to change so right here

when we generate the new session we

should take the session ID and update

the payment

okay we have order right here if we go

in the order

the order has payment

and now right here I'm going to get

order let's zoom in order payment

will have a session ID

and this session ID equals to session ID

so we update the session ID and let's

call order

payment

save that's going to update the session

ID and let's go back

and let's have a look in the orders of

the orders but in the in the payments

okay the second one has this this is

actually it's um session ID let me copy

part of it and then when I click pay

it's going to generate new session and

it should update right here so if I just

reload the page right now that should be

different yeah now my search uh copied

uh session ID is not basically found on

the page so the session ID was updated

and now whenever the redirect happens

the we can use the same uh same success

URL okay in this case in the success URL

the code will select the payment

now first it will valid validate then it

will select the payment and then goes

through the same process and update the

payment and the order

which is excellent so now if I proceed

and if I

fill up the information

oops

and click on pay

that should change the order into paid

let's let's have a look okay where your

order has been completed now if we go

into my orders both of them are paid

okay but one very important thing uh

when building a production ready online

payments system

uh and I have to reproduce this

okay now let's add one more item in the

cart go in the cart proceed to checkout

the order was created at this moment

uh let me paste this

and now

be like be careful so I click on hey

okay and as as soon as I get the green

button green the payment is done I'm

going to close the tab okay

now what happened is that the payment

was completed

but the redirect didn't work

okay and if we reload now payments page

we see that the um the order is actually

uh made and the payment is pending and

if we open now stripe dashboard

let's go under payments

and the very latest payment is this one

okay now you see we have the latest two

payments uh three seven eight six which

is the previous one in the latest one

which is succeeded 399 okay this one is

succeeded user actually paid but

mistakenly maybe close the tab or the

electricity was off and that happened

and the order if the user now this is

the this is not something else okay

let's open the our closed

Tab and now if the user goes in in my

orders we see that the order is actually

unpaid by the way the item is in the

cart which is something

we should change so let me actually

the items from the cart is deleted on

success but that's not

that's not correct so let's take the

cart item and that should be deleted as

soon as the order is created order item

is created and the payment is created we

delete the items from the cart okay this

is small Improvement but in any case

the order is unpaid even though the like

almost 400 was taken from the user's

account

so for this uh stripe has web Hooks and

the web hooks uh will be triggered from

time to time if the

a success URL didn't work

stripe will send web Hooks and you have

to provide those web hooks let's go in

the payments again in the stripe

dashboard and I'm going to go in the

let's actually look for uh web hooks

cane developer webhooks

and okay I actually I was testing and I

generated a few web hooks but on the

webhook section like we have the API

keys right here and then we have web

hooks by the way I have this webhook key

which I'm going to delete so you won't

have this so I'm going to delete that

let's confirm the password because I'm

going to generate new one so that you

can follow

okay now if you go in the webhook

section we have to add an endpoint

while we are doing this on a local

environment on localhost we can test in

local environment and we have to use the

stripe CLI for that okay but as soon as

we deploy this project on staging or on

a production environment we have to

provide right here endpoint URLs which

will be for web hooks

and we can also configure uh the events

on which the web hook should be

triggered for us

so let's click an endpoint and test in

local environment because right now we

are doing everything locally so we have

to download the CLI I'm going to click

the download CLI that will redirect us

to the get started with stripe CLI and

we have a few options right here okay so

on Windows for example we can go to the

GitHub following link on Linux uh we

need to go to the following link and

download the Target easy let's go on

Windows I'm going to open this in a new

tab and right here we have the release

and we have the zip file we have to

download the zip file I'm going to click

on the zip file

and it's going to trigger the download I

actually already have it downloaded so

now let's open this

I opened it and extracted the zip file

and inside there we have the only file

is stripe XM and that is the file that

is described CLI okay now let's go in

the browser again

and we don't need this we downloaded

okay now we need to log in into the CLI

and that is also written right here okay

so we have to do logging I'm going to

click on copy to clip actually I don't

need to click on copy to clipboard this

very small to type and even just stripe

login will not work in my case I'm going

to now bring up this CMD okay CMD or git

bash if you are going to use CMD

first you have to navigate to the folder

where this type X is located okay I'm

gonna paste this and navigate and right

now I can already use the stripe Excel

file so uh let me actually write stripe

XA login and hit the enter

okay this one will ask me please enter

to open the browser or visit the

following URL okay I'm going to Simply

click enter right here

which will start the authorization

process for the stripe CLI

and this will ask me to allow access to

my account information and look at this

so right here your peering code is exalt

amuse poised up with something and it

asks me if that's the information you

see on screen yes I allow the access

access is granted now I can close the

window and return to the CLI I already

have access to CLI so let me clear up

everything and now following the

documentation we need to forward the

events to my web hook so basically the

web hooks are triggered by stripe and

whenever we start listening to the web

Hooks and forward it to local

stripe will send it to my local server

and my local server at the moment is

running on Port 8000. so

this is an example I'm going to copy

these and now paste this right here

however the executable is called stripe

exam listen forward to localhost Port

8000 okay and I'm going to specify the

path to the web hook and we don't have

path yet let me actually move this uh in

the corner just like this and now let's

open a page to worm and create path for

that I'm going to open

um

webphp and Define the roads for the web

hook we have redirect callbacks and

let's actually create

let's create now two routes but that's

going to be post rules

one will be web hook

success

and it's going to use let's use the same

controller checkout controller

um

yeah let's feature code controller okay

and that's going to be called success

and the second one will be

failure

well basically I think we only need one

Web book okay webhook uh stripe let's go

into epic stripe and

web hook

fine so if we go in the checkout

controller we have to create this

webhook right now

however

um

let's actually do it like this I want to

just follow the error so we have the web

hook which accepts the post requests now

what now what to do now let's go in the

documentation again and on the right

side we have the sample endpoint okay

this is how webhook PHP should look like

we have to install the stripe PHP which

we already have we have to start

listening to the localhost 4242 which we

are not doing we are listening on

localhost Port 8000 and we have to

configure it like this and we can

already by the way

put this in the corner we can already

specify right here webhook slash stripe

okay this is now listening to webhooks

and it will redirect to the webhook

stripe okay but we have to trigger

webhooks as well so now

uh let's actually open another CMD

let me copy this open another CMD

and I'm going to put this in the left

corner and

we need to navigate to the folder and

now let's have a look in the

documentation again

down below we have the stripe trigger

and the event okay here we have a lot of

different types of events uh but right

now we're gonna trigger the payment

intent succeeded so I'm going to copy

this and open the second terminal and

open the right one as well and it went

up uh put this right here okay stripe

trigger but let's specify stripe XA

trigger payment intent succeeded and

whenever we hit enter ID right here

stripe will redirect the event to my

local domain let's wait

here it comes okay charge succeeded

payment intent created payment intent

succeeded okay these three events were

sent to my web hook and all of them

return with status code 419.

and that error code identifies that we

have csrf validation on post requests we

have to disable csrf basically for the

following endpoints so I'm going to open

now the file which is called app

um

where where it is

um let me actually double click C ISR if

verify CSF token that is located under

app HTTP middleware uh verify csrf token

and right here we the by default is

going to be empty and we have to specify

a web hook

slash stripe whatever whatever is the

URL okay so in the webphp we have

webhook stripe and we have to specify

right here where poke stripe as well so

we basically disable CSF validation for

this URL now if I try to trigger the

same event it's going to succeed in

return with the status quo 200.

foreign

okay what happened

it doesn't send right now

okay

here it is it was returned with 302.

let me restart this

well let's trigger once again

okay we get this with um 302 because

probably because we don't return

anything okay if we just return

response uh with empty response but the

status code is 200 and by default this

article is 200 by the way so when we

trigger this once again

and on the right side we still get

302

webhook stripe

webhook stripe let's open web PHP we

have workbook stripe which is post

why should why why are we are getting

302 we should not be getting but let's

actually keep following the instructions

and then we will identify the problem

okay on the right sides then we have to

we have to validate the signature of the

payload okay we have to read the payload

and validate that so the very first

thing what we need is to set the API key

inside the stripe so we will still need

to take this by the way the user is not

used here so we can remove that

and we set this stripe API key the very

first thing second is that whenever we

run our

um redirect let's clear up

uh it tells us what is the webhook uh

here it is uh webhook sign in secret

this is webhook signing secret so I'm

going to copy this

and basically put this somewhere in the

comment right here and then if we copy

everything from the documentation this

is the endpoint Secret by the way so

let's copy everything

and paste now this right here

and let's format the code

okay the only thing is endpoint secret

which should be this

okay we set the API key we have the

endpoint secret we read the payload uh

we read the signature header okay and

then we try to construct an event from

this payload signature header and

endpoint secret and if there is any

error we'll return either 400 or

um yeah 400 basically in different type

of errors and finally if everything is

okay we return with 200. I'm going to

actually change this with return

response

um empty string with

400 and I'm going to actually return

this with 401 and with this 402 because

that helps me to debug if there is this

error I get 401 if there is a second

there I get this 402. when I was testing

I was getting the signature verification

exception uh very often and it took me

huge time to find out the problem the

problem was that the time zone in my

computer was mixed up and

the time wasn't correct and the header

basically contains the information about

the current timestamp as well and that

needs to be validated as well so that's

why I had this big problem okay make

sure your time is correct when you are

doing this

and finally I'm going to return with

status code

at 200.

return

response 200. okay so far so good we

have everything which we need now let's

bring up the

Terminals and we are listening and now

let's trigger

okay we still get 302 which is weird we

should not be getting this

webhook stripe web hook stripe

okay

why do we get this let's actually open

uh and change this into get

and then

I will try to access this in the browser

maybe I'm going to return

everything I think I know why I think I

know why because we have this route

protected in the out and verified that

should be that should be accessible

uh from anywhere okay because the stripe

can access yeah okay I think it's very

obvious very clear we shouldn't have

this in our verified because the stripe

is accessing uh this URL and stripe

obviously is not authorized when making

requests to this okay so the web hook

needs to be accessed from anywhere

without authorization

okay so when we do this now let's have a

look

so we trigger again and now on the right

side we get 200 okay so it was

successfully completed and if we now go

in the web hook

um we actually cannot dump the

information right here and see however

we have this payment intent and that

payment intent contains uh everything

which we need so we know that payment

intent succeeded

and we can mark the uh payment is

um like the payment and order is paid

now let's go in this stripe dashboard

and go in the received events and look

at this so we see what event we received

okay we received the whole everything

right here is

um

is event

okay and we have data object look at

this we have data object and that is the

event that is the payment intent at the

moment right here so we have the ID we

have the object amount what amount

received

um

way well we have charges as well however

I'm looking for if we have anything

related to a specific session

payment intent payment method

fingerprint receipt URL

succeeded

client secrets

to the client secret I think that's not

the

it's not the session ID I want the

session ID to

identify which order should I Mark as

paid

now we are listening web Hooks and then

sending the uh intent but why don't we

listen to webhooks like this

but don't actually send it manually but

try to make a normal payment like this

one for example which is considered as

unpaid at the moment even though that

the user paid let's click pay right here

and let's provide the user information

and by the way

if we increase this

so we're going to get information

not only about like payment succeeded

but payment intent created

so whenever we open this page it's

triggered this payment intent created so

let me actually

to like

reduce it

and click on pay

now let's wait

okay right now payment succeeded I think

I I had to close the tab my mistake so

let me actually go to the cart and

proceed to checkout

and let's provide

and again when this form was opened

another payment intent created was

triggered in my opinion okay here it is

and checkout session completed

sometimes this CMD is stuck and until

you hit the enter it doesn't show

progress but here we see this payment

intent created okay now let's click on

pay and I'm going to close the tab

as soon as it turns into green okay I

close the top and we got a few

information like charge succeeded

checkout session completed and now we

should payment intent succeeded here it

is as well

and let's go in the stripe dashboard and

we see that

this is checkout session we are looking

for payment intent succeeded and if we

if we're talking about the checkout

session we get the session ID as well so

previously because we were testing some

test data the idea was obviously wrong

but if I look for

a payment intent succeeded like 31

seconds ago we should have some kind of

identifier

for the session okay customer created

this is something we don't hear payment

intent succeeded okay so we don't have a

decision ID for payment intent succeeded

but we do have session ID for

uh checkout session

we have the amount as well the correct

amount 399

however can we know from this event that

the

yeah the status is completed but

basically so if the checkout session is

completed then we know that the user

actually completed the payment so right

here instead of payment instant

succeeded so we set checkout

session if that is completed then we

also take the ID which is the session ID

we have the payment intent and we get

the session ID from payment intent

um just ID

okay and then we will do the a whole

process like we were doing in the

success

now right here so we get the session ID

um

we can also retrieve the session but I

guess that's not necessary we select the

payment we updated status we update the

order as well

and and and then we return uh the

customer push the customer to the view

so if I just take this portion and

extract into a new function and I'm

going to call this

these update

um update order and session

and we only pass session ID or session

underscore ID doesn't matter so let's

create this update order in session

method private method down below and I'm

going to paste my code here

okay so I get session underscore ID

right here

let's format the code I select the

payment if the payment doesn't exist we

return View

but we have to we have to be careful

here

uh if we return view from there we have

to return view from here as well

okay the payment doesn't exist

will return payment doesn't exist why

don't we simply

roll new not found

HTTP exception

is this the correct one just scroll new

HTTP not

bound

okay let's draw this exception

and in other case we will update the

payment and the order and we're going to

take this code and put this in our

webhoop right here as well so if the

event is checkout session and we get the

session ID and we selected the order if

the payment was not selected we throw

not for an exception but if that was

selected we update status and that's it

okay now if we go in the browser and

have a look so we're gonna have

um this order actually is already paid

they tease the payment let's go in the

orders

okay we have all of them paid now let's

open

our website

and add item into the cart let's go in

the cart proceed to checkout

we have this uh webhook

um redirect enabled

let's provide some details

and let's hit pay and I'm going to close

the tab

okay so I close the tab reload the page

and we see that the order or the payment

is pending now let's see right here we

got

um checkout session completed okay I

think

we made a small mistake right here it's

not simply checkout session the event is

called checkout session completed

Okay let's listen to this so we get the

session ID we update the order

and just like these then we we will

return 200.

so now the order will stay pinning

so let's

let's open the tab again go to websites

now we can go in my orders and we see

this is unpaid I'm going to click pay on

this

okay let's provide formation again

and let's click pay and I'm going to

close the tab again as soon as it turns

into green

okay close the top okay let's have a

look now it's already paid look at this

and if we have a look right here we see

checkout session completed okay chart

succeeded checkout session completed

okay this works fine however let's test

one more time because whenever we don't

close the tab

like this might be triggered and as well

as redirect and then when we select the

payment which has should have status

pending one of them might fail

okay let's let's see let's have a look

so let's open the tab

and let's add one more item

now proceed to checkout

okay and let's have this also

opened

or maybe I'm going to clear up

everything and restart it

okay and now let's click

pay and have this open

so we get succeeded check out complete

and now look at this so your payment was

not successful and that happened

that happened because the web hook

actually triggered earlier than the

redirect okay so on this redirect we

have to make few modifications

uh here it is let me actually look for

uh success

so here it is and we get the session ID

and we have to update uh order and

session so maybe we can make a small

change right here so I'm going to take

this out and we're going to accept

uh payment here it's going to be an

instance of payment model

and let me make sure to remove this

mixed and I'm going to change the

notation into well we don't even need

session ID we just passed the payment

then from the success we select the

payment first but on the success web

hook we only select the

let's select the payment

if it is

pending or completed and then we check

if it is completed we still show success

to the

to the user

so but if it's failed we aren't going to

do anything so we have pending uh paid

and failed

so let's put right here let's change

this into an array and we're going to

select pending payments or payment when

payment status is paid

okay if payment does not exist then

we're gonna throw not found

however

if payment exists in the payment

tattoos

is called

payment status paid

this means that webhook already

succeeded and then the redirect happened

so we have to show success message to

the user so basically we have to put

this right here okay or we can do vice

versa if payment status equals pending

it should be either pending or paid

because we are selecting only these two

statuses if this status is pending then

we update

um then we update the payment and we're

going to pass right here payment okay

this accepts payment right now and we're

going to accept payment we're going to

pass payment

uh and and what

and then the payment will be updated

with the order and then we show success

message to the user let's find the

second place where we are passing the

session ID and we have to select right

here

um

okay

we have to select

payment right here which

okay in this case we can assume that the

payment is pending because it looks like

webhook comes earlier than the redirect

but just in case the redirect comes

first uh we have to select only now we

have to select um completed as well okay

if it's completed we won't do anything

or simply in this case

so we get the checkout session completed

okay let's select only pending

and if that doesn't exist we don't do

anything okay simply if that exists we

will update it

otherwise we just don't do anything

okay now let's test one more time

we are creating something which should

be

used on on production right so proceed

to checkout

according my to my observation and my

past few years

uh like a lot of time is taken on to

actually test your product on multiple

use cases

now hit the enter payment

okay payment session checkout session

completed but here we have another error

yeah the order has been completed we got

this we got multiple

we got multiple succeeds so customer

created succeeded payment and then

succeeded but session to code has 500

error and I think we can have a look at

this error inside storage

logs larval log

it's going to be probably huge right so

let's crawl at the very bottom

and what is the error let's see

argument one payment must be type of

payment string given

okay

that's right

laravel is right as always

so we pass payment right here

now we need one more test because we

want everything to pass

a law I bought a lot of things from my

website

and click pay let's bring up this

we see them coming all of them succeeded

and payment was not successful

okay payment was not successful

let's understand why

so

we tried to

we tried to fetch the session in valid

session ID so we we don't see this

message

your payment wasn't successful let's

open this checkout failure by the way

and see what

we need View

okay your payment was not successful see

that's the message is empty

okay

If the message is empty

then this does didn't happen

okay what might happen

is this

some exception

okay let's open Laurel log

and see if there is any new exception

update session order okay okay no

there's nothing new or at least let's

try to reopen this

thank you

no that's not

it's not a new message so let's close it

so obviously there was an error the

error might be

we get the first payment if the payment

doesn't exist withdrawn not found an

exception

if the payment is pending we update that

and then in the exception I think the

problem is right here okay

so there was some kind of exception

but because

we should have a message displayed

somewhere right if we inspect this we

have a paragraph which is empty

okay we have to we have to throw maybe

throw an exception from here and do one

more test

let's enter cart and then

check out

okay now here we see not found

in the not found

because the payment

okay maybe this doesn't work where I

expected this status would be

um in this but I think that doesn't work

so that should be weird

we are in

tattoos in the array

so let's remove this

now let's go back

okay one and um one another thing like

we are throwing not sound exception

right here

uh but that will be caught by this so

maybe we need another catch

which will catch not found

not found HTTP exception and simply

throw that exception

otherwise we will take this and display

it

okay but that should already work

okay we don't have any items

and it took card

and press it to checkout

and where's my information it didn't

save I think

or it did let me know

I don't want to provide my phone number

at the moment

so let's fill up the form and click pay

let's open this

okay everything completed and your order

has been completed now I think we have

everything good and let's check now our

payments

okay the last one is paid

if we go in the orders we see this is

also paid if we go in my orders we see

that all of them actually is paid except

this one so let's pay this one as well

just to make sure that the payment from

the orders also works fine

here is the intent that was created

and your order has been completed if you

go into my orders we see all of them is

paid

okay I think this is the full flow of

stripe so you configure not only

redirect URLs success and failure but

webhook as well and you have to test

your web hook because that is

um

that's a fallback case if the redirect

failed for some reason okay

okay now let's Implement view order or

view invoice functionality if we go into

design so when we click on this order

number it opens the order Details page

where we see the order number date

status what is the subtotal and the

items what is inside the order and if

the order is not paid we have make a

payment button right here as well if we

go back and click view invoice that

basically doesn't do anything but I

think we need to show a model maybe

inside which we will have invoice okay

but let's first implement the um this my

this should not be my orders that should

be an order with some specific number

this page basically so for this let's

now close everything I'm going to close

all the tabs I have opened and now let's

open

order

controller

and create

function View

where we will get order right here

and we have to render return view order

Dot View and we're going to pass

order

okay however we need to make sure that

the order belongs to the user who is

actually trying to

um trying to view the order so I'm gonna

get this

current user

and we can accept requests right here

I think we can get the current user from

a simple function

to have that function I think no okay

anyway so I think we have a request

request user so basically no need to

accept a request argument right here so

we get the user

and we need to make sure that the order

belongs to the user okay so we check if

the order

created by that can be done in the

middleware as well

but yeah I'm doing it right here so if

the order created by equals or let's say

doesn't equal to user ID then we throw

new forbidden

uh forbidden forbidden I think we don't

have forbidden exception do we have

unauthorized

unauthorized we do have unauthorized

let's go in the

unauthorized exception and maybe we have

some of them

exceptions here as well

exception we have validation exception

and basically that's it we don't have

forbidden exception

well let me actually return

in this case return response

response with message you don't have

um

let's put this in double quotation marks

you don't have permission to view this

order

and

we're gonna pass 403 or maybe we need to

render a page which is specifically for

this for Simplicity I'm going to do it

like this because there's a basically

case when someone is trying something

illegal or something which is not

actually possible from the user

interface okay

so in another case we will render the

order so let's now open order slash view

blade and let's delete this and now I'm

going to open vs code and open order

Details page

and let's copy

this container and put this right here

let's format the code and have a look in

the browser

let's reload the page

okay it doesn't seem to be linked

properly let's open

let's open index blade as well

and let's see we should have wrote order

view we're passing order now let's open

web.php and see

we have order right here and the order

uh sorry

okay this is how it should be

okay orders and maybe we can specify

URL like this so if I just reload the

page

now we see URLs look correct in the

bottom left corner of the screen so I'm

going to click the first one and it's

going to open the order view page and we

have to implement this so if we go right

here uh the title which is called my

orders that should be order number

whatever is order ID

then we have order number right here as

well

order ID

order date we can specify it right here

order created it

order status let's

format HTML nicely and for the order

status we're going to have

order a status

however we have to change this as well

so we have to add a conditional classes

right here if the order

is paid

then we're going to have a class BG

Emerald

500 maybe otherwise we're going to have

PG gray 400

uh that's fine subtotal let's

output

order

amount I think it's called amount we're

going to fix if something if we have a

typo so let's just reload the page

and what happens

okay this is what happens

subtotal order amount okay it seems like

the order doesn't have amount it's

called total price okay total price

now we reload and we see total price we

see order status we see order number as

well

and now let's render order items

so

cart item that should not be card item

that should be an order item

uh okay let me remove all of them except

only one

and let's put this in a 4-H

for each

order items is item

lowercase

Oops why do I need dollar sign here

then we have end for each and let's put

this right here

okay so we need to Output the item

item product

image

I think product has image right

or image URL it's an image okay then

right here we have product title

that is item

product

title

and then we have price the price should

come from

uh item

I think it's called unit price

and then quantity it should come from

item

um 150.

and then we have remove why do we have

remove right here I don't know there's a

mistake

we shouldn't have removed

it was cart item probably in that that's

why we hit remove it is for the right

okay if we just reload the page

we see

the items

that's fine however the image is

um straight not stretched but image

takes huge amount of hate so we have to

do something

uh like we have in the cart

like this so if we now open

a cart blade

and look for the product item how image

is rendered

we see that this is

the image

section so

let's put this right here for the image

URL this is how it should be and remove

colon because that column is using uh

uses alpine.js

and we can change this in to link to an

actual product page which is also fine

so we can specify root right here we're

going to specify product Dot View and

provide item

product

and let's delete this and have a look so

go my orders and click on the first one

and okay this is how it looks like and

we have everything like we have the

title and we have the price however

um I think I'm gonna move the price down

next to quantity Maybe

it's like just if I justify between I

think that's that's much better

okay let's go back and let's actually go

to my orders and view another one

okay fine

another one which is also fine

okay so we have implemented

um we have implemented the order view

page however

this make a payment button should be

disabled or maybe not even visible if

the order is actually paid but if not

paid that should do the same thing as

the payment button from here so let's

open let's close cart index blade and

open order index plate and find the this

portion

okay if the order is paid so let's go

right here and I'm going to paste this

and let's now copy this button make a

payment button let's format the code

and if the order is not paid we send we

create a form with the cart checkout

order

I think that's it and then

we should replace this button

we can leave the icon I think

make a payment

however let's leave the icon this SVG

icon

let's put this right here

okay

let's see

reload the page

okay let's comment out to see the button

first

okay make a payment is looking ugly that

should be Flex

items Center

and here we go justify Center as well

make a payment perfect

now we can

we can recover this if statement if

order is paid

right here and down below we need end

if

okay now let's create one more order

let's add few items in the cart let's

check out let's see to checkout

okay we the order was created at this

moment so now let's open localhost 8000

I'm going to go into my orders and we

see unpaid order let's by the way sort

the orders the reasons to be at the top

so if you open now order controller and

see

um we're let's put right here Order

by

order by created it

uh descending

okay reload the page we see latest at

the top uh however we don't also see the

pagination let's move this format this

nicely let's give it pagination five now

we don't see the buttons so we have to

implement the buttons as well just like

we have in the uh in the product index

so I think

if we go in the index

um

maybe after the table

we have a table

and inside it should be inside

um no it should be outside of the video

white I think it will be nicer so we're

going to have uh orders I think it's

called links not sure let's see

yeah we see these links and let's put

this in zone div and give it class

margin top like three

okay here we see that the first page

second page third page and let's display

only 10

10 at a time

okay go to the first page we have 10

items and we see this pay button here as

well

uh however the button is not that nice

and the viewing invoice button also has

some Styles missing we go in the orders

view invoice looks like this

so now let's go in the index and look

for view invoice not sure if we need

this because the invoice is kind of um

form it's kind of document to prove that

you made an order and you should be able

to print that however this is something

that is a proof and if that's that is

printable that's going to be fine okay

so I'm going to remove this view invoice

at the moment and

leave it

leave it like this

okay so we have the date we have status

we have subtotal

um

and yeah well the only thing we can add

here is maybe number of items

um

items

after subtotal so we collapse this TD

second uh this is status this is

subtotal and

maybe items

and then we call count how many items

the order has

so end dollar is not necessary here

and we can specify text here

okay

this should have um

text no wrap I want no wrap

white space no wrap

however the action has fixed width which

I want to reduce

no that's much better

so we have like three items two one item

one item and so on

okay

fine so we have now orders page and we

um we have to

this one works however I'm going to

slightly increase the button

slightly the vertical padding of the

button

uh yeah that's much better

and if we go inside we need to test if

this make a payment button also works so

I'm going to click on that and we are

redirected right here let's fill up the

form

let's click on pane and and your order

has been completed and here is my orders

as well

which is by the way which is by the way

unpaid and you know why because I have

stopped the stripe CLI in the web hook

uh was not sent

however the redirect worked so so it

should have marked this as completed so

we probably have a small error in the

checkout controller

again testing testing takes a huge

amount of time building your production

ready application

so we should be checking success

excuse me so right here we get the

session we select the payment

and I think the payment will be pending

right so we select pending

we are in pending or paid if the payment

doesn't exist we show not found

if the payment equals pending we update

order and session for the payment

okay paid and paid

and then we show success so

this should have updated

this should have updated the payment

okay

we don't know why it didn't work

let's dump

I'm going to dump the payment

if that's available so let's click on

pay from here

okay we have the payment

in status is pending

so it should come right here

let's put this here

reload the page

we see your order has been completed

because probably the if wasn't satisfied

probably because I don't use right here

value

okay I think that's the reason so

basically comparing a status to

payments such as pending which is an num

NM value simply will not kind of work

especially when when you compare with

two

uh with three quality basically so

if I do this with two equal sign

probably it might work no it's not going

to work so I'm going to specify right

here value in this case this if we'll be

satisfied and we should see payment

right here

here we go and now it's marked as

completed actually marked as completed

and we should be able to see in the

database as well and if we go into my

orders page we should see it marked as

completed here as well

all right fantastic

in this section we have implemented

outputting all orders in the admin this

table looks amazing in my opinion so the

statuses have nice colors and

um I generally uh I am not strong in

design but this is something I I

personally actually liked so we have um

the orders inner page as well from which

we have possibility to change the order

details status I think the UI of these

Details page is not that nice and I'm

going to work on this UI in the future

and make it more like better basically

in terms of UI so whenever this status

is changed right here the customer of

this order will receive an email that

his order status was actually changed

let's see everything basically that has

been changed so far so we created order

controller for the API and that is done

inside the API folder and it has a

couple of methods like to get the order

details

um is it get the all orders as a list

get specific order get the orders

tattooses which are basically values of

NM and we have change status as well

inside which we are using the

um updates order email class for email

sending basically so that's the order

controller we have the order list

resource we have created order list

resource which Returns the following

information which is displayed in the

table and we have created order resource

that is a massive resource it has the

order items inside there each item has

product details there we have the

customer with this shipping and billing

addresses inside this order resource and

we have two classes New Order email and

update order email so New Order email is

sent to the customer as well as to the

admin user that the new order has been

made that information is necessary for

both admin receives basically that hey

new order has been made and you need to

take care of this order and the customer

receives a new email that hey you you

have just made an order and here is your

order details okay so this is the this

is very simple available class and it

has right here New Order subject and

view we're going to have a look at the

views as well so we have order update

the same type and let's have a look

first the mailable views so we have

right here tables that these are just um

not nice user interface basically for

email sending we have links also to the

order Details page for admin if the the

same view basically is used for admin

for the customer when the New Order is

made and if the this view is for admin

we are passing a variable if the user is

for admin we are rendering the backend

URL for the for the view link and in

else case we render the front-end URL

for the order Details page okay and the

similar view is this update order we

just give the user information that your

order is has been updated this is the

new order status and this is a link to

the order which was basically updated

and on the front hand side we created a

similar view views basically we have for

the products we created the orders view

component which has inside the orders

table the orders table basically has the

pagination there and the table header

cell which is uh which is the common one

for sorting and we also have a search

right there and we have order statuses

component as well or the status

component basically as well and that

order status reusable component is used

right here as well as in the list of the

orders right here okay

and we have created that reusable

component and that is basically all we

made in this uh in this section so we

inside the order statuses we added uh

three more sentences canceled and

shipped and completed and we added this

method which returns all the statuses

okay that is all that has been made in

this particular section again I cannot

explain everything line by line uh this

is going to take the huge time of course

and if you're interested to see the full

process of this particular section check

uh the full course on my website

thecodeholic.com all right let's move on

the next section

in this section we have implemented the

user management from the admin side and

that is for the admin users so from here

we now added possibility to create new

admin user provide its email address

provide the password and just like this

new admin user will be created and we

have of course possibility to edit or

delete existing users and that's a

simple user's crowd right here the one

small difference of the difference but

one small thing is that whenever a new

user is added from from here is admin

flag is added to true because the user

needs to be able to log in into the

admin interface okay let's understand

how this was made that's going to be

pretty straightforward and similar to

like orders or products cried so we

create the user controller inside the

API folder for at least for index store

update and delete methods we created

create user request and update user

request we created user resource which

Returns the following information we

actually updated the existing user

resource not created and just edit right

here created it because that's going to

be used right here in this table okay

and we created new user model that's

going to be under API folder which

simply extends to app modules user okay

that's that's that is generally good

approach to create different models for

API because you might need some things

differently for the API models and

that's why we created the user model

probably we are using in the next

sections of the course and we made few

updates in the app layout so we see that

we modified the get user that was a

action get user and that was modified

into get current user okay because the

get user might be necessary for to get

the the following user whichever on

whichever we click this edit button okay

so we make those changes in the actions

as we see we change the gate user into

get current user and down below we're

going to see that we created get users

action right here

and we have get a single user as well

which at the moment is not used in my

opinion and we have create user as well

and we have created update user inside

the actions of course the corresponding

mutations are added as well set users

and I think yeah only set users is added

and similar to orders and products we

have the users component which has users

table and the user model right here in

the user table has possibility

for a pagination and sorting and for

search as well all right and in the API

of course we added new root right here

new API resource for users from the user

controller okay that was all that made

in this particular section and the next

section is the customers crud

customers grad is very similar to users

but we actually I actually spent much

much more time working on the customer's

crowd than on the user's crowd because

the customers cried ahead one

um one tricky thing which we have

finally implemented of course so the

customer details form has these

addresses right there okay so we have

billing addresses and shipping addresses

and we implemented uh we had a custom

input component in the vue.js we have

that and we added this support for the

select as well as we implemented this

possibility to have right here either

text field or select and that believe me

uh the the section is really interesting

the the whole section I think it's also

two hours I planned it to be actually

like a half an hour maximum because uh

it was very similar to the users but it

took some time and if we have a look in

the source code you you will know that

so the customer's controller is

like similar to user's controller but in

this case we consider if we go in the

update we consider the addresses as well

okay and that makes things a little bit

challenging and we are we are also

returning from the customer's control

controller all the countries we have

because we need the countries drop down

and the data is received from the back

end of course

okay so let's let's see the next section

so we change the authenticated session

controller as well and

um

okay so this this is unnecessary the

customer set is right here so let's keep

that uh in the login request however we

made the following changes so we make

sure that whenever the customer I think

this is the authenticate yeah so

whenever the customer authorizes we

check

um on the website we check if the

customer status is active so we are low

if this status is not active basically

we log out the customer invalidate the

session and return the error message

that that your account has been disabled

okay so that was made in the customer

request we have all the validation for

the customer Fields as well as for the

addresses we have kind we have created

country resource and customer list

resource with a few fields in the

customer resource with much more Fields

right here and inside the models we may

just made changes we had has one right

here but we changed it into correct

approach uh to using belongs to and

let's scroll down below and in the

customers I want to open the customers

model okay so that was challenging

actually tricky and challenging so we

have right here all the inputs so this

is the header and down below we have all

the inputs so custom inputs this is what

we are using and we made it so that the

select basically is also a custom input

right now so we create we improved our

custom input and make made it even more

reusable so we have select right here we

provide all the countries we provide of

course V model and now down below we

check if the billing country states does

not exist we render it as a text field

however if it exists we render the

states as a drop down and we even

provide the billing State options and

the same thing of course happens for the

shipping and down below we have the

whole logic how we basically take those

billing country identify the active one

and take out the billing States as well

as consider the cases when the building

country might not be selected the

response is not received from the server

and so that it should not throw an error

like I can't explain again everything

line by line but that was actually

challenging and the whole section as I

mentioned is about like two hours long

in the premium course

okay so and finally on submit we call

the action update customer and down

below we have the create customer okay

that was basically all about the

customer crud

in this section we have implemented the

dashboard page and the whole information

basically is coming from the backend so

we have the number of active customers

number of active products we have paid

orders the total income in the uh in the

whole period we have this website

running and we have the latest 10 orders

right here and we have the latest

customers as well down below and we also

have the orders by country okay so the

whole thing is implemented in this

section and we even have uh we even have

right here change date period drop down

and if we switch this into last week

we're going to see updated numbers right

there that basically nothing was uh

purchased in the last week let's change

this into last two weeks we probably see

something no all the orders has been

made in last month okay so we have this

date range period and let's Now

understand how these changes have been

made in the in the back end so we

obviously created dashboard controller

this section is very very interesting so

we created dashboard controller and we

have a couple of endpoints right here to

get all the active customers count to

get the active products count and this

count will be changed in the future and

added the possibility to only get to

those products which is published on the

website at the moment the published flag

does not exist on the product but this

will be added in the later sections so

the paid orders that's going to return

the all the number of paid orders and

down below we have the total income

that's going to return the sum of all

the total prices of the orders okay but

we also consider in every request

basically this orders by country and we

return this is a complex select with

joins and we return finally the number

of Records by country okay

and down below we have the latest

customers and the latest orders with

limited for the customers we have limit

five and for the orders we have limits

limit 10. okay and in this case we are

using order Resource as well and we

return only the information we need and

down below we have get from date so this

is interesting basically most of the

methods right here uh not this one not

this one this one actually is uh uses

that get from date and we have this from

date so basically if the date was

changed in the user interface like last

month or last week so we basically need

to use uh inside the wear query we want

to add where the create that is more

than the last week date okay and this is

what we calculate okay so get from date

Returns the following array

um and we have we're using carbon

package and we calculate the following

days and then return that information

let's proceed so we have now this from

date

all right let's have a look in the other

files so we have all the resources I

mentioned that's going to return the

order details which is necessary for

displaying the latest orders right here

um the basically this order resource is

under the resources dashboard folder

okay because that order resource is only

for dashboard

okay and uh of course we implemented

installed the chart.js so vue.js chart

let's have a look what's the exact name

of a package viewcharge Jes package and

the charge JS was also installed okay

and using that package we rather render

this donut chart right now if we change

this into all time we're going to see

this donut right here

okay so we also made modifications in

the customer section as well because

right here we render all the latest

customers but whenever we click on the

customer I want the customer details to

be visible for the users okay so

whenever I click now previously the

customer form was a modal okay and

showing the model from this place is is

um is not a good idea basically it's

even more challenging but not a good

idea so when you click on the customer

right now there is dedicated customer

page that customer page opens and it is

also affected in the URL so when you

just reload the page then the active

customer stays right there okay this is

this is the uh change we made of course

in the API we added the following

dashboard roads everything starts with

the dashboard prefix with the dashboard

controller and the method name

and we created the currency filter in

the view.js that's that's something

interesting so we basically if we go in

the dashboard we see that the number

right here is formatted with the dollar

sign okay and this is done through the

currency filter we created that currency

filter we installed that currency filter

we activated the currency filter in the

main JS and then we are using this uh

the

in the dashboard where is dashboard view

file here it is okay and if we scroll

down below let's

enlarge the right side

total income

we have this total income

so basically we are using that uh not

sure here it is here's how we are using

that

currency filter okay so that is all that

has been done into the dashboard

controller but the full process is of

course

um like much much longer I think more

than one hour I think it's uh one and a

half hours the whole section all right

let's move on the next section and see

how the reports are done

in this section we created two uh two

reports and one is the orders report and

second is the customers report so

basically we see all the orders that the

number of orders made per day for the um

from the beginning of the application

okay and if we choose like last week for

example uh we don't see anything because

no order has been made in the last week

but we see seven

um seven days right here okay uh seven

over eight I think this is this is eight

so this includes like um seven days plus

one okay which is probably something

that needs to be fixed but uh at the

moment it is um like this so we have

this report orders by orders by day and

we have the customer report as well

let's choose last month and we're going

to see how many customers basically was

registered the last month so only one

customer was producer okay the data is

not that much at the moment that's why

it doesn't look that nice but believe me

uh when you have a good data and I

tested this on good data as well so

these reports look uh look amazing okay

let's understand how these reports have

been done okay so first we added

published column into products okay so

this was added and we updated the

dashboard controller as well if we

scroll down below we are only returning

those the count of those products which

has published true we also changed the

product controller on the front end and

we return only those products who has

published true okay if the product

doesn't have published true it's not

going to be outputted on the website

okay that was added

and then we let's have a look in the

report controller okay the report

controller has two main methods orders

and customers and it has a private

method prepared data for bar chart

and we are using bar charts in both

cases let's have a look but the actual

data is very similar The Identical

basically for bar chart online chart so

we can even create the line chart for

the customer's report okay it's going to

be pretty straightforward the same

basically okay but I also created report

trade remember in the dashboard

controller we we are using the method

called get from date

okay this is from date or start date

from which uh until the current date we

want to get the data and this gate from

date was used and is used still

right here for example to get the orders

by country or right here to get the

total income from starting from this day

but I created a trade because I needed

the same method in the report controller

as well and I used this trade right here

in the dashboard controller and in the

report controller as well right here

okay and the trade is very simple it has

just one method right here okay

okay we updated the product request uh

we did publish right there we updated

the product uh resource we returned

published and down below we created the

bar and line I think I created the line

chart but not sure why I didn't use this

line chart uh probably I just forgot to

use this line chart and still using the

bar chart

okay so we made a few changes in the

customer we created a customer's report

orders report and we also used

um currency USD filter everywhere

basically we have the price output okay

so in any place where you see price

outputted on the website on the admin

panel right here on this products uh

right here in the orders basically now

it's going to use this currency currency

formatter and the currency format is

like the big Advantage the biggest

Advantage is that it formats with the

currency symbol as well as with the

Thousand separator okay that is

something which is very

um necessary for the uh for the

readability let's let's say like this

okay so that was uh that was basically

all so inside this state we added the

date options we moved the date options

from the dashboard into the States state

store State and we are using this in

both cases in the uh report

um as well as on the dashboard okay

ending the API of course we added those

two report API endpoints okay and just

like this as it it's it is as simple as

that so we created this dashboard in

just five minutes explaining

all right now it's time to take our

e-commerce application and deploy it on

custom domain we can also create custom

email address and configure laravel

application to send emails from that

email address this is hostinger age

panel and from here we can manage our

hosting we can claim our free domain set

up our email set up our SSL certificates

and create databases and Etc

okay so once you register the first time

you will be redirected right here so I

use hostinger as I mentioned for every

kind of things I need and right here I

have premium shared hosting which I can

set up but first we need to claim our

free domain I'm going to click right

here claim domain and I'm going to

search now my domain so I can choose the

um

suffix for my domain which I want

and let's search for L as a the first

letter for laravel L Commerce

L Commerce dot.com

let's see the domain is already taken

let's try another one lcommerce.net

let's click right here

okay and as we see L commerce.net is

available I think that's great domain

for our e-commerce website and I'm going

to take this domain and after one year

the domain renews for 14.

okay so I'm going to click claim domain

right here

which will claim the domain for me and

then we have to set up our SSL

certificates

and premium shared hosting so select

primer details I'm going to choose my

country

this is the place where I have to

provide the address details and this is

just for personal purposes

I'm going to provide right here my

address information

and then click finish registration okay

so my contact information is under

review and I will be informed about my

domain registration in a short while and

I can already create my website so I'm

going to click continue right here

no this is something else

protect your brand it suggests me to

take ecommerce.live but I see right here

the domain status is active email

verification status is verified

and now we just need to add a website

so let's click on the home page right

here on the left side we have the domain

chosen so let's click on the home page

right here we have this setup section we

have to set up premium shared hosting

I'm going to click setup right here and

let's click Start now I can skip this

part I'm building something

fresh new I'm going to choose skip I

will start from scratch here is my

domain

I'm going to select my domain and your

teeth so I'm going to click finish setup

okay now let's go on the home page again

and

we have to basically set up activate SSL

certificates my browser right now is

zoomed and this is displayed on the

right side the navigation if I just zoom

out we see this main navigation at the

top okay you will probably see this at

the top and right here we have couple of

options let me actually zoom in so we

have websites

the websites basically uh I am I have on

this shared hosting so we have right

here hosting and emails and domains and

PPS and SSL let's click on SSL here it

is so lcommerce.net

and let's by the way check what is the

result in the browser

ecommerce.net okay so we see hostinger

welcome page this means that the domain

is taken and it is on the hostinger all

right so this is failed for let's

encrypt why it is failed let's click

manage right there

rhinestone

let's try to reinstall the SSO

certificate okay the SSL is being

installed for eCommerce in the

background https will be automatically

forced on your domain let's click close

right here it's trying to install and

once this finishes we are going to see

right here it is not secure but we're

going to see https protocol right here

and the mark that now this is secure

let's wait until this is done and we

have to add websites as well okay let's

reload the page now we see this as

active so if we go in the tab

ecommerce.net and just refresh this page

now we see lock icon right here and we

have connection is secure now this is

under https we have to add subdomain as

well because this is going to be the

main website now this is going to be

this part but we need item inside as

well we can take subdomain like

admin.elcomers.net which is really

logical

so let's go in the hostinger

premium shirt for hosting for alchemers

we have it right there let's click

manage for l commerce.net so I think

this is the place so from here we can

also take the free email but let's

create first a subdomain okay we have to

add a website let me actually zoom out

this slightly we have domains and

subdomains let's try to add subdomain

admin dot lcommerce.net let it create a

custom folder for subdomain okay let's

understand so basically our main website

is this and if we have a look in the

project Source okay our main website

will be

under public so basically this index

index dot PHP is what will be served and

we have this backend side and we have to

build this vue.js application and to

deploy it on the place where we need

that so it really does not matter I

think

what's going to be the path

so let's specify right here

folder admin

let's create subdomain

subdomin created successfully and let's

now open in a new tab admin

e Commerce

Dot

net

let's hit enter

okay now we see website for our

subdomain as well and let's install SSO

certificate right here

on the right side we have this SSL

section I'm going to click on this SSL

and here we see this admin ecommerce.net

let's click manage okay now it is

already active it automatically got

active and if we just reload this page

we will see lock right here as well so

now we have two domains

admin.elcomers.net and lcommerce.net for

our eCommerce website and the only thing

we need is to deploy our applications

but now let's understand where we need

to deploy it

let's go under files and click the file

manager so let's explore the file

structure and understand where we are

going to actually deploy or how we are

going to deploy it hostinger provides

nice really nice file manager but I am

not going to use file manager to deploy

lateral application maybe we can use the

file manager to deploy vue.js

application but not for a lot of

so right here we see this public HTML

which is a symbolic link basically into

domains L commerce.net public HTML and

if we click on the root directory right

here

we see the same thing if we click on the

domains double click maybe if we go

inside we see ecommerce.net right here

if we go inside

we see this public HTML okay

and right here we see this default PHP

and admin folder if we go inside the

admin folder

this also includes default PHP and let's

open default PHP click edit right here

and understand what is there inside

default PHP we see the HTML basically

this part of HTML okay so we can

actually delete this this is for admin

default HTML so I can delete this

everything

and simply write hello from admin this

is PHP so we can write HTML there I'm

going to save this

and now if we go on the admin page and

just reload this

we're gonna see hello from admin okay

this is the place

right here we are going to deploy our

vue.js application okay so let's close

this and let me actually go back into

eCommerce and we have public HTML right

here and I know that from inside this

public HTML we have to put our vue.js

application under admin folder by the

way we can change this folder as well if

we want

okay so now I'm going to use SSH to

clone my my application in the correct

folder okay and then make

public folder of our vue.js sorry of our

laravel application this public folder

is something that needs to be web

accessible okay right now everything

what is inside this public HTML

is the web accessible if I rename this

right click and rename and call this

index dot PHP it's going to work in the

same way for our

lcommerce.net okay so if we just manage

to have this index PHP which is our

laravel applications entry script index

PHP into here

okay then our application will be

deployed now let's go in the age panel

and I'm going to search for

SSH

right here we have this SSH access under

Advanced so let's click it right here

and here we have IP and port and

username and password basically using

these configurations we can connect to

our project we can do deployment using

basically uploading our files right here

but we have to upload vendor as well and

if we have a look in the application so

our vendor contains a lot of packages

and it's going to take a lot of time

until we upload it so we can zip the

whole application and upload it like

this as well but that's going to also

take huge time so I'm going to try

to show you and teach you how you can

use SSH to deploy your application

okay so let's try to connect using SSH

so for this I'm going to use Puti I

don't have putty so let's download

download Puti which is an SSH client for

Windows so let's click right here

download putting we have to download for

our operating system

so I'm going to click right here to

download the installer save that click

next next

and let's install it

okay now we have protein installed now

let's open it

here is per team and now we have to

provide right here the credentials in IP

that hostinger gave us so IP is this

so we have to hostname or IP we're going

to paste this right here this is the

port

65002 we're gonna put this right here

and we can already click open we have to

click accept right here

and now we have to provide username so

for username we we need to copy these

and then paste it right here and hit the

enter

now it asks password let's Click Change

right here and let's generate new

password okay we have to generate new

password we can type of course new

password we prefer or I prefer to take a

random password so in the Google I'm

going to type random password let's

click right here and let's click

Generate random password and this is the

password now I'm going to set so let's

copy this right click and copy then

let's paste this and click change okay

our password was actually changed now

let's open booty

and let's paste our password here as

well just right click and it's going to

paste it seems like nothing is pasted

but if you just right right click it's

going to paste so then let's hit the

enter

but he was closed okay basically you can

connect to your SSH server in two ways

using password or using public private

keys so let's try to repeat these steps

I have actually password so I'm gonna

save this password temporarily so let me

actually put this right here in our code

I'm going to comment and push it just

put right here for a short time so let's

repeat these steps so I'm going to copy

IP

and put this right here

copy port

this right here

we can also provide username so let's

copy the username

and we can go in the

let's give it let's give it a name we

can save this session as well let's give

it a name the name is l

commerce.net okay and I'm going to click

save right here this is our e-commerce

and then if we go under connection under

data right here under connection data we

have to provide after login username so

I'm going to paste our username right

here go under session and hit save so

now our lcommerce.net session has that

username saved and if we click open

right now it's gonna take the username

but ask password okay so we have our

password right here so let's take this

password

and hit shift and insert or right click

and then hit the enter

for some reason we are not able to log

in and I think I know the reason

so right here we have SSH status

inactive we have to click enable right

here okay SSH is successfully enabled

and now it also recommends to use either

putty or pinguinet and this is the

command which you can run from your

Linux machine okay and the recommended

way which I'm going to also do is to add

a public key okay but first I want to

log in with the password so again I'm

going to now open putty now we have this

lcommerce.net saved I'm going to click

load and then click open

it will ask password I'm going to take

the password

and specify it right here and hit the

enter

okay now we are inside the server this

is the server we are in and we can type

some basic Linux commands and those

basic Linux commands can be found right

here as well basic SSH comments if you

just click on this it's going to open

new tab and it will show you some basic

comments and it will show you also how

you can connect to the server using

putty okay but let me close this and I'm

going to show you a few basic cons to

see every file and folder in this

directory we need to type LS

in this case we only have domain and

domains and public HTML we can type ALS

Dash L A and it's going to give you much

more information for each file and it's

going to also show us that we have some

files and folders which start with DOT

like dot logs in dot profile we can type

PWD to show the current path we are

under home U24 something now if we go in

the browser and click right here this is

the same path okay this is the path we

are inside right now this is our home

directory

K right here

and if we type again

ls-l-a we see right here public HTML

which is a symbolic link from domains L

commerce.net public HTML and we see

domains folder right there and we see

them right here as well domains in

public HTML and profile and logs as well

and we see all all of them right here

okay so this is the same folder now we

need to clone our application right here

okay not right here but under domains

basically so if we navigate inside

domains

and just type

ls-l-a navigation happens using CD

command which stands for change

directory we change the directory into

domains and now we are in the domains if

we just type PWD

now we are under home username domains

okay and then we can type

ls-la and hit the enter and we see our

domain L commerce.net this is our

website so if we navigate inside

lcommerce.net and hit the enter and then

type

ls-l-a we see public HTML right here

okay and if we navigate again inside the

public HTML or we can just list the

directories from this public HTML using

LS LA Public HTML hit the enter we see

admin and index PHP right there okay so

this reflects the same folder in file

structure we see in the browser under

domains we have l commerce.net and

public HTML and in fact if I now

delete this admin folder and index PHP

it's going to disappear from here as

well because that's the actual same file

storage

so let's type ls-la and we see right

here public HTML so basically I'm going

to remove this public HTML RM

Dash RF

public HTML that's going to delete this

public HTML and if we go in the L

Commerce folder right now

we don't see anything we don't have

public HTML anymore and if we check our

websites which is this is the admin

website

we don't see anything we see not found

page from hostinger

and if we check our another website

let's close these tabs another website

we're going to see not found right right

there as well

here we go now we need to clone our

application using our ssh in our file

system so let's clear up everything now

we are under l commerce.net so let's go

One Directory back and I'm going to

clone my application right here in this

lcommerce.net

I have my application on my GitHub so if

we open github.com the code holy go

under repositories

here is laravel view e-commerce okay let

me check if I have everything pushed so

I'm going to delete this password

let's check if I have everything pushed

yes I do have everything pushed

and I now I need to clone this before I

clone this I want to show you one very

important thing as well

so now we are connected right here using

username and password okay but I want to

connect using public private Keys as

well

how to do that if you go in the SSH

access right here we have ADD SSH key we

have to generate public private SSH keys

and edit them right here

okay what are public private SSH Keys

those are the authorization mechanism

modern today's like the most popular and

secure authorization mechanism so

basically you generate two keys public

and private Keys you save Private key on

your operating system and you don't

share it to anyone and you share your

public key to third parties for which

you basically want the authorization to

work

okay and we have to generate our public

private keys on Windows the most common

tool to generate them is putty gain but

I think yeah we do have put again I

think it comes with putty so if we open

this put again it's going to show The

Following window okay and we click this

generate button and basically we have to

move our Mouse randomly

to Generate random public private Keys

okay and now that was generated so we

have public key and we have to save our

public keys in private Keys just click

right here save public key and we have

to save this in a

specific location in that location

should be under your home folder

okay you can save it in else in

different places as well but that is

that is the most common common place and

also the SSH client will by default

search for your public private keys in

that place so under your home folder dot

SSH

okay and you have to save your public

private keys right here okay and for

your public Keys you just need to call

it ID

underscore rsa.pub and just click save I

I'm not going to save because I already

have that saved

and then click save Private key

and in this case it will ask you are you

sure you want to save this key without

passphrase to protect it so in this case

I'm going to give it yes I want to save

it without passphrase passphrase is kind

of additional security layer on top of

this public private keys but I want I

don't want these passphrase because I

want

I want whenever I try to log in inside

the server I don't want to enter any

kind of passwords there anymore okay and

if we if I just set the passphrase it's

going to ask me passphrase

okay I'm going to click yes right here

and again we have to specify the

location your home your username then

SSH folder and you have to call

your private key ID underscore RSA Dot

PPK I think I don't have any kind of PPK

files at the moment because I have my

public private Keys generated on a

different operating system on the Linux

operating system and then moved into

this machine so you just create ideas

say dot PPK and save it okay I'm not

going to save it instead I'm gonna load

my private key let's try to load my

private key

show all files and this is ideas this is

my private private key let's click open

that was actually imported okay this is

my

um my public key for my private key

okay I do definitely have public and

private keys and if you follow your the

instructions I showed to you you are

going to have public private Keys as

well generated we have to take our

public key and put in our

in our website okay so for this let's

basically open our home folder okay

here's my home folder let's open SSH

folder and inside there I actually have

multiple public private keys but this is

what I'm going to use idrc.pop

okay and then right click on this and

I'm going to open this using vs code or

you can open with any editor you prefer

and here is my public key so I'm going

to copy everything go in the browser

click add SSH key and paste this right

here and I'm going to give this name

which is which gives you some kind of

context to identify what kind of kind of

key is this so this is my

Windows laptop and I'm going to click

add SSH key

okay SSH key is successfully added on

the server and now I can authorize you

inside the SSH using putty without

entering password

okay password is less secure way than

public private keys so you should always

try to have authorization using public

private Keys now let's open

Puti okay this is our active session so

I'm gonna type exit right here and now

let's open hoodie and we have these

l-commerce.net I'm going to load and if

I click open it will ask me for password

that's because we need to configure our

putty to take to have a look at the

private key and try to authorize using

public private keys so let's actually

start new session and let's close this

and let's click on L commerce.net and

load this and now if you go under

connection and data connection sorry SSH

and Under auth This Is The Place private

key file for authentication so I'm going

to browse right here and choose our

private key so if I click my user folder

SSH and let's show all files right here

and choose ID RSA in your case it might

be called

idrsa.ppk but they are going to be the

same so I'm going to click idea say open

that and then I will go under session

again and click save

so this will associate my just specified

private key into loaded session and the

loaded session is lcommerce.net

now if I click open right here basically

it I should be authorized and able to

use key file okay opensh SSH to private

key new format so in my case I have a

different format than the server

requires so that's why I wasn't able to

authenticate but if you have just

generated your public private Keys you

should be able to authenticate in fact

let me make is make this um easy and I

can generate new public private keys or

I can convert

my existing private key into the new

version so let's try to open putty again

and let me open now

private key

from my home directory SSH folder

I'm going to choose ideas say and I'm

going to open this okay so that's

successfully imported and I'm going to

now save the private key I think it

needs PPK file so I'm going to click yes

right here go again in the whole the my

home folder zura SSH and I'm going to

call this ID underscore airsa dot PPK

okay this is the extension I think it

needs on Windows I'm going to hit save

right here I think the file was actually

saved now let's open booty and we need

to load L Commerce

and then go under connection SSH alph

and let's browse right here PPK file

open that let's click on session again

and hit save

then we click open right here and let's

wait here we go we are successfully

authorized using our public private Keys

okay I my again I mentioned this but my

public private Keys we are generated on

Linux and then I moved them copied them

on my windows as well because I use the

same public private keys on Windows and

Linux as well but if you just generated

your public private Keys you're gonna

name it dot PPK and you shouldn't have

any problems

okay now I'm on the server and again

let's type LS la

let's see right here we have this broken

symbolic link it tries to it is linked

to domains L commerce.net public HTML

but we deleted that public HTML from

domains which is fine no problem uh we

can even delete that symbolic link RM

RM Dash RF public HTML then

ls-la and we don't see this Pro can

simply click let's navigate into domains

and now I'm going to clone clear up

everything and I'm going to clone my

project right here let's open GitHub

and just copy the https URL

and then type git clone and paste this

URL okay but I'm gonna give it the same

name whatever is our domain

okay so in our case I'm gonna name it l

Commerce dot net

and let's hit the enter

it's going to clone our application in

the lcommerce.net and if I just type LS

La L commerce.net it's gonna show me

list of files and folders we have in the

lcommerce.net right now and if we open

browser

the file manager and if we just refresh

this

we're going to see those laravel files

and folders right here as well okay we

don't have vendor because vendor only

appears if you run composer install

right so let's just run composer install

here

what happened uh composer could not be

found yes we need to run composer

install from the lcommerce.net folder

right now we are under domains folder

look at this so if we navigate into

lcommerce.net

type ls-l-a

this is the files and folders we see and

we're going to run composer install

right here let's hit the enter

all right now we have small problem and

the problem tells us that we are we

don't have enough extensions PHP

extensions

okay first the problem one this package

requires PHP 8.1 by your PHP version

7.4 doesn't satisfy that requirement

that version 7.4 is by default set from

the when you create new application from

the hostinger age panel this is the

default version it is set okay so let's

go now in our age panel right here and

I'm going to search for PHP

so we need this under Advanced section

we see this PHP configuration this is an

excellent thing so I think

that's why I just love the singer shared

hosting Services because it gives you

possibility to configure as much as you

need

the PHP version we are using is 8.1 so

we're going to just change this and hit

the update

changing the PHP version will result PHP

extension values to default okay no

problem I'm going to click confirm right

here it's going to take a few seconds

until this is actually changed

and right now in our terminal

if we just type PHP Dash V

we have already 8.1

that was already changed and it was

immediately changed okay let's run

composer install again

now we have different problems

let's scroll up and have a look okay

composer runtime API I think

by default if we just clear up

everything by default this uses composer

version one so let's just type composer

dash dash version hit the enter

uh we see warnings and composer version

1.10 point something okay I think we can

update the composer we need to update

the composer and we have to run composer

self Dash update

okay once we do this uh it's gonna

download the latest version but the

latest version is one point something

one point latest so it's going to update

into one point latest version we need to

update into second latest version so we

have to type composer self update dash

dash 2 and hit the enter

now it is downloading the latest version

for version 2.

and let's see file system exception

composer update failed user local being

composer one far could not be written

okay so this user local Bean composer

one far so this is the place where

composer self update basically tries to

put it okay this is probably one small

not maybe disadvantage but a

configuration a restriction let's say

that the current version in this

hostinger Services is the composer

current version is version one if we

just try to update composer self update

version 2 that's not going to work

because we don't have root permissions

to update it and it should be updated

globally basically the order there

should be probably an option from this

hpanel to update

the composer to the version one I think

we don't have this

a possibility not sure I'm going to type

composer right here I think we don't

have anything related to this we have to

find a solution that's basically

um daily life of of the developer you

have problems you find the solutions so

in this case we need to use a local

composer so by default when we type

composer we see this is a global

composer and this is the version one but

now I'm going to download the composer

file far file locally which will be for

version two okay let's open Google and

just type download

composer far we want to download for the

latest version so I think we need to run

this following code okay let's just

paste this right here

everything using right click and here we

go so composer version 2.4.3

successfully installed 2 and here's the

location so it was installed right here

in this location

and let's hit the enter and if we just

type

ls-l-a we're going to see composer far

right here okay so we basically need to

execute this composer far using PHP and

it's going to give us version 2. so I'm

going to type PHP composer far

and let's hit the enter now this is

composer version 2. we see it right here

we don't see any warnings by the way and

if we just type composer for test Dash

version he didn't enter we see version

two so we basically need to run

PHP composer far install

space right here and install

let's hit the enter now it is

downloading all the packages our laravel

application needs

we have the correct version of PHP 8.1

and we have the correct version of

composer in this case we used the local

composer because the global composer

basically was referring to the composer

version one okay it should not take much

time until this is downloaded I'm gonna

pause recording and then continue okay

so that was actually finished and we

need to now create a local en file so if

we just type LS again La we see right

here enf example but we don't see en

file okay so I'm going to run CP which

means copy so I want to copy en dot

example into enf and then we need to use

veeam which is an very popular text

editor

to open this EnV file and we're going to

modify a few things right here once you

are inside the veeam you have to type I

on your keyboard to go in the insert

mode and let's change the application

name which is

let's put use double quotes

laravel e-commerce okay so we can leave

the environment local at the moment and

make sure that everything works so far

let's specify right here our application

URL and our application URL is https L

commerce.net okay what options do we

need if we scroll down below we need to

create mySQL database which we haven't

created by the way and then run

migrations so let me leave this open and

now let's create mySQL database let's go

and search for database right here

here we see MySQL databases I'm going to

click on this and let's specify the name

database name L Commerce

okay and that's going to be our full

database name this is the prefix this is

our name L Commerce

the username we can specify the same

username and password I'm going to

Generate random password take this

password

and put this in our in file by the way

you can edit your en file from here as

well if you just refresh this page we

are going to see en right here just

click on this and click edit so we can

do editing from here as well okay maybe

that's that's better for you

so right here I'm going to specify the

connection is MySQL the host is

localhost or

12127001 this is the port everything is

default let's adjust now database

username and password I have password

copied so I'm going to put this right

here so this is the database password

now let's take the let's take the

database name the database name is let's

delete everything the prefix and then L

Commerce

and username is the same thing

prefix and L Commerce

all right now let's go down below we

don't need to change anything right here

okay and we are going to create new

email custom email and we're going to

configure this right here but let's

leave this until now just to make sure

that the website works

if you scroll down below we have to

provide

stripe Keys as well but let's actually

save everything to save everything we're

going to hit escape on our keyboard then

we're going to type colon W which means

to write the changes on the inside the

file and then Q to quit basically from

the file I'm going to hit enter okay and

what else do we have remained I think we

have to generate the ANSI key but let's

check first the browser in the browser

we don't see anything yet because we

have one very important thing missing

okay we don't have public HTML under L

Commerce folder and by default it

searches for public HTML if we type

ls-l-a we don't see public HTML right

here but we have public folder

if we just create a symbolic link

from public into public HTML then it

should work

so for creating a symbolic link we're

going to type Ln Dash public dash s

public needs to be linked inside public

underscore HTML so let's hit enter

now we should see symbolic link right

here actually we see that and if we open

our browser and reload it we're gonna

see some kind of error okay this is

larval error that tells no application

encryption key has been specified and

that is exactly what I expected now we

are in the project main directory and

we're going to run PHP artisan

uh T colon generate a insi

let's hit the enter application key set

successfully and if we just reload the

page

now we see problem about the database

okay now we're going to run migrations

PHP Artisan migrate

and let's run seed as well dash dash

seed

let's hit the enter we have the problem

access denied for user did we actually

finish creating database I think we we

haven't finished that so we have to

click create right here it's going to

take a few seconds database created

successfully and we have the database

right here and now let's rerun PHP

design migrate dash dash seed

and here it goes

now it it is running migrations it runs

admin user Cedar and Country Cedar as

well and if we open our website and

reload it now we have the problem which

is basically about the vue.js not the

view JS but the white because of white

so we don't have white manifest file we

need to run npm run build let's all open

our project we can do this from here as

well but not sure if we have npm do we

have node.js and npm here no we don't

have that we can go ahead and install it

right here but it is not necessary we

can open our project

we can bring up the terminal and I'm

going to run npm run build

okay that's gonna create and build

and create these build folder under

public so if we now check

under public we have this build folder

okay and we have to commit and push this

build folder and then pull the changes

right here okay using git so I'm going

to go and comment the changes

I think this build might be even ignored

I think it is ignored but I'm gonna just

remove it from git ignore

so if I open git ignore and search for

public build it is added right here so

basically purpose why the spill

directory is added under uh here in the

git ignore is that

the it is a generated file build file

and it can be generated on any platform

so basically if we have node.js right

here and if we just run npm install and

then npm run build we would be able to

generate it from here as well but I

think the easiest solution will be just

to remove it from here at the moment we

save it

now I'm going to make

I'm going to comment those changes

basically I can comment from terminal as

well it status and here's the public

build so let's add git head

public build okay let's type git status

and we see those those changes right

here and let's comment and we have to

also add a git ignore as well so git add

Dot git ignore

hit the enter

now again git status and we see those

changes right there let's comment them

hit commit minus M Aid build directory

let's hit enter now we need to push our

changes kit push origin main okay we'll

push them now let's open our project

terminal this is our project true

directory and I'm going to run git pool

origin Main

if we hit the enter now our changes have

been pulled and if we just reload

we see the home page up and running we

don't have any product pro products at

the moment but we do have the login

registration all of that should actually

successfully work now let's deploy our

vue.js application so that log in and

create products right there okay this is

it and it shows not found deploying

view.js application is much easier so

let's go in the project and let's

navigate into

backend okay we will have that right

here

under back end and I'm going to run npm

run build and that is going to generate

build files let's wait here we see this

folder let's go in the backend

and right here we see this dist folder

okay and everything basically we should

take everything from this this folder

and put it in the directory we mapped

into our uh into our subdomain so in

this case we mapped everything from the

public so if we go inside let's refresh

everything

we should see right here public HTML as

well here we go so inside there we need

to create right here admin folder and if

we open that we're going to put our

files right here

so here are our files I'm going to open

this in a file system

on our file system

then basically let's open browser and

then these files and I'm going to drag

and drop those files right here in this

admin

there are not much files let's click

upload it's going to take few seconds

until all theme is uploaded

and let's have a look

let's reload the page

and here we go so we see our application

and now let's try to log in with the

admin username and password we gave it

in the admin user Cedar so we have this

admin user Cedar and there we specified

admin one two three to be the password

so let's specify username to be admin at

example.com

the password will be admin one to three

and let's click sign in but I'm going to

also inspect and have a look in the

network just in case there are some

errors

to observe it

there are no errors and we are actually

able

to successfully

logging into the backend

however however look at this so we don't

have any products we don't have any paid

orders but we see numbers right here

okay that happened because

when we build our vue.js application it

used

the domain of our local API not the

production API okay we didn't specify

this

and if we just click login for example

look at this the URL basically is the

localhost port 8000 okay and this is

something we have to adjust so we have

right here dot EnV and the dot en

basically corresponds to inside the dot

EnV we have this base URL to be

localhost Port 8000. we need to create

another en file which should be for

production

Dot en.production

and we can have a look at the white

let's search for white environment

variables

or byte for example.en production

okay so if we just click right here

so you can read these section but

basically as far as I remember if we

just have these em dot mode in this case

production and we build that it's going

to take

the this byte API based URL from this

enf production so I'm going to basically

modify now these in production and call

this https

L Commerce

.net

so I save this

I open the terminal and run npm run

build again that's going to take few

seconds okay as soon as this is done I'm

going to open the file manager and I'm

going to delete

all the

files from here

and re-upload

then these files now the Javascript file

which is inside the assets folder will

correspond to production server not

local server and if we open our admin

and reload the page

we see not found that's that's

understandable we're going to fix this

not found as well okay and let's now try

to log in with admin in admin123 and hit

sign in okay now we see everything is

zero because there are no products no

orders nothing is there everything is

empty if we go in the products empty

database orders empty users we have only

one admin user which is the logged in

one we have customers and we have

reports okay everything is empty

however if I just reload this right now

we have this not bound problem

so that happens because

our web server is configured that it

tries to find a file or folder this path

at this path

so we basically need to change the

configuration so that everything needs

to be redirected to the index HTML

because the index.html in our case is

the file which takes all the requests

okay and this is processed by JavaScript

not by the server side now we have to

open file manager

inside which we have this admin

basically deployed and right here we're

going to create new file called dot

htaccess that is the Apache

configuration file and we have to

configure it so that everything should

be redirected to the index HTML so let's

click this HD access and click edit

and I'm going to specify right here

first we're going to enable rewrite

engine so rewrite engine

on uppercase O then we're going to write

rewrite conditions

we write

cond we have to specify right here

the request file name request

file name

space

exclamation Dash F so basically this

means the request file name the request

file name is everything after the domain

okay

and we specify if the request file name

doesn't equal to file and we have to

copy this and put this and change this

into D and if the request file name is

not a directory

then inside rewrite rule we write that

should be everything redirected into

index HTML

okay and we hit save right here and

let's now refresh

and here we go so now we see up

dashboard if we go on another page and

reload that Apache understands that it

needs to redirect to the index.html and

we see our application okay and just

like this we deployed our vue.js

application

now we need to take custom email address

create custom email address and

Implement email sending with that custom

email address let me close all the tabs

I don't need them at the moment and if

we go in the register now and fill up

the form it's not going to send us an

email because we don't have eno file

configured correctly okay if I go in the

ecommerce.net and click on this EnV and

edit that scroll down below we see in

the mailer section we have a mail hog

right here which is basically for local

testing okay let's create now custom

email address configure it right here so

that when the user registers the email

is sent basically from let's say info at

lcommerce.net from that email address

okay for this we need to search

email section right here

emails go to control panel and we have

to select the plan for our eCommerce so

we can take a business email which has

couple of advantages like email

templates and send later feature and

follow-up reminders

but I think we don't need that at the

moment so I'm going to click this free

email

select right here

email plan was successfully selected and

right here we have to create now uh

email and I'm going to call this info

info at lcommerce.net and let's generate

random password for our email info at

lcommerce.net let me actually I can

specify or automatically generate

password so let's create new account uh

we're going to specify by the way the

recovery email address as well I'm going

to specify this as my email address and

create new account okay so the email was

actually created and in fact we can now

login into the email inbox as well so if

I just click on this it's going to open

new tab and we have this info at L

commerce.net provided right here and

let's copy the password

and paste this right here click login

it will ask us again about recovery

email and click on submit

okay once this process is finished we

will be able to see our inbox let's just

reload because sometimes it Stacks right

there okay and here we have this inbox

so let's close this we don't we don't

need this professional email okay and

this is our email from which we can

basically send emails and receive emails

using info at lcommerce.net this is

awesome right but we're gonna go even

step further we have this custom email

address from which we can respond to the

customers of our e-commerce website and

anyone but let's take now SMTP

credentials and put this in our website

okay so let me hit done right here

let's go on the home and this is the

place so here we have multiple options

but what I need is configure desktop

application basically this is the

approach how a third party can connect

to your email so I click on configure

desktop app and it gives me now the SMTP

information I need so we basically we're

going to use this so we have two options

configure via pop or iMap for us it's

the same so I'm going to I'm going to

take this outgoing server which is SMTP

titan.email quick disclaimer right here

the only purpose of this section is just

to show you how you can configure your

laravel application to use production

ready SMTP credentials this particular

email provider is not intended for

massive email sending it has limitations

per day or per hour its main purpose is

to give you a business email and

business look when sending and receiving

emails from the user interface from the

inbox I don't recommend using this

particular email provider on production

for massive email sending if you need

massive email sending we should probably

consider something like MailChimp or

sendgrid also don't abuse the email

service providers terms and conditions

and don't send emails to non-existing

accounts in such case your email account

might be suspended

and put this in the file manager

mailer is SMTP itan email let me zoom in

then we need to take

let's use SSL encryption to be SSL

we have encryption right here

let's specify Port which is 465

we have portrait here

uh excuse me

excuse me right here the mailer should

be as MTP

I'm sorry the host should be SMTP Titan

email let me remove this the mailer

should be SMTP host should be SMTP Titan

email

mail Port we have now username and

password the username and password is

basically

what we

just copied I think we copied password

once but we need to probably reset the

password because I didn't save that

password so here we see that

email accounts

let's click on this reset password info

at eCommerce dot net send result link we

should receive reset link right here

here we received let me zoom out and

click reset your password and we have we

have to specify new password so I'm

going to generate again a random

password

because we need a strong password for

that let's take this

and this is my new password

okay so that was successfully changed

and I was logged out from the system

basically and now I'm gonna put this

right here okay this is my password and

the username is obviously info at l

commerce.net

so now we have the mailer configured

properly and let's specify from address

as well which will be in for at

lcommerce.net

scroll down below and hit save right

here okay now I'm going to close this

and now let's try to register on our

website

and I'm going to use my personal email

address and let's hit sign up

okay so here it tells me that

thanks for signing up before getting

started I had to verify my email address

basically let me open my Gmail

look at this so I just received an email

verify email address laravel elcom

eCommerce this is our website hello

click the link below to verify your

email address let's click on this link

and now we are authorized in the system

and we can go in my profile and add

addresses right here and we see

countries as well which came from the

country Cedar okay now we have our email

address

set a custom email address set up

correctly and basically from application

we use this custom email address for

email sending which is awesome now I

think we need to create couple of

products and make an order and we have

to also specify stripe fees as well so

because I am going to have a test

account uh for stripe as well so I'm

just gonna have a production stripe

account so I'm I can

take

these keys from dot EnV

I can copy these three keys and then

open the file manager open in edit it

scroll down below

and paste them right here

okay so we have publishable key secret

key and webhook secret key as well we

have to configure webhook as well so I'm

going to click save and close Okay so we

have that stripe information as well and

now I'm going to add a few products and

then make an order

we have this small problem because we

added published and whenever we are

trying to create new product and we hit

the submit no matter if you tick this

published or not we hit the submit we

have this error we have this debugger

and if we just continue and have a look

in the network we have this problem that

published the published field is

required if we check payload right here

we don't see published so we don't pass

published on the new product creation so

let's open big inside go under source

views

products product model

and let's have a look

what do we do right here

so when the user hits submit

on submit

we take product value

and send that

okay so whenever we call update product

if we change the image we're going to

lose that published yes this will happen

so whenever we are trying to create new

product let's search for

create

product we basically lose that published

so let's click right here we have to

duplicate this

and change this into published

product published

but I have a feeling that that's going

to be always true because it's going to

send probably

shrink so we're gonna test this I'm

going to click a new product

give it test title

let's choose some image

and give some price

clear up the network

and hit

submit

okay we have this error let's check the

networking payload

we send published to be undefined all

right let's check now

what do we have inside the product

debugger

let's add new product

test choose an image give some price and

hit the submit

the product contains right there

published to be undefined

okay if we don't tag the checkbox it is

undefined which is okay so it's kind of

false

but we definitely get this error

let's continue There

the published field must be true or

false we send it undefined but it must

be true or false

all right let's change this

and if it's undefined

well we can cast it into Boolean so

let's use double exclamation mark

okay and this will simply cast this into

Boolean

if it's undefined it's going to become

false

so it's just a new product

test

choose the image

and give some price

let's not mark this published checkbox

hit the submit

and now the product should contain

it will not contain actually but it will

product published I think the browser

will didn't update

our changes Let's test this test

image and price hit the submit

let's proceed

we have an error let's see what

information is sent it is still

undefined

let's proceed

published is still undefined

let's remove the debugger from here so

let's do like this if published exists

then we take true otherwise we take

false because we want it to be Boolean

but the value right here actually should

be string inside form append not sure

how this will work so let's check this

price is one two let's mark this and hit

the submit now

okay we still get this error I want to

remove this debugger from product model

let's remove it

endless proceed

and let's check Network

the published field must be true or

false

yes in this case we send it to be true

but this is actually string it is not

Boolean

okay this is the problem the published

field must be true or false

I think this can be adjusted using

laravel rules so if we open product

request

and scroll down below

and find the published

needs to be required in Boolean so by

default the Boolean rule basically

checks only the following values it

should be either false or true or zero

or or one or it can be string zero or

string one okay but it doesn't have

string true and string false so if we

open now our

actions JS and if we just change what we

are sending so instead of sending right

here true or false why don't we send one

and a zero

okay we can even wrap this as strings

but we it will be

um just converted into Strings in any

case if we do like this and then try to

add new product

hit this submit now we see that the

product was actually created

okay and it also has this published

checked now let's create second product

test two

which will not have this published

marked

and we see test two and if we edit we

see it is not published and if we check

on the front and side we're going to

also see test outputted right here but

S2 is not output

okay just like this we have fixed this

problem

let's try update as well because that

was the creation part and if we search

for update or why why don't we simply

copy this part

and search for update product and put

this right here

okay we need to send it like this as

well and now if we just

open any products

and just change the image and tick the

checkbox

it's gonna work so here we see this last

updated and it should have also checkbox

checked

okay the description is now which I know

why because right here we send the

description was actually null and it was

sent as now string so we can specify

right here if the description doesn't

exist just take an empty string okay and

we have to do the same thing when we are

creating product right here as well so

we fixed this problem about creating new

product

I have created a simple test product but

the uploaded image is not displayed and

there are two things to do to make the

uploaded images to be displayed first we

have to create a storage link which we

haven't done we're going to run PHP

Artisan storage column link and this

will create a link from Storage up

public into public storage so basically

the uploaded files go under storage app

public and that storage are public is

not web accessible only those files and

folders are web accessible which are

under public folder so laravel creates a

symbolic link from Storage are public

into public storage and now if we go

under public folder we're going to see

right here storage symbolic link okay

and everything which is uploaded under

Storage Public will be available right

here as well okay so far so good but

this will not fix our problem there is a

second thing to do to make this working

now the storage link exists but we are

using an incorrect nothing correct but

the file system we are using is not

configured to be publicly accessible all

right so let's have a look let's

navigate One Directory back calling the

project through directory and we're

going to open Dot en file

and right here we have this file system

disk equals local okay so we are using

at the moment local file system and now

let's open our laravel project

let's open a file under config file

systems PHP and right here we have

multiple disks configured this comes out

of the box with laravel we have local

file system public S3 and so on and if

we scroll up the default one is taken

from the en file system disk and this is

local we just saw and if we have a look

the local file system is not configured

to be publicly available and accessible

okay so right here we need to give it a

visibility to be public just like the

public disk has like we could use this

public disk as well but in this case a

few things might not work because we

might have to update the code of

uploading image which we don't want at

the moment so we're going to put right

here visibility is public okay so once

you do this just comment and push the

changes on your git repository then

we're gonna we're gonna go in the

project we can

exit from veeam

and then we're gonna pull the changes

we're going to run git pool and I

already have those changes pulled

well we're going to run gitpool origin

Master main origin main this will

download the latest version and now if

we open a full file from config file

systems and have a look if I scroll at

the top so let's have a look we have the

local and right here we have visibility

public so this indicates that now we

have the latest change on our server

okay and now we can open the browser

let's delete this and try to create new

product

okay

let's name it test

choose some image

give some price

and hit submit

okay the product was uploaded and images

right there let's test also modifying

the image I'm going to choose a

different one and click submit

and that works perfectly now I'm going

to go ahead and create several simple

products I added these two items and I'm

going to now add both of them in the

cart

go to the cart

click on proceed to check out

we have already provided stripe keys so

we should be good to go

let's specify right here stripe

S card information

we haven't configured the web hook so

far so the redirect should work and our

order should be able our order should be

marked as completely and I get the

success message and if I go in my orders

I see right here Order

click on this I see the order is

actually paid if I go in the admin

right here we see one order and I also

got an email I want to show this email

this is the email I received new order

has been created

okay the image for the second one is for

some reason broken

but the email is actually received and

if you go in the dashboard

we are going to see two active products

one active customer one paid order total

income

we see the latest customer latest order

if we go in the orders we see this order

and if we click right here we're going

to see the order details

we probably have an error right here

sometimes the error happen after you

deploy your application they don't

happen on locally but they happen when

you deploy so you should know how to

deal with these problems I tend to read

property ID on null

that happens

on order resource

this is where it happens and I think the

reason might be addresses because we

don't restrict users

from checkout

and if we open this

right here we try to access to

something like customer and shipping ID

and and I think that is the that is the

problem

and yeah this is something which can be

easily fixed we have the line right here

as well so the line is 47 this is

exactly

okay here is the line mentioned

so this is something we need to improve

but the main thing is that the

application is deployed and working and

we are able to register and log in

and make an order as well

probably the only thing that is remained

is to configure web hooks which is very

easy so let's go to the stripe dashboard

let's search for web hooks right here

and at an end point

so now we have to provide right here our

domain

which is this

and I think the URL is called webhook

right so let's put this right here and

let's open in our project web PHP

and webhook stripe this is the URL so

I'm going to paste this right here

select the events to listen we can

listen for checkout

session

completed because this is what we are

interested in

this is what we're looking for and we

can open this webhook and scroll down

below and find checkout session

completed yeah this is exactly what we

are interested anything else is

something we don't care all right so we

add an event

we have this domain ready

endpoint URL and let's add endpoint so

we edit this webhook and now let's make

one more order but in this case we're

gonna close the tab after

the payment basically is made but before

the redirect happens so we proceed to

check out

so we fill up the information and click

on pay and this button turns into green

I'm going to close the tab

okay I'm going to close the tab and now

let's have a look so let's reload the

page it's gonna go through an error if

we click on the orders now we see both

is actually paid and that's because

stripe sent webhook properly and if we

check the customer

ecommerce.net

and go in my orders right here I see

both of them are paid so our webhook

also works fine

all right guys that's it for this

project and I hope you liked it if so

hit the like button and subscribe to my

channel I will see you in the next time

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.