Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
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
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
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
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
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.