diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..4e637713
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+node_modules
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..77f6afab
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+# Bagisto Documentation
+
+You can find the online version of the Bagisto documentation at [https://devdocs.bagisto.com](https://devdocs.bagisto.com).
+
+## Contribution guide
+
+For contributing to the docs, you first need to set up the project,
+
+- Fork the repository.
+
+- Clone your fork.
+
+- Follow the [Install Dependencies](#Install-dependencies) section.
+
+Make sure your PR follows all these points,
+
+- Before writing the docs just make sure to check that if that topic is already written or not.
+
+- Make sure your markdown indentation should be proper. You can install `mark-down` lint also. This will help you to follow the markdown conventions.
+
+- If you are creating new files for the docs, then make sure the filename should be `kebab-case`. For e.g. `file-1.md`, `file-2.md`.
+
+## Install dependencies
+
+- Run the following command,
+
+ ~~~sh
+ npm install
+ ~~~
+
+- Run the docs locally,
+
+ ~~~sh
+ npm run docs:dev
+ ~~~
+
+- Open your browser and go to [http://localhost:8080](http://localhost:8080).
diff --git a/deploy.sh b/deploy.sh
new file mode 100644
index 00000000..964c073a
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env sh
+
+# abort on errors
+set -e
+
+# build
+npm run docs:build
+
+# navigate into the build output directory
+cd docs/.vuepress/dist
+
+echo 'devdocs.bagisto.com' > CNAME
+
+git init
+git add -A
+git commit -m 'Deploy docs to GitHub'
+git push -f git@github.com:bagisto/bagisto-docs.git master:gh-pages
+
+cd -
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
new file mode 100644
index 00000000..e957a2a2
--- /dev/null
+++ b/docs/.vuepress/config.js
@@ -0,0 +1,37 @@
+module.exports = {
+ base: '/',
+ port: '8080',
+ cache: false,
+ title: 'Bagisto Documentation',
+ description: 'Bagisto Developer Portal',
+ head: [
+ ['link', { rel: "icon", type: "image/png", href: "/favicon.ico" }],
+ ],
+ themeConfig: {
+ smoothScroll: true,
+ lastUpdated: 'Last Updated',
+ repo: 'bagisto/bagisto',
+ repoLabel: 'Contribute to Bagisto',
+ docsRepo: 'bagisto/bagisto-docs',
+ docsDir: 'docs',
+ docsBranch: 'master',
+ editLinks: true,
+ editLinkText: 'Help us improve this page on Github.',
+
+ logo: '/logo.png',
+ nav: [
+ { text: 'Home', link: '/' },
+ { text: 'Extensions', link: 'https://bagisto.com/en/extensions/' },
+ { text: 'Community Forum', link: 'https://forums.bagisto.com/' }
+ ],
+ sidebar: {
+ '/1.x/': require('./version-configs/1.x'),
+ '/1.5.x/': require('./version-configs/1.5.x'),
+ '/2.x/': require('./version-configs/2.x')
+ }
+ },
+ markdown: {
+ lineNumbers: false
+ },
+ plugins: ['@vuepress/pwa', 'copy-code', '@vuepress/back-to-top']
+};
diff --git a/docs/.vuepress/override.styl b/docs/.vuepress/override.styl
new file mode 100644
index 00000000..69843be3
--- /dev/null
+++ b/docs/.vuepress/override.styl
@@ -0,0 +1,7 @@
+// color settings
+$accentColor = #227CD9
+$borderColor = #e1e1e1
+$codeBgColor = #282c34
+$badgeTip = #42b983
+$badgeWarning = darken(#ffe564, 35%)
+$badgeError = #DA596
\ No newline at end of file
diff --git a/docs/.vuepress/public/favicon.ico b/docs/.vuepress/public/favicon.ico
new file mode 100644
index 00000000..e9c217bb
Binary files /dev/null and b/docs/.vuepress/public/favicon.ico differ
diff --git a/docs/.vuepress/public/logo.png b/docs/.vuepress/public/logo.png
new file mode 100644
index 00000000..fd410637
Binary files /dev/null and b/docs/.vuepress/public/logo.png differ
diff --git a/docs/.vuepress/styles/palette.styl b/docs/.vuepress/styles/palette.styl
new file mode 100644
index 00000000..458baf4a
--- /dev/null
+++ b/docs/.vuepress/styles/palette.styl
@@ -0,0 +1,17 @@
+$accentColor = #0041FF
+$borderColor = #e1e1e1
+$codeBgColor = #282c34
+$badgeTip = #42b983
+$badgeWarning = darken(#ffe564, 35%)
+$badgeError = #DA596
+
+// layout
+$navbarHeight = 3.6rem
+$sidebarWidth = 20rem
+$contentWidth = 960px
+$homePageWidth = 960px
+
+// responsive breakpoints
+$MQNarrow = 959px
+$MQMobile = 719px
+$MQMobileNarrow = 419px
\ No newline at end of file
diff --git a/docs/.vuepress/theme/LICENSE b/docs/.vuepress/theme/LICENSE
new file mode 100644
index 00000000..15f1f7e7
--- /dev/null
+++ b/docs/.vuepress/theme/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2018-present, Yuxi (Evan) You
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/docs/.vuepress/theme/components/AlgoliaSearchBox.vue b/docs/.vuepress/theme/components/AlgoliaSearchBox.vue
new file mode 100644
index 00000000..7b2a5807
--- /dev/null
+++ b/docs/.vuepress/theme/components/AlgoliaSearchBox.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/theme/components/DropdownLink.vue b/docs/.vuepress/theme/components/DropdownLink.vue
new file mode 100644
index 00000000..be6563fa
--- /dev/null
+++ b/docs/.vuepress/theme/components/DropdownLink.vue
@@ -0,0 +1,252 @@
+
+
+
+
+
diff --git a/docs/.vuepress/theme/noopModule.js b/docs/.vuepress/theme/noopModule.js
new file mode 100644
index 00000000..b1c6ea43
--- /dev/null
+++ b/docs/.vuepress/theme/noopModule.js
@@ -0,0 +1 @@
+export default {}
diff --git a/docs/.vuepress/theme/styles/arrow.styl b/docs/.vuepress/theme/styles/arrow.styl
new file mode 100644
index 00000000..20bffc0d
--- /dev/null
+++ b/docs/.vuepress/theme/styles/arrow.styl
@@ -0,0 +1,22 @@
+@require './config'
+
+.arrow
+ display inline-block
+ width 0
+ height 0
+ &.up
+ border-left 4px solid transparent
+ border-right 4px solid transparent
+ border-bottom 6px solid $arrowBgColor
+ &.down
+ border-left 4px solid transparent
+ border-right 4px solid transparent
+ border-top 6px solid $arrowBgColor
+ &.right
+ border-top 4px solid transparent
+ border-bottom 4px solid transparent
+ border-left 6px solid $arrowBgColor
+ &.left
+ border-top 4px solid transparent
+ border-bottom 4px solid transparent
+ border-right 6px solid $arrowBgColor
diff --git a/docs/.vuepress/theme/styles/code.styl b/docs/.vuepress/theme/styles/code.styl
new file mode 100644
index 00000000..9d3aa9a5
--- /dev/null
+++ b/docs/.vuepress/theme/styles/code.styl
@@ -0,0 +1,137 @@
+{$contentClass}
+ code
+ color lighten($textColor, 20%)
+ padding 0.25rem 0.5rem
+ margin 0
+ font-size 0.85em
+ background-color rgba(27,31,35,0.05)
+ border-radius 3px
+ .token
+ &.deleted
+ color #EC5975
+ &.inserted
+ color $accentColor
+
+{$contentClass}
+ pre, pre[class*="language-"]
+ line-height 1.4
+ padding 1.25rem 1.5rem
+ margin 0.85rem 0
+ background-color $codeBgColor
+ border-radius 6px
+ overflow auto
+ code
+ color #fff
+ padding 0
+ background-color transparent
+ border-radius 0
+
+div[class*="language-"]
+ position relative
+ background-color $codeBgColor
+ border-radius 6px
+ .highlight-lines
+ user-select none
+ padding-top 1.3rem
+ position absolute
+ top 0
+ left 0
+ width 100%
+ line-height 1.4
+ .highlighted
+ background-color rgba(0, 0, 0, 66%)
+ pre, pre[class*="language-"]
+ background transparent
+ position relative
+ z-index 1
+ &::before
+ position absolute
+ z-index 3
+ top 0.8em
+ right 1em
+ font-size 0.75rem
+ color rgba(255, 255, 255, 0.4)
+ &:not(.line-numbers-mode)
+ .line-numbers-wrapper
+ display none
+ &.line-numbers-mode
+ .highlight-lines .highlighted
+ position relative
+ &:before
+ content ' '
+ position absolute
+ z-index 3
+ left 0
+ top 0
+ display block
+ width $lineNumbersWrapperWidth
+ height 100%
+ background-color rgba(0, 0, 0, 66%)
+ pre
+ padding-left $lineNumbersWrapperWidth + 1 rem
+ vertical-align middle
+ .line-numbers-wrapper
+ position absolute
+ top 0
+ width $lineNumbersWrapperWidth
+ text-align center
+ color rgba(255, 255, 255, 0.3)
+ padding 1.25rem 0
+ line-height 1.4
+ br
+ user-select none
+ .line-number
+ position relative
+ z-index 4
+ user-select none
+ font-size 0.85em
+ &::after
+ content ''
+ position absolute
+ z-index 2
+ top 0
+ left 0
+ width $lineNumbersWrapperWidth
+ height 100%
+ border-radius 6px 0 0 6px
+ border-right 1px solid rgba(0, 0, 0, 66%)
+ background-color $codeBgColor
+
+
+for lang in $codeLang
+ div{'[class~="language-' + lang + '"]'}
+ &:before
+ content ('' + lang)
+
+div[class~="language-javascript"]
+ &:before
+ content "js"
+
+div[class~="language-typescript"]
+ &:before
+ content "ts"
+
+div[class~="language-markup"]
+ &:before
+ content "html"
+
+div[class~="language-markdown"]
+ &:before
+ content "md"
+
+div[class~="language-json"]:before
+ content "json"
+
+div[class~="language-ruby"]:before
+ content "rb"
+
+div[class~="language-python"]:before
+ content "py"
+
+div[class~="language-bash"]:before
+ content "sh"
+
+div[class~="language-php"]:before
+ content "php"
+
+@import '~prismjs/themes/prism-tomorrow.css'
diff --git a/docs/.vuepress/theme/styles/config.styl b/docs/.vuepress/theme/styles/config.styl
new file mode 100644
index 00000000..9e403210
--- /dev/null
+++ b/docs/.vuepress/theme/styles/config.styl
@@ -0,0 +1 @@
+$contentClass = '.theme-default-content'
diff --git a/docs/.vuepress/theme/styles/custom-blocks.styl b/docs/.vuepress/theme/styles/custom-blocks.styl
new file mode 100644
index 00000000..5b868166
--- /dev/null
+++ b/docs/.vuepress/theme/styles/custom-blocks.styl
@@ -0,0 +1,44 @@
+.custom-block
+ .custom-block-title
+ font-weight 600
+ margin-bottom -0.4rem
+ &.tip, &.warning, &.danger
+ padding .1rem 1.5rem
+ border-left-width .5rem
+ border-left-style solid
+ margin 1rem 0
+ &.tip
+ background-color #f3f5f7
+ border-color #42b983
+ &.warning
+ background-color rgba(255,229,100,.3)
+ border-color darken(#ffe564, 35%)
+ color darken(#ffe564, 70%)
+ .custom-block-title
+ color darken(#ffe564, 50%)
+ a
+ color $textColor
+ &.danger
+ background-color #ffe6e6
+ border-color darken(red, 20%)
+ color darken(red, 70%)
+ .custom-block-title
+ color darken(red, 40%)
+ a
+ color $textColor
+ &.details
+ display block
+ position relative
+ border-radius 2px
+ margin 1.6em 0
+ padding 1.6em
+ background-color #eee
+ h4
+ margin-top 0
+ figure, p
+ &:last-child
+ margin-bottom 0
+ padding-bottom 0
+ summary
+ outline none
+ cursor pointer
diff --git a/docs/.vuepress/theme/styles/index.styl b/docs/.vuepress/theme/styles/index.styl
new file mode 100644
index 00000000..976bfb04
--- /dev/null
+++ b/docs/.vuepress/theme/styles/index.styl
@@ -0,0 +1,201 @@
+@require './config'
+@require './code'
+@require './custom-blocks'
+@require './arrow'
+@require './wrapper'
+@require './toc'
+
+html, body
+ padding 0
+ margin 0
+ background-color #fff
+
+body
+ font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif
+ -webkit-font-smoothing antialiased
+ -moz-osx-font-smoothing grayscale
+ font-size 16px
+ color $textColor
+
+.page
+ padding-left $sidebarWidth
+
+.navbar
+ position fixed
+ z-index 20
+ top 0
+ left 0
+ right 0
+ height $navbarHeight
+ background-color #fff
+ box-sizing border-box
+ border-bottom 1px solid $borderColor
+
+.sidebar-mask
+ position fixed
+ z-index 9
+ top 0
+ left 0
+ width 100vw
+ height 100vh
+ display none
+
+.sidebar
+ font-size 16px
+ background-color #fff
+ width $sidebarWidth
+ position fixed
+ z-index 10
+ margin 0
+ top $navbarHeight
+ left 0
+ bottom 0
+ box-sizing border-box
+ border-right 1px solid $borderColor
+ overflow-y auto
+
+{$contentClass}:not(.custom)
+ @extend $wrapper
+ > *:first-child
+ margin-top $navbarHeight
+
+ a:hover
+ text-decoration underline
+
+ p.demo
+ padding 1rem 1.5rem
+ border 1px solid #ddd
+ border-radius 4px
+
+ img
+ max-width 100%
+
+{$contentClass}.custom
+ padding 0
+ margin 0
+
+ img
+ max-width 100%
+
+a
+ font-weight 500
+ color $accentColor
+ text-decoration none
+
+p a code
+ font-weight 400
+ color $accentColor
+
+kbd
+ background #eee
+ border solid 0.15rem #ddd
+ border-bottom solid 0.25rem #ddd
+ border-radius 0.15rem
+ padding 0 0.15em
+
+blockquote
+ font-size 1rem
+ color #999;
+ border-left .2rem solid #dfe2e5
+ margin 1rem 0
+ padding .25rem 0 .25rem 1rem
+
+ & > p
+ margin 0
+
+ul, ol
+ padding-left 1.2em
+
+strong
+ font-weight 600
+
+h1, h2, h3, h4, h5, h6
+ font-weight 600
+ line-height 1.25
+
+ {$contentClass}:not(.custom) > &
+ margin-top (0.5rem - $navbarHeight)
+ padding-top ($navbarHeight + 1rem)
+ margin-bottom 0
+
+ &:first-child
+ margin-top -1.5rem
+ margin-bottom 1rem
+
+ + p, + pre, + .custom-block
+ margin-top 2rem
+
+ &:hover .header-anchor
+ opacity: 1
+
+h1
+ font-size 2.2rem
+
+h2
+ font-size 1.65rem
+ padding-bottom .3rem
+ border-bottom 1px solid $borderColor
+
+h3
+ font-size 1.35rem
+
+a.header-anchor
+ font-size 0.85em
+ float left
+ margin-left -0.87em
+ padding-right 0.23em
+ margin-top 0.125em
+ opacity 0
+
+ &:hover
+ text-decoration none
+
+code, kbd, .line-number
+ font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace
+
+p, ul, ol
+ line-height 1.7
+
+hr
+ border 0
+ border-top 1px solid $borderColor
+
+table
+ border-collapse collapse
+ margin 1rem 0
+ display: block
+ overflow-x: auto
+
+tr
+ border-top 1px solid #dfe2e5
+
+ &:nth-child(2n)
+ background-color #f6f8fa
+
+th, td
+ border 1px solid #dfe2e5
+ padding .6em 1em
+
+.theme-container
+ &.sidebar-open
+ .sidebar-mask
+ display: block
+
+ &.no-navbar
+ {$contentClass}:not(.custom) > h1, h2, h3, h4, h5, h6
+ margin-top 1.5rem
+ padding-top 0
+
+ .sidebar
+ top 0
+
+
+@media (min-width: ($MQMobile + 1px))
+ .theme-container.no-sidebar
+ .sidebar
+ display none
+
+ .page
+ padding-left 0
+
+@require 'mobile.styl'
diff --git a/docs/.vuepress/theme/styles/mobile.styl b/docs/.vuepress/theme/styles/mobile.styl
new file mode 100644
index 00000000..f5bd3273
--- /dev/null
+++ b/docs/.vuepress/theme/styles/mobile.styl
@@ -0,0 +1,37 @@
+@require './config'
+
+$mobileSidebarWidth = $sidebarWidth * 0.82
+
+// narrow desktop / iPad
+@media (max-width: $MQNarrow)
+ .sidebar
+ font-size 15px
+ width $mobileSidebarWidth
+ .page
+ padding-left $mobileSidebarWidth
+
+// wide mobile
+@media (max-width: $MQMobile)
+ .sidebar
+ top 0
+ padding-top $navbarHeight
+ transform translateX(-100%)
+ transition transform .2s ease
+ .page
+ padding-left 0
+ .theme-container
+ &.sidebar-open
+ .sidebar
+ transform translateX(0)
+ &.no-navbar
+ .sidebar
+ padding-top: 0
+
+// narrow mobile
+@media (max-width: $MQMobileNarrow)
+ h1
+ font-size 1.9rem
+ {$contentClass}
+ div[class*="language-"]
+ margin 0.85rem -1.5rem
+ border-radius 0
diff --git a/docs/.vuepress/theme/styles/toc.styl b/docs/.vuepress/theme/styles/toc.styl
new file mode 100644
index 00000000..d3e71069
--- /dev/null
+++ b/docs/.vuepress/theme/styles/toc.styl
@@ -0,0 +1,3 @@
+.table-of-contents
+ .badge
+ vertical-align middle
diff --git a/docs/.vuepress/theme/styles/wrapper.styl b/docs/.vuepress/theme/styles/wrapper.styl
new file mode 100644
index 00000000..a99262c7
--- /dev/null
+++ b/docs/.vuepress/theme/styles/wrapper.styl
@@ -0,0 +1,9 @@
+$wrapper
+ max-width $contentWidth
+ margin 0 auto
+ padding 2rem 2.5rem
+ @media (max-width: $MQNarrow)
+ padding 2rem
+ @media (max-width: $MQMobileNarrow)
+ padding 1.5rem
+
diff --git a/docs/.vuepress/theme/util/index.js b/docs/.vuepress/theme/util/index.js
new file mode 100644
index 00000000..92fcd3b3
--- /dev/null
+++ b/docs/.vuepress/theme/util/index.js
@@ -0,0 +1,244 @@
+export const hashRE = /#.*$/
+export const extRE = /\.(md|html)$/
+export const endingSlashRE = /\/$/
+export const outboundRE = /^[a-z]+:/i
+
+export function normalize (path) {
+ return decodeURI(path)
+ .replace(hashRE, '')
+ .replace(extRE, '')
+}
+
+export function getHash (path) {
+ const match = path.match(hashRE)
+ if (match) {
+ return match[0]
+ }
+}
+
+export function isExternal (path) {
+ return outboundRE.test(path)
+}
+
+export function isMailto (path) {
+ return /^mailto:/.test(path)
+}
+
+export function isTel (path) {
+ return /^tel:/.test(path)
+}
+
+export function ensureExt (path) {
+ if (isExternal(path)) {
+ return path
+ }
+ const hashMatch = path.match(hashRE)
+ const hash = hashMatch ? hashMatch[0] : ''
+ const normalized = normalize(path)
+
+ if (endingSlashRE.test(normalized)) {
+ return path
+ }
+ return normalized + '.html' + hash
+}
+
+export function isActive (route, path) {
+ const routeHash = decodeURIComponent(route.hash)
+ const linkHash = getHash(path)
+ if (linkHash && routeHash !== linkHash) {
+ return false
+ }
+ const routePath = normalize(route.path)
+ const pagePath = normalize(path)
+ return routePath === pagePath
+}
+
+export function resolvePage (pages, rawPath, base) {
+ if (isExternal(rawPath)) {
+ return {
+ type: 'external',
+ path: rawPath
+ }
+ }
+ if (base) {
+ rawPath = resolvePath(rawPath, base)
+ }
+ const path = normalize(rawPath)
+ for (let i = 0; i < pages.length; i++) {
+ if (normalize(pages[i].regularPath) === path) {
+ return Object.assign({}, pages[i], {
+ type: 'page',
+ path: ensureExt(pages[i].path)
+ })
+ }
+ }
+ console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`)
+ return {}
+}
+
+function resolvePath (relative, base, append) {
+ const firstChar = relative.charAt(0)
+ if (firstChar === '/') {
+ return relative
+ }
+
+ if (firstChar === '?' || firstChar === '#') {
+ return base + relative
+ }
+
+ const stack = base.split('/')
+
+ // remove trailing segment if:
+ // - not appending
+ // - appending to trailing slash (last segment is empty)
+ if (!append || !stack[stack.length - 1]) {
+ stack.pop()
+ }
+
+ // resolve relative path
+ const segments = relative.replace(/^\//, '').split('/')
+ for (let i = 0; i < segments.length; i++) {
+ const segment = segments[i]
+ if (segment === '..') {
+ stack.pop()
+ } else if (segment !== '.') {
+ stack.push(segment)
+ }
+ }
+
+ // ensure leading slash
+ if (stack[0] !== '') {
+ stack.unshift('')
+ }
+
+ return stack.join('/')
+}
+
+/**
+ * @param { Page } page
+ * @param { string } regularPath
+ * @param { SiteData } site
+ * @param { string } localePath
+ * @returns { SidebarGroup }
+ */
+export function resolveSidebarItems (page, regularPath, site, localePath) {
+ const { pages, themeConfig } = site
+
+ const localeConfig = localePath && themeConfig.locales
+ ? themeConfig.locales[localePath] || themeConfig
+ : themeConfig
+
+ const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar
+ if (pageSidebarConfig === 'auto') {
+ return resolveHeaders(page)
+ }
+
+ const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar
+ if (!sidebarConfig) {
+ return []
+ } else {
+ const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig)
+ if (config === 'auto') {
+ return resolveHeaders(page)
+ }
+ return config
+ ? config.map(item => resolveItem(item, pages, base))
+ : []
+ }
+}
+
+/**
+ * @param { Page } page
+ * @returns { SidebarGroup }
+ */
+function resolveHeaders (page) {
+ const headers = groupHeaders(page.headers || [])
+ return [{
+ type: 'group',
+ collapsable: false,
+ title: page.title,
+ path: null,
+ children: headers.map(h => ({
+ type: 'auto',
+ title: h.title,
+ basePath: page.path,
+ path: page.path + '#' + h.slug,
+ children: h.children || []
+ }))
+ }]
+}
+
+export function groupHeaders (headers) {
+ // group h3s under h2
+ headers = headers.map(h => Object.assign({}, h))
+ let lastH2
+ headers.forEach(h => {
+ if (h.level === 2) {
+ lastH2 = h
+ } else if (lastH2) {
+ (lastH2.children || (lastH2.children = [])).push(h)
+ }
+ })
+ return headers.filter(h => h.level === 2)
+}
+
+export function resolveNavLinkItem (linkItem) {
+ return Object.assign(linkItem, {
+ type: linkItem.items && linkItem.items.length ? 'links' : 'link'
+ })
+}
+
+/**
+ * @param { Route } route
+ * @param { Array | Array | [link: string]: SidebarConfig } config
+ * @returns { base: string, config: SidebarConfig }
+ */
+export function resolveMatchingConfig (regularPath, config) {
+ if (Array.isArray(config)) {
+ return {
+ base: '/',
+ config: config
+ }
+ }
+ for (const base in config) {
+ if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) {
+ return {
+ base,
+ config: config[base]
+ }
+ }
+ }
+ return {}
+}
+
+function ensureEndingSlash (path) {
+ return /(\.html|\/)$/.test(path)
+ ? path
+ : path + '/'
+}
+
+function resolveItem (item, pages, base, groupDepth = 1) {
+ if (typeof item === 'string') {
+ return resolvePage(pages, item, base)
+ } else if (Array.isArray(item)) {
+ return Object.assign(resolvePage(pages, item[0], base), {
+ title: item[1]
+ })
+ } else {
+ const children = item.children || []
+ if (children.length === 0 && item.path) {
+ return Object.assign(resolvePage(pages, item.path, base), {
+ title: item.title
+ })
+ }
+ return {
+ type: 'group',
+ path: item.path,
+ title: item.title,
+ sidebarDepth: item.sidebarDepth,
+ initialOpenGroupIndex: item.initialOpenGroupIndex,
+ children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)),
+ collapsable: item.collapsable !== false
+ }
+ }
+}
diff --git a/docs/.vuepress/version-configs/1.5.x.js b/docs/.vuepress/version-configs/1.5.x.js
new file mode 100644
index 00000000..467f27a2
--- /dev/null
+++ b/docs/.vuepress/version-configs/1.5.x.js
@@ -0,0 +1,101 @@
+/* set version */
+let version = '1.5.x';
+
+/* version prefix setter */
+function setVersionPrefix(children) {
+ if (children.constructor === Array) {
+ return children.map(child => {
+ child[0] = `/${version}/${child[0]}`;
+ return child;
+ });
+ }
+ return `/${version}/${children}`;
+}
+
+/* module export */
+module.exports = [
+ {
+ title: 'Prologue',
+ path: setVersionPrefix('prologue'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['prologue/upgrade-guide', 'Upgrade Guide'],
+ ['prologue/contribution-guide', ' Contribution Guide']
+ ])
+ },
+ {
+ title: 'Introduction',
+ path: setVersionPrefix('introduction'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['introduction/requirements', 'Requirements'],
+ ['introduction/installation', 'Installation'],
+ ['introduction/docker', 'Docker']
+ ])
+ },
+ {
+ title: 'Architecture concepts',
+ path: setVersionPrefix('architecture'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['architecture/packages', 'Packages'],
+ ['architecture/frontend', 'Frontend'],
+ ['architecture/theme', 'Theme'],
+ ['architecture/performance', 'Performance'],
+ ['architecture/repository-pattern', 'Repository Pattern'],
+ ['architecture/modular-design', 'Modular Design']
+ ])
+ },
+ {
+ title: 'Package Development',
+ path: setVersionPrefix('packages'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['packages/create-package', 'Getting Started'],
+ ['packages/create-migrations', 'Migrations'],
+ ['packages/create-models', 'Models'],
+ ['packages/store-data-through-repositories', 'Repository'],
+ ['packages/routes', 'Routes'],
+ ['packages/controllers', 'Controllers'],
+ ['packages/views', 'Views'],
+ ['packages/localization', 'Localization'],
+ ['packages/layouts', 'Layouts'],
+ ['packages/assets', 'Assets'],
+ ['packages/add-menu-in-admin', 'Admin Menu'],
+ ['packages/customize-hompepage-menu.md', 'Homepage Menu'],
+ ['packages/validation', 'Validation'],
+ ['packages/datagrid', 'DataGrid'],
+ ['packages/create-acl', 'Access Control List'],
+ ['packages/create-custom-configuration', 'Custom Configuration']
+ ])
+ },
+ {
+ title: 'Digging Deeper',
+ path: setVersionPrefix('advanced'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['advanced/create-shipping-method', 'Shipping Method'],
+ ['advanced/create-payment-method', 'Payment Method'],
+ ['advanced/create-product-type', 'Product Type'],
+ ['advanced/events', 'Events Listeners'],
+ ['advanced/helpers', 'Helpers'],
+ ['advanced/override-core-model', 'Override Core Models'],
+ ['advanced/render-event', 'View Render Event'],
+ ['advanced/change-email-template.md', 'Email Template'],
+ ['advanced/indexing-products-to-elasticsearch.md', 'Configure Elasticsearch'],
+ ['advanced/security-practice', 'Best Security Practices'],
+ ])
+ },
+ {
+ title: 'Themes',
+ path: setVersionPrefix('themes'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['themes/create-theme', 'Store Theme'],
+ ['themes/create-admin-theme', 'Admin Theme'],
+ ['themes/notification', 'Real Time Notification'],
+ ['themes/integrate-image-search-in-theme', 'Image Search']
+ ])
+ }
+
+]
diff --git a/docs/.vuepress/version-configs/1.x.js b/docs/.vuepress/version-configs/1.x.js
new file mode 100644
index 00000000..04d74b5b
--- /dev/null
+++ b/docs/.vuepress/version-configs/1.x.js
@@ -0,0 +1,158 @@
+/* set version */
+let version = '1.x';
+
+/* version prefix setter */
+function setVersionPrefix(children) {
+ if (children.constructor === Array) {
+ return children.map(child => {
+ child[0] = `/${version}/${child[0]}`;
+ return child;
+ });
+ }
+ return `/${version}/${children}`;
+}
+
+/* module export */
+module.exports = [
+ {
+ title: 'Introduction',
+ path: setVersionPrefix('introduction'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['introduction/requirements', 'Requirements'],
+ ['introduction/installation', 'Installation'],
+ ['introduction/upgrade-to-latest-bagisto', 'Upgrade Bagisto'],
+ ['introduction/docker', 'Docker']
+
+ ])
+ },
+ {
+ title: 'Package Development',
+ path: setVersionPrefix('packages'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['packages/create-package', 'Create a new package'],
+ ['packages/create-migrations', 'Create migrations'],
+ ['packages/add-menu-in-admin', 'Add menu in admin'],
+ ['packages/create-acl', 'Access control list'],
+ ['packages/create-custom-configuration', 'Create custom configuration'],
+ ['packages/create-models', 'Create models'],
+ ['packages/store-data-through-repositories', 'Store data through repositories'],
+ ])
+ },
+ {
+ title: 'Advanced Topics',
+ path: setVersionPrefix('advanced'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['advanced/create-shipping-method', 'Create a shipping method'],
+ ['advanced/create-payment-method', 'Create a payment method'],
+ ['advanced/create-product-type', 'Create your own product type'],
+ ['advanced/datagrid', 'DataGrid'],
+ ['advanced/events', 'Events'],
+ ['advanced/helpers', 'Helpers'],
+ ['advanced/override-core-model', 'Override core models'],
+ ['advanced/render-event', 'View render event'],
+ ['advanced/indexing-products-to-elasticsearch.md', 'Indexing products to Elasticsearch'],
+ ['advanced/security-practice', 'Best Security Practices'],
+ ])
+ },
+ {
+ title: 'Themes',
+ path: setVersionPrefix('themes'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['themes/tracer', 'Blade file tracer'],
+ ['themes/create-theme', 'Create a store theme'],
+ ['themes/create-admin-theme', 'Create an admin theme'],
+ ['themes/change-email-template.md', 'Change email template'],
+ ['themes/customize-hompepage-menu.md', 'Customize homepage menu'],
+ ['themes/integrate-image-search-in-theme', 'Integrate image search in theme']
+ ])
+ },{
+ title: 'Admin Theme',
+ path: setVersionPrefix('admin-theme'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['admin-theme/notification', 'Enable real time notification'],
+ ])
+ },{
+ title: 'Translations',
+ path: setVersionPrefix('translations/translation-based-on-locale'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['translations/translation-based-on-locale', 'Translation based on locale'],
+ ['translations/change-the-language-of-error-validations-on-your-store', 'Change the language of error validations on your store']
+ ])
+ },
+ {
+ title: 'User Guides',
+ path: setVersionPrefix('user-guides'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['user-guides/tax-rates', 'Tax Rates'],
+ ['user-guides/cart-rule', 'Cart rules'],
+ ['user-guides/social-auth', 'Social Authentication']
+ ])
+ },
+ {
+ title: 'Bagisto Web API',
+ path: setVersionPrefix('api'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['api/getting-started-with-the-api', 'Authentication'],
+ ['api/customers', 'Customers'],
+ ['api/locales', 'Locales'],
+ ['api/addresses', 'Addresses'],
+ ['api/products', 'Products'],
+ ['api/categories', 'Categories'],
+ ['api/attributes', 'Attributes'],
+ ['api/attribute-families', 'Attribute Families'],
+ ['api/cart', 'Shopping Cart'],
+ ['api/orders', 'Orders'],
+ ['api/invoices', 'Invoices'],
+ ['api/shipments', 'Shipments'],
+ ['api/transactions', 'Transactions'],
+ ['api/reviews', 'Reviews'],
+ ['api/wishlists', 'Wishlists'],
+ ])
+ },
+ {
+ title: 'Bagisto GraphQL Admin API',
+ path: setVersionPrefix('graphql-admin-api'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['graphql-admin-api/installation', 'Installation'],
+ ['graphql-admin-api/getting-started-with-the-api.md', 'Authentication'],
+ ['graphql-admin-api/settings.md', 'Settings'],
+ ['graphql-admin-api/cms.md', 'CMS'],
+ ['graphql-admin-api/velocity.md', 'Velocity'],
+ ['graphql-admin-api/customers.md', 'Customers'],
+ ['graphql-admin-api/promotions.md', 'Promotions'],
+ ['graphql-admin-api/products.md', 'Products'],
+ ['graphql-admin-api/categories.md', 'Categories'],
+ ['graphql-admin-api/attributes.md', 'Attributes'],
+ ['graphql-admin-api/attribute-groups.md', 'Attribute Groups'],
+ ['graphql-admin-api/attribute-families.md', 'Attribute Families'],
+ ['graphql-admin-api/sales.md', 'Sales'],
+ ])
+ },
+ {
+ title: 'Bagisto GraphQL Shop API',
+ path: setVersionPrefix('graphql-shop-api'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['graphql-admin-api/installation', 'Installation'],
+ ['graphql-shop-api/getting-started-with-the-api.md', 'Authentication'],
+ ['graphql-shop-api/addresses.md', 'Addresses'],
+ ['graphql-shop-api/orders.md', 'Orders'],
+ ['graphql-shop-api/reviews.md', 'Reviews'],
+ ['graphql-shop-api/wishlists.md', 'Wishlists'],
+ ['graphql-shop-api/compare.md', 'Compare'],
+ ['graphql-shop-api/downloadable-links.md', 'Downloadable Links'],
+ ['graphql-shop-api/cart.md', 'Cart'],
+ ['graphql-shop-api/checkout.md', 'Checkout Process'],
+ ['graphql-shop-api/homepage.md', 'Home Page'],
+ ])
+ },
+]
\ No newline at end of file
diff --git a/docs/.vuepress/version-configs/2.x.js b/docs/.vuepress/version-configs/2.x.js
new file mode 100644
index 00000000..0431f038
--- /dev/null
+++ b/docs/.vuepress/version-configs/2.x.js
@@ -0,0 +1,30 @@
+/* set version */
+let version = '2.x';
+
+/* version prefix setter */
+function setVersionPrefix(children) {
+ if (children.constructor === Array) {
+ return children.map(child => {
+ child[0] = `/${version}/${child[0]}`;
+ return child;
+ });
+ }
+ return `/${version}/${children}`;
+}
+
+/* module export */
+module.exports = [
+ {
+ title: 'Product Types',
+ path: setVersionPrefix('products'),
+ collapsable: true,
+ children: setVersionPrefix([
+ ['products/simple', 'Simple Product'],
+ ['products/configurable', 'Configurable Product'],
+ ['products/virtual', 'Virtual Product'],
+ ['products/bundle', 'Bundle Product'],
+ ['products/grouped', 'Grouped Product'],
+ ['products/downloadable', 'Downloadable Product'],
+ ])
+ }
+]
diff --git a/docs/1.5.x/advanced/README.md b/docs/1.5.x/advanced/README.md
new file mode 100644
index 00000000..d25989dd
--- /dev/null
+++ b/docs/1.5.x/advanced/README.md
@@ -0,0 +1,33 @@
+# Digging Deeper
+
+Welcome to the "Digging Deeper" section of the Bagisto documentation. Here, we will explore various advanced topics related to Bagisto, which will enable you to customize and extend your e-commerce platform to suit your specific needs.
+
+We expect you to have knowledge of creating packages in Laravel. If you are new to package development, we recommend referring to the [Package Development](../packages/create-package.html) section for a primer on creating and managing packages in Laravel.
+
+### Creating Payment Methods
+
+Bagisto provides a flexible and configurable system for integrating different payment methods into your e-commerce store. We will guide you through the process of setting up and configuring payment methods, allowing you to offer a variety of options to your customers while ensuring a seamless and secure checkout experience.
+
+### Product Types
+
+Bagisto supports different types of products, allowing you to showcase and sell a wide range of items. We will delve into the details of configuring and managing product types, giving you the ability to define specific attributes and behaviors for each product category.
+
+### Shipping Methods
+
+Efficient and reliable shipping is crucial for any e-commerce business. Bagisto offers robust features for managing shipping methods, enabling you to define various shipping options, rates, and rules based on factors such as location, weight, or order value. We will explain how to configure and customize shipping methods to streamline your order fulfillment process.
+
+### Events and Event Handlers
+
+Events and event handlers provide a powerful way to extend the functionality of Bagisto by allowing you to react to specific actions or triggers within the application. We will show you how to utilize events and event handlers effectively, enabling you to integrate custom functionalities and automate processes.
+
+### Helpers
+
+Bagisto includes a comprehensive set of helper functions that simplify common development tasks and enhance productivity. We will explore the various helper functions available, explaining their purpose and usage to assist you in writing clean and efficient code.
+
+### Indexing through Elastic
+
+To optimize search performance, Bagisto integrates with Elasticsearch, a highly scalable search engine. We will guide you through the process of indexing your data using Elastic, improving the search functionality of your e-commerce store and providing a seamless search experience for your customers.
+
+### Overriding Core Models
+
+Sometimes, you may need to modify or extend the default behavior of Bagisto's core models to accommodate your specific business requirements. We will demonstrate how to override core models effectively, enabling you to customize the behavior of Bagisto without modifying the underlying codebase.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/change-email-template.md b/docs/1.5.x/advanced/change-email-template.md
new file mode 100644
index 00000000..2dd7d406
--- /dev/null
+++ b/docs/1.5.x/advanced/change-email-template.md
@@ -0,0 +1,106 @@
+# Email Template
+
+[[TOC]]
+
+## Introduction
+
+In this section, we will explain how to customize the email templates in Bagisto. Customizing email templates allows you to personalize the appearance of your emails according to your preferences.
+
+## Email Template Flow
+
+Before we dive into template customization, let's understand how email templates work in Bagisto.
+
+Bagisto provides various mail notification classes, such as **`CancelOrderAdminNotification`** and **`NewCustomerNotification`**, located in the **`Webkul\Admin\Mail`** namespace. Let's take the **`CancelOrderAdminNotification`** class as an example.
+
+```php
+order = $order;
+ }
+
+ /**
+ * Build.
+ *
+ * @return void
+ */
+ public function build()
+ {
+ return $this->from(core()->getSenderEmailDetails()['email'], core()->getSenderEmailDetails()['name'])
+ ->to(core()->getAdminEmailDetails()['email'])
+ ->subject(trans('shop::app.mail.order.cancel.subject'))
+ ->view('shop::emails.sales.order-cancel-admin');
+ }
+}
+```
+
+In the **`build()`** method of the above class, you can see that the main view file, **`view('shop::emails.sales.order-cancel-admin')`**, is loaded from the shop package.
+
+Now, let's explore the view file mentioned in **`view('shop::emails.sales.order-cancel-admin')`**. If you check the file at the path **`packages/Webkul/Shop/src/Resources/views/emails/sales/order-cancel-admin.blade.php`**, you will find it. This view file uses the main layout component **`shop::emails.layouts.master`**.
+
+```php
+@component('shop::emails.layouts.master')
+ ...
+@endcomponent
+```
+
+This layout component is responsible for the overall email layout. If desired, you can explore this file as well. Now, let's proceed to learn how to change these email templates.
+
+## Changing Email Template
+
+To customize the email template, the recommended approach is to override the package's view. Since all email views are defined in the shop package, we need to override the view within the shop package.
+
+Here's how you can override the view for the same file we mentioned above, **`view('shop::emails.sales.order-cancel-admin')`**.
+
+Bagisto registers two locations for views: the application's **`resources/themes`** directory specified in **`config/themes.php`**, and the directory you specify. If you are using the default theme, **`shop`** package, Bagisto will first check if a custom version of the view exists in the **`resources/themes/default`** directory. If the view has not been customized, Bagisto will then search the package's view directory.
+
+To override the view, create the same directory structure in the application's **`resources/themes/default`** directory:
+
+```
+- resources/
+ └── themes/
+ └── default/
+ └── views/
+ └── emails/
+ └── sales/
+ └── order-cancel-admin.blade.php
+```
+
+For example, create a file named **`order-cancel-admin.blade.php`** within the **`sales`** directory, and modify its content as desired:
+
+```blade
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Laborum porro cumque numquam neque dicta quo, accusantium, perferendis sed beatae nesc
+
+ iunt eum impedit vel doloribus dolor excepturi vero tenetur perspiciatis saepe?
+```
+
+Now you can test the modified email template.
+
+## Email Template Sample
+
+![Email Template Sample](../../assets/1.5.x/images/advanced-topics/mail-sample.png)
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/create-payment-method.md b/docs/1.5.x/advanced/create-payment-method.md
new file mode 100644
index 00000000..822333b1
--- /dev/null
+++ b/docs/1.5.x/advanced/create-payment-method.md
@@ -0,0 +1,220 @@
+# Payment Method
+
+[[TOC]]
+
+## Introduction
+
+Bagisto eases the task of creating payment methods, making it simple for both novice and professional developers.
+
+The diversity of payment methods provides customers with various options for payment when they proceed to checkout. Moreover, offering multiple payment methods is a great strategy to reach out to the global marketplace.
+
+## Using Bagisto Package Generator
+
+To create a payment method package, follow these commands in the Bagisto root directory:
+
+- If the package directory is not present:
+
+ ```sh
+ php artisan package:make-payment-method Webkul/Blog
+ ```
+
+- If the package directory is already present, you can use the force command to overwrite it. Simply add the **`--force`** flag:
+
+ ```sh
+ php artisan package:make-payment-method Webkul/Blog --force
+ ```
+
+ These commands will generate the entire directory structure automatically, saving you from manual setup.
+
+## Manually Setting Up All Files
+
+1. To create your payment method, follow these steps to set up the respective directory structure:
+
+ ```
+ - Webkul/
+ └── Blog/
+ └── src/
+ ├── ...
+ ├── Config/
+ │ ├── system.php
+ │ └── paymentmethods.php
+ ├── Payment/
+ │ └── Stripe.php
+ └── Providers/
+ └── StripeServiceProvider.php
+ ```
+
+2. The **`Config`** folder contains application configuration files. Create two files, **`system.php`** and **`paymentmethods.php`**, within the **`Config`** folder. In the **`system.php`** file, include the following array keys:
+
+ ```php
+ 'sales.paymentmethods.stripe',
+ 'name' => 'Stripe',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'title',
+ 'title' => 'admin::app.admin.system.title',
+ 'type' => 'text',
+ 'validation' => 'required',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ], [
+ 'name' => 'description',
+ 'title' => 'admin::app.admin.system.description',
+ 'type' => 'textarea',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ], [
+ 'name' => 'active',
+ 'title' => 'admin::app.admin.system.status',
+ 'type' => 'boolean',
+ 'validation' => 'required',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ]
+ ]
+ ]
+ ];
+ ```
+ - **`key`**: A unique value for the configuration, concatenated with a dot (`.`) operator.
+ - **`name`**: The placeholder value for the configuration. It is recommended to use translations in Bagisto.
+ - **`sort`**: The position of the configuration menu.
+ - **`fields`**: An array containing the custom configurations and fields for the payment method. The example includes three arrays for **`title`**, **`description`**, and **`status`**. You can add more arrays for additional settings.
+
+3. In the **`paymentmethods.php`** file, add the following content:
+
+ ```php
+ [
+ 'code' => 'stripe',
+ 'title' => 'Stripe',
+ 'description' => 'Stripe',
+ 'class' => 'Webkul\Blog\Payment\Stripe',
+ 'active' => true,
+ 'sort' => 1,
+ ],
+ ];
+ ```
+ - **`code`**: A text representing the payment method.
+ - **`title`**: The name of the payment method.
+ - **`description`**: A brief description of the payment method.
+ - **`class`**: The namespace of the class where the payment method functions are defined.
+ - **`active`**: A boolean value (`true` or `false`) to enable or disable the module.
+ - **`sort`**: The position of the payment method.
+
+4. In the **`Stripe.php`** file within the **`Payment`** directory, add the following code:
+
+ ```php
+ registerConfig();
+ }
+
+ /**
+ * Register package config.
+ *
+ * @return void
+ */
+ protected function registerConfig()
+ {
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/paymentmethods.php', 'paymentmethods'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ```
+
+2. Next, add your payment method namespace to the **`psr-4`** key in the **`composer.json`** file located in the Bagisto root directory:
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ // Other PSR-4 namespaces
+ "Webkul\\Blog\\": "packages/Webkul/Blog/src"
+ }
+ }
+ ```
+
+3. Register your service provider in the **`config/app.php`** file, also located in the Bagisto root directory:
+
+ ```php
+ ServiceProvider::defaultProviders()->merge([
+ // Other service providers
+ Webkul\Blog\Providers\StripeServiceProvider::class,
+ ])->toArray(),
+
+ // Other configuration options
+ ];
+ ```
+
+4. After making these changes, run the following commands:
+
+ ```sh
+ composer dump-autoload
+ ```
+
+ ```sh
+ php artisan config:cache
+ ```
+
+ If you encounter any issues with **`composer dump-autoload`**, delete all files from the **`bootstrap/cache`** directory and run **`composer dump-autoload`** again.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/create-product-type.md b/docs/1.5.x/advanced/create-product-type.md
new file mode 100644
index 00000000..d6372ccc
--- /dev/null
+++ b/docs/1.5.x/advanced/create-product-type.md
@@ -0,0 +1,80 @@
+# Product Type
+
+[[TOC]]
+
+## Introduction
+
+Bagisto provides several default product types, including simple, configurable, virtual, grouped, downloadable, bundled, and bookings. However, if these default product types do not meet your requirements, you can create your own custom product types.
+
+## Creating a New Product Type
+
+To create a new product type in Bagisto, follow these steps:
+
+**Note**: In this example, we will create a new product type called "coupon".
+
+1. Create your own package. If you need assistance with package development, you can refer to the [Package Development](../packages) section.
+
+2. Inside the **Config** folder of your package, create a file named **`product_types.php`**.
+
+3. Add the following code to the **`product_types.php`** file. This code will define the new product type and its properties:
+
+ ```php
+ [
+ 'key' => 'coupon',
+ 'name' => 'Coupon',
+ 'class' => 'Webkul\Blog\Type\Coupon',
+ 'sort' => 7
+ ],
+ ];
+ ```
+
+### Merging the Configuration
+
+4. To merge the **`Config/product_types.php`** with the core product types configuration, use the **`mergeConfigFrom()`** method in the **`register()`** method of your service provider. For example, in the **`CouponServiceProvider.php`** file:
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/product_types.php', 'product_types'
+ );
+ }
+ }
+ ```
+
+5. In the code snippet above, notice the **`class`** key mentioned in step 3. This key specifies the class that loads the coupon product type. Create a file named **`Coupon.php`** within your package under the **`src/Type`** folder, and add the following code:
+
+ ```php
+ [
+ 'code' => 'blog',
+ 'title' => 'Blog',
+ 'description' => 'Blog',
+ 'active' => true,
+ 'default_rate' => '10',
+ 'type' => 'per_unit',
+ 'class' => 'Webkul\Blog\Carriers\Blog',
+ ]
+ ];
+ ```
+
+ - **code**: A unique value used to refer to the particular shipping method.
+ - **title**: The label or name displayed in the user interface.
+ - **description**: Information about your shipping method.
+ - **active**: Enable or disable option for the shipping method.
+ - **default_rate**: The default rate value.
+ - **type**: Specifies whether the shipping method applies per unit or per order.
+ - **class**: The path and filename of the shipping method class (**`namespace\package-name\Carriers-folder\filename`**).
+
+3. Create a **`Carriers`** folder inside the **`src`** folder. Then, create a **`Blog.php`** file inside the **`Carriers`** folder.
+
+ ```
+ - Webkul
+ └── Blog/
+ └── src/
+ ├── ...
+ ├── Carriers/
+ │ └── Blog.php
+ └── Config/
+ ├── ...
+ └── carriers.php
+
+ ```
+
+4. Copy the following code into the **`Blog.php`** file:
+
+ ```php
+ isAvailable()) {
+ return false;
+ }
+
+ $object = new CartShippingRate;
+
+ $object->carrier = 'blog';
+ $object->carrier_title = $this->getConfigData('title');
+ $object->method = 'blog_blog';
+ $object->method_title = $this->getConfigData('title');
+ $object->method_description = $this->getConfigData('description');
+ $object->price = 0;
+ $object->base_price = 0;
+
+ if ($this->getConfigData('type') == 'per_unit') {
+ foreach ($cart->items as $item) {
+ if (
+ $this->getConfigData('base_amount') &&
+ $this->getConfigData('base_amount') > ($item->product->price)
+ ) {
+ continue;
+ }
+ if ($item->product->getTypeInstance()->isStockable()) {
+ $object->price += core()->convertPrice($this->getConfigData('default_rate')) * $item->quantity;
+ $object->base_price += $this->getConfigData('default_rate') * $item->quantity;
+ }
+ }
+ } else {
+ if (
+ $this->getConfigData('base_amount') &&
+ $this->getConfigData('base_amount') > ($cart->sub_total)
+ ) {
+ return false;
+ }
+ $object->price = core()->convertPrice($this->getConfigData('default_rate'));
+ $object->base_price = $this->getConfigData('default_rate');
+ }
+
+ return $object;
+ }
+ }
+ ```
+
+ The **`Blog.php`** file extends the **`AbstractShipping`** class defined at **`Webkul\Shipping\Carriers\AbstractShipping`**. In this file, you can write all the operations needed for your shipping method. To render the shipping methods in the checkout process, define the **`calculate()`** method within the **`Blog.php`** file and return the shipping rate, title, and description within a **`CartShippingRate`** object.
+
+5. After creating all the necessary files and configurations, create a form that will appear in the configuration section. Create a **`system.php`** file in the **`src/Config`** path and add the following code to it:
+
+ ```php
+ 'sales.carriers.blog',
+ 'name' => 'admin::app.admin.system.blog-shipping',
+ 'sort' => 2,
+ 'fields' => [
+ [
+ 'name' => 'title',
+ 'title' => 'admin::app.admin.system.title',
+ 'type' => 'depends',
+ 'depend' => 'active:1',
+ 'validation' => 'required_if:active,1',
+ 'channel_based' => true,
+ 'locale_based' => true
+ ], [
+ 'name' => 'description',
+ 'title' => 'admin::app.admin.system.description',
+ 'type' => 'textarea',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'default_rate',
+ 'title' => 'admin::app.admin.system.rate',
+ 'type' => 'depends',
+ 'depend' => 'active:1',
+ 'validation' => 'required_if:active,1',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'base_amount',
+ 'title' => 'admin::app.admin.system.minimum-amount',
+ 'type' => 'text',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'type',
+ 'title' => 'admin::app.admin.system.type',
+ 'type' => 'select',
+ 'options' => [
+ [
+ 'title' => 'Per Unit',
+ 'value' => 'per_unit',
+ ], [
+ 'title' => 'Per Order',
+ 'value' => 'per_order',
+ ],
+ ],
+ 'channel_based' => true,
+ 'locale_based' => false,
+ ], [
+ 'name' => 'active',
+ 'title' => 'admin::app.admin.system.status',
+ 'type' => 'boolean',
+ 'validation' => 'required',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ]
+ ]
+ ]
+ ```
+
+## Merge Configuration
+
+1. To merge all your configurations, modify the **`packages/Webkul/Blog/src/Providers/BlogServiceProvider.php`** file as follows:
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/carriers.php', 'carriers'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ```
+
+2. Add the namespace for your shipment method in the **`psr-4`** key of the **`composer.json`** file in the Bagisto root directory:
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ // Other PSR-4 namespaces
+ "Webkul\\Blog\\": "packages/Webkul/Blog/src"
+ }
+ }
+ ```
+
+3. Register your service provider in the **`config/app.php`** file located in the Bagisto root directory:
+
+ ```php
+ ServiceProvider::defaultProviders()->merge([
+ // Other service providers
+ Webkul\Blog\Providers\BlogServiceProvider::class,
+ ])->toArray(),
+
+ // Other configuration options
+ ];
+ ```
+
+4. After making these changes, run the following commands:
+
+ ```sh
+ composer dump-autoload
+ php artisan config:cache
+ ```
+
+ If you encounter an error with the **`composer dump-autoload`** command, try deleting all files in the **`bootstrap/cache`** directory and then running the command again.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/events.md b/docs/1.5.x/advanced/events.md
new file mode 100644
index 00000000..bcd0332c
--- /dev/null
+++ b/docs/1.5.x/advanced/events.md
@@ -0,0 +1,238 @@
+# Event Listeners
+
+[[TOC]]
+
+## Introduction
+
+Event Listeners in Bagisto are a way to implement the observer pattern, where listeners respond to events that occur in the application. Events can be thought of as announcements made by the application, and listeners are the actions taken in response to those announcements. All event classes in Bagisto are stored in the **Providers** folder, and the listeners are stored in the **Listeners** folder.
+
+## Creating an Event Class
+
+If you have the Bagisto Package Generator installed, you can use the following command to create a new event class in the **`packages/Webkul/Blog/src/Events`** directory:
+
+```sh
+php artisan package:make-event BlogEvent Webkul/Blog
+```
+
+If the event class already exists, you can use the **`--force`** option to overwrite it:
+
+```sh
+php artisan package:make-event BlogEvent Webkul/Blog --force
+```
+
+Alternatively, if you don't have the package generator, you can create the file manually.
+
+## Manually Registering Events
+
+In Bagisto, events are manually registered in the **`boot`** method of your **`EventServiceProvider.php`** file. Here is an example of how to register events:
+
+```php
+/**
+ * Register any other events for your application.
+ *
+ * @return void
+ */
+public function boot()
+{
+ //...
+
+ parent::boot();
+
+ Event::listen('event.name', 'path-upto-listener@function');
+}
+```
+
+## Manually Registering Listeners
+
+When registering events, you specify the listener function to be executed when an event is called. Here is an example of how to register a listener:
+
+```php
+class EventServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstrap services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ //...
+
+ Event::listen('checkout.order.save.after', 'Webkul\Admin\Listeners\Order@sendNewOrderMail');
+ }
+}
+```
+
+## Specifying Events
+
+In most CRUD operations, events are fired before and after the execution of a function. This allows listeners to perform additional operations before or after certain actions, such as product creation, update, or deletion.
+
+## Events Fired in Bagisto
+
+- Events fired in bagisto but not listened such that if any user wants to perform any action on event fire, then they may create listener file and perform the respective operation.
+
+ | Events name | Functionality|
+ | ------------------------------- | ------------- |
+ |core.configuration.save.after|This event will be fired after core configuration form data gets saved, then you may create a listener file and perform the respective operation when that event fires |
+ |core.configuration.save.after|This event will be fired after core configuration form data gets saved, then you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.add.before |This event will be fired before saving into the database of item added in checkout and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.add.after|This event will be fired after saving into the database of item added in checkout and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.update.before|This event will be fired before updating the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires |
+ |checkout.cart.item.update.after|This event will be fired after updating the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.delete.before|This event will be fired before deleting the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.delete.after|This event will be fired after deleting the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.delete.before|This event will be fired before deleting the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.delete.after|This event will be fired after deleting the database item of checkout table of respective passed **`id`** and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.move-to-wishlist.before|This event will be fired before adding cart item to wishlist added in checkout and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.item.move-to-wishlist.after|This event will be fired after adding cart item to wishlist added in checkout and you may create a listener file and perform the respective operation when that event fires|
+ |customer.registration.before|This event will be fired before registration of customer details and you may create a listener file and perform the respective operation when that event fires|
+ |customer.registration.after|This event will be fired after registration of customer details and you may create a listener file and perform the respective operation when that event fires|
+ |customer.after.login|This event will be fired after login of customer and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.create.before|This event will be fired before attribute family gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.create.after|This event will be fired after attribute family gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.update.before|This event will be fired before updating attribute family and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.update.after|This event will be fired after updating attribute family and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.delete.before|This event will be fired before deleting attribute family and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute_family.delete.after|This event will be fired after deleting attribute family and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.create.before|This event will be fired before attribute gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.create.after|This event will be fired after attribute gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.update.before|This event will be fired before attribute gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.update.after|This event will be fired after attribute gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.delete.before|This event will be fired before attribute gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.attribute.delete.after|This event will be fired after attribute gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.delete.after|This event will be fired after deleting category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.delete.before|This event will be fired before deleting category with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.delete.after|This event will be fired after deleting category with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.create.before|This event will be fired before creating category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.create.after|This event will be fired after creating category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.update.before|This event will be fired before updating category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.update.after|This event will be fired after updating category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.delete.before|This event will be fired before deleting category and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.category.delete.after|This event will be fired after deleting category and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.create.before|This event will be fired before channel gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.create.after|This event will be fired after channel gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.update.before|This event will be fired before channel gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.update.after|This event will be fired after channel gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.delete.before|This event will be fired before channel gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.channel.delete.after|This event will be fired after channel gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.create.before|This event will be fired before currency gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.create.after|This event will be fired after currency gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.update.before|This event will be fired before currency gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.update.after|This event will be fired after currency gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.delete.before|This event will be fired before currency gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.delete.after|This event will be fired after currency gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.delete.before|This event will be fired before currency gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |core.currency.delete.after|This event will be fired after currency gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.create.before|This event will be fired before exchange rate gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.create.after|This event will be fired after exchange rate gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.update.before |This event will be fired before exchange rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.update.after|This event will be fired after exchange rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.delete.before|This event will be fired before exchange rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.exchange_rate.delete.after|This event will be fired after exchange rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.create.before|This event will be fired before locale gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.create.after|This event will be fired after locale gets created and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.update.before|This event will be fired before locale gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.update.after|This event will be fired after locale gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.delete.before|This event will be fired before locale gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |core.locale.delete.after|This event will be fired after locale gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |customer.registration.before|This event will be fired before customer gets registered and you may create a listener file and perform the respective operation when that event fires|
+ |customer.registration.after|This event will be fired after customer gets registered and you may create a listener file and perform the respective operation when that event fires|
+ |customer.after.login|This event will be fired after customer successfully logins in store and you may create a listener file and perform the respective operation when that event fires|
+ |customer.after.logout|This event will be fired after customer successfully logouts from store and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.create.before|This event will be fired before inventory source gets created and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.create.after|This event will be fired after inventory source gets created and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.update.before|This event will be fired before inventory source gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.update.after|This event will be fired after inventory source gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.delete.before|This event will be fired before inventory source gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |inventory.inventory_source.delete.after|This event will be fired after inventory source gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.update.before|This event will be fired before customer review gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.update.after|This event will be fired after customer review gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.delete.before|This event will be fired before customer review gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.delete.after|This event will be fired after customer review gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.delete.before|This event will be fired before customer review gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.delete.after|This event will be fired after customer review gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.update.before|This event will be fired before customer review gets updated with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |customer.review.update.after|This event will be fired after customer review gets updated with mass selection and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.create.before|This event will be fired before product gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.create.after|This event will be fired after product gets created and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.update.before|This event will be fired before product gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.update.after|This event will be fired after product gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.delete.before|This event will be fired before product gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.delete.after|This event will be fired after product gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |sales.invoice.save.before|This event will be fired before invoice gets created and you may create a listener file and perform the respective operation when that event fires|
+ |sales.invoice.save.after|This event will be fired after invoice gets created and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.order.save.before|This event will be fired before order gets created and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.order.save.after|This event will be fired after order gets created and you may create a listener file and perform the respective operation when that event fires|
+ |sales.order.cancel.before|This event will be fired before order gets cancelled and you may create a listener file and perform the respective operation when that event fires|
+ |sales.order.cancel.after|This event will be fired after order gets cancelled and you may create a listener file and perform the respective operation when that event fires|
+ |catalog.product.update.after|This event will be fired after product gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |sales.shipment.save.before|This event will be fired before shipment for product gets created and you may create a listener file and perform the respective operation when that event fires|
+ |sales.shipment.save.after|This event will be fired after shipment for product gets created and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.add.before|This event will be fired before product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.add.after|This event will be fired after product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.delete.before|This event will be fired before product get deleted from cart and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.delete.after|This event will be fired after product get deleted from cart and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.update.before|This event will be fired before cart item get updated and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.update.after|This event will be fired after cart item get updated and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.add.before|This event will be fired before configurable product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+ |checkout.cart.add.after|This event will be fired after configurable product get added in cart and proceeded to but the product and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.create.before|This event will be fired before tax category gets created and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.create.after|This event will be fired after tax category gets created and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.update.before|This event will be fired before tax category gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.update.after|This event will be fired after tax category gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.delete.before|This event will be fired before tax category gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_category.delete.after|This event will be fired after tax category gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.create.before|This event will be fired before tax rate gets created and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.create.after|This event will be fired after tax rate gets created and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.update.before|This event will be fired before tax rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.update.after|This event will be fired after tax rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.delete.before|This event will be fired before tax rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |tax.tax_rate.delete.after|This event will be fired after tax rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.create.before|This event will be fired before user role gets created. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.create.after|This event will be fired after user role gets created. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.update.before|This event will be fired before user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.update.after|This event will be fired after user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.delete.before|This event will be fired before user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.role.delete.after|This event will be fired after user role gets deleted. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.create.before|This event will be fired before user gets created. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.update.before|This event will be fired before user gets updated. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.update.after|This event will be fired after user gets updated. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.delete.before|This event will be fired before user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.delete.before|This event will be fired before user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+ |user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+
+## Events Listen in Bagisto
+
+- Event listen in bagisto is given below with their functionality.
+
+ | Events name | functionality |
+ | ------------------------------- | ------------- |
+ | checkout.order.save.after | This event will be fired after order creation and listen in **`ProductFlat`** listener file to send new order mail from **`sendNewOrderMail`** function |
+ | sales.invoice.save.after | This event will be fired after invoice details have been saved and listen in **`ProductFlat`** listener file to send new invoice mail from **`sendNewInvoiceMail`** function |
+ | sales.shipment.save.after | This event will be fired after shipment details have been saved and listen in **`ProductFlat`** listener file to send new shipment mail from **`sendNewShipmentMail`** function |
+ | checkout.order.save.after | This event will be fired after order has been created and will listen in **`ProductFlat`** listener file to update product inventory from **`updateProductInventory`** function |
+ | catalog.attribute.create.after | This event will be fired after attribute has been created and listen in **`ProductFlat`** listener file from **`afterAttributeCreatedUpdated`** function |
+ | catalog.attribute.update.after | This event will be fired after attribute has updated and listen in **`ProductFlat`** listener file from **`afterAttributeCreatedUpdated`** function |
+ | catalog.attribute.delete.before | This event will be fired before attribute has been delete and listen in **`ProductFlat`** listener file from **`afterAttributeDeleted`** function |
+ | catalog.product.create.after | This event will be fired after product has been creation and listen in **`ProductFlat`** listener file from **`afterProductCreatedUpdated`** function |
+ | catalog.product.update.after | This event will be fired after product has been updated and listen in **`ProductFlat`** listener file from **`afterProductCreatedUpdated`** function |
+
+## Listening to Existing Events
+
+To listen to an existing event in Bagisto, you can follow these steps:
+
+1. Open the **`EventServiceProvider.php`** file located in the **`Providers`** folder.
+
+2. Inside the **`boot`** method, you can register your listener by calling the **`Event::listen`** method and providing the event name and the listener function.
+
+ ```php
+ Event::listen('checkout.order.save.after', 'Webkul\Admin\Listeners\Order@sendNewOrderMail');
+ ```
+
+ In the example above, we are listening to the **`checkout.order.save.after`** event and specifying the **`sendNewOrderMail`** function from the **`Order`** listener class in the **`Webkul\Admin\Listeners`** namespace.
+
+By registering the listener, you have associated the **`sendNewOrderMail`** function with the **`checkout.order.save.after`** event. Whenever this event is triggered, the specified function will be executed.
+
+You can modify the listener function according to your requirements to perform the desired operation.
diff --git a/docs/1.5.x/advanced/helpers.md b/docs/1.5.x/advanced/helpers.md
new file mode 100644
index 00000000..e0e4058e
--- /dev/null
+++ b/docs/1.5.x/advanced/helpers.md
@@ -0,0 +1,187 @@
+# Helpers
+
+[[TOC]]
+
+## Introduction
+
+Bagisto provides several helper methods in its packages, which are designed to assist developers in building their projects more efficiently.
+
+## Core Helpers
+
+The core helper methods mentioned below are part of the `Core` class in the `Webkul\Core` namespace. Let's explore some common methods:
+
+- **Get all channels:**
+
+ ```php
+ core()->getAllChannels();
+ ```
+
+- **Get the current channel:**
+
+ ```php
+ core()->getCurrentChannel();
+ ```
+
+- **Set the current channel:** This method takes an instance of the `Webkul\Core\Models\Channel` class as an argument.
+
+ ```php
+ core()->setCurrentChannel($channel);
+ ```
+
+- **Get the current channel code:**
+
+ ```php
+ core()->getCurrentChannelCode();
+ ```
+
+- **Get the default channel:**
+
+ ```php
+ core()->getDefaultChannel();
+ ```
+
+- **Get the default channel code:**
+
+ ```php
+ core()->getDefaultChannelCode();
+ ```
+
+- **Get the requested channel code:** This method is useful when you need to retrieve the channel from the request, with an optional fallback parameter.
+
+ ```php
+ core()->getRequestedChannelCode($fallback = true);
+ ```
+
+- **Get the channel name:** This method retrieves the name of the channel. It handles fallback cases by checking the name in the property, app locale code, and the `app.fallback_locale` config key.
+
+ ```php
+ core()->getChannelName($channel);
+ ```
+
+- **Get all locales:**
+
+ ```php
+ core()->getAllLocales();
+ ```
+
+- **Get all locales by requested channel:** This method provides all the locales associated with the requested channel.
+
+ ```php
+ core()->getAllLocalesByRequestedChannel();
+ ```
+
+- **Get the current locale:**
+
+ ```php
+ core()->getCurrentLocale();
+ ```
+
+- **Get the requested locale code:** This method retrieves the locale code from the request, with optional parameters for specifying the locale key and fallback behavior.
+
+ ```php
+ core()->getRequestedLocaleCode($localeKey = null, $fallback = true);
+ ```
+
+- **Get all customer groups:**
+
+ ```php
+ core()->getAllCustomerGroups();
+ ```
+
+- **Get the requested customer group code:** This method fetches the customer group code from the request.
+
+ ```php
+ core()->getRequestedCustomerGroupCode();
+ ```
+
+- **Get all currencies:**
+
+ ```php
+ core()->getAllCurrencies();
+ ```
+
+- **Get the base currency:**
+
+ ```php
+ core()->getBaseCurrency();
+ ```
+
+- **Get the base currency code:**
+
+ ```php
+ core()->getBaseCurrencyCode();
+ ```
+
+- **Get the channel-based currency:**
+
+ ```php
+ core()->getChannelBaseCurrency();
+ ```
+
+- **Get the channel-based currency code:**
+
+ ```php
+ core()->getChannelBaseCurrencyCode();
+ ```
+
+- **Get the current currency:**
+
+ ```php
+ core()->getCurrentCurrency();
+ ```
+
+- **Get the current currency code:**
+
+ ```php
+ core()->getCurrentCurrencyCode();
+ ```
+
+- **Get the exchange rate based on the currency ID:**
+
+ ```php
+ core()->getExchangeRate($targetCurrencyId);
+ ```
+
+- **Get the formatted amount:**
+
+ ```php
+ core()->currency($amount = 0);
+ ```
+
+- **Get the configuration data based on the key, channel, and locale:**
+
+ ```php
+ core()->getConfigData($field, $channel = null, $locale = null);
+ ```
+
+- **Get all countries:**
+
+ ```php
+ core()->countries();
+ ```
+
+- **Get the country name by country code:**
+
+ ```php
+ core()->country_name($countryCode);
+ ```
+
+- **Get all states of a country:**
+
+ ```php
+ core()->states($countryCode);
+ ```
+
+- **Get sender email details:**
+
+ ```php
+ core()->getSenderEmailDetails();
+ ```
+
+- **Get admin email details:**
+
+ ```php
+ core()->getAdminEmailDetails();
+ ```
+
+These core helper methods provide various functionalities to simplify common tasks and streamline development in Bagisto.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/indexing-products-to-elasticsearch.md b/docs/1.5.x/advanced/indexing-products-to-elasticsearch.md
new file mode 100644
index 00000000..4ae0bbe5
--- /dev/null
+++ b/docs/1.5.x/advanced/indexing-products-to-elasticsearch.md
@@ -0,0 +1,100 @@
+# Elasticsearch Configuration
+
+[[TOC]]
+
+In this section, we will explain how to configure Elasticsearch for indexing products from the database.
+
+## Environment Setup
+
+Before we proceed, make sure you have [Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) installed on your system. By default, Elasticsearch uses port **`9200`**. We will be using the same port for our configuration.
+
+To verify if Elasticsearch is installed successfully on your system, open your browser and navigate to **`http://localhost:9200`**. If you see the following output, it means Elasticsearch is installed:
+
+```json
+{
+ "name" : "webkul-pc",
+ "cluster_name" : "elasticsearch",
+ "cluster_uuid" : "suPotT8zQjCOlq9dteWKyQ",
+ "version" : {
+ "number" : "8.6.2",
+ "build_flavor" : "default",
+ "build_type" : "deb",
+ "build_hash" : "2d58d0f136141f03239816a4e360a8d17b6d8f29",
+ "build_date" : "2023-02-13T09:35:20.314882762Z",
+ "build_snapshot" : false,
+ "lucene_version" : "9.4.2",
+ "minimum_wire_compatibility_version" : "7.17.0",
+ "minimum_index_compatibility_version" : "7.0.0"
+ },
+ "tagline" : "You Know, for Search"
+}
+```
+
+Alternatively, you can use the curl command:
+
+```sh
+curl -X GET 'http://localhost:9200'
+```
+
+## Configuration Setup
+
+To configure Elasticsearch, you can set the necessary key-value pairs in the **`.env`** file of your project.
+
+Open the **`.env`** file and add the following lines:
+
+```env
+ELASTICSEARCH_PORT=9200
+ELASTICSEARCH_HOST=localhost
+```
+
+Save the file and run the following command to cache the configuration:
+
+```sh
+php artisan config:cache
+```
+
+Now your environment is set up and ready to index products.
+
+If you encounter any issues, you can directly set the configuration in the **`config/elasticsearch.php`** file:
+
+```php
+'hosts' => [
+ [
+ 'host' => env('ELASTICSEARCH_HOST', 'localhost'),
+ 'port' => env('ELASTICSEARCH_PORT', 9200),
+ // Additional configuration options can be added here
+ ]
+]
+```
+
+## Indexing
+
+After setting up the environment and configuration, new products will be automatically indexed when created.
+
+To index existing products, run the following command:
+
+```sh
+php artisan indexer:index
+```
+
+This command will index all the data from the **`product_flat`** table to the Elasticsearch index.
+
+## Checking Indexes
+
+To check if your products have been indexed successfully, open your browser and navigate to **`http://localhost:9200/_cat/indices?v`**. You should see information about the imported index.
+
+Alternatively, you can use the curl command:
+
+```sh
+curl -X GET 'http://localhost:9200/_cat/indices?v'
+```
+
+The output will provide details about the product index:
+
+:::details Output
+
+![Product Index Information](../../assets/1.5.x/images/advanced-topics/product-index.png)
+
+:::
+
+By following these steps, you have successfully configured Elasticsearch and indexed your products.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/override-core-model.md b/docs/1.5.x/advanced/override-core-model.md
new file mode 100644
index 00000000..fd08acdf
--- /dev/null
+++ b/docs/1.5.x/advanced/override-core-model.md
@@ -0,0 +1,66 @@
+# Override Core Model
+
+[[TOC]]
+
+## Introduction
+
+Bagisto utilizes Concord, a Laravel extension, for building modules on top of Laravel's built-in service providers. Concord introduces the concept of model proxies, which allow you to override and extend core models in a modular way.
+
+Concord requires the existence of an interface, such as **Product**, which serves as a contract that can be bound to a concrete class using Concord's **registerModel()** method.
+
+By default, the **`Models\Product`** class is bound to the **`Contracts\Product`** interface within the module. If you want to extend or override this class, you can use Concord's **registerModel()** method.
+
+The **registerModel()** method handles the binding of the interface and implementation in Laravel's service container, enabling you to easily type-hint the interface for automatic injection.
+
+For more details, you can visit the [Concord GitHub repository](https://github.com/artkonekt/concord) or refer to the [Concord documentation](https://artkonekt.github.io/concord/#/).
+
+## Overriding a Model Class
+
+- In Concord modules, an interface is typically defined for each Eloquent model. If you wish to override a model, you can instruct Concord to use another class for that interface. Here's an example:
+
+ ```php
+ app->concord->registerModel(
+ \Webkul\Product\Contracts\Product::class, \App\Http\Product::class
+ );
+ }
+ }
+ ```
+
+- In the code above, the **registerModel()** method accepts two parameters:
+
+ - The first parameter specifies the path to the interface (contract) you want to override.
+ - The second parameter specifies the path to the model class that will override the default implementation.
+
+- The model class you're overriding must extend your specified model path, as shown in the example below:
+
+ ```php
+ field('home_page_content')
+ ->with(['sliderData' => $sliderData])->render() !!}
+
+ {!! view_render_event('bagisto.shop.home.content.after') !!}
+
+@endsection
+```
+
+In the example above, we use **`view_render_event()`** to inject content before and after the main content of the **`home_page_content`** template.
+
+## Render View
+
+To render content before or after a specific section of a template, follow these steps:
+
+1. Add the event in the blade file where you want to inject the content. For example:
+
+ ```php
+ {!! view_render_event('bagisto.shop.test.before') !!}
+ ```
+
+ In this example, **`bagisto.shop.test`** is the event name defined in a random blade file of your project.
+
+2. Next, you need to listen to the event in the **`EventServiceProvider.php`** file. Add the following code in the **`boot()`** method:
+
+ ```php
+ addTemplate('template file path to be injected');
+ });
+ }
+ }
+ ```
+
+ In the code above, replace **`'template file path to be injected'`** with the actual path to the template file that you want to render.
+
+:::warning
+ Make sure that you have registered the **`EventServiceProvider`** in your own service provider.
+:::
+
+By following these steps, you can use the **`view_render_event()`** function to dynamically inject content before or after the main content of a template in Bagisto.
\ No newline at end of file
diff --git a/docs/1.5.x/advanced/security-practice.md b/docs/1.5.x/advanced/security-practice.md
new file mode 100644
index 00000000..a3ce5d39
--- /dev/null
+++ b/docs/1.5.x/advanced/security-practice.md
@@ -0,0 +1,135 @@
+# Best Security Practices
+
+[[TOC]]
+
+## Software Updates
+
+To ensure the security of your system, follow these best practices:
+
+- Use HTTPS to encrypt communication. Google now considers HTTPS as a ranking factor.
+- Keep all software on the server up-to-date, including Bagisto, the database, Adminer/phpMyAdmin, Apache, Redis, etc.
+- Regularly update the server operating system to apply available security patches.
+- Manage files only through secure communication protocols like SSH, SFTP, or HTTPS. Disable FTP.
+- Use the **`.htaccess`** file to protect system files when using the Apache web server.
+- Disable unused ports and stop unnecessary services running on the server.
+- Restrict access to the admin panel by allowing only specific IP addresses and enforcing two-factor authorization for admin logins.
+- Ensure the use of strong and unique passwords.
+- Configure and update the firewall properly to secure the connection between payment card data and the public network.
+
+## Limiting Error Messages
+
+To limit the exposure of sensitive information in error messages, follow these steps:
+
+- Edit your Apache configuration file to avoid displaying server and operating system details.
+- Set **`ServerSignature`** to **`Off`** (by default, it is **`On`**).
+- Add **`ServerTokens Prod`** to display Apache only as the product.
+
+:::details Screenshot
+
+![limiting-error-messages](../../assets/1.5.x/images/advanced-topics/limiting-error-messages.png)
+
+:::
+
+## Limiting Admin Access
+
+To restrict access to the admin area, modify the **`.htaccess`** file with the following code:
+
+```apacheconf
+RewriteEngine On
+RewriteCond %{REQUEST_URI} .*/admin
+RewriteCond %{REMOTE_ADDR} !=
+RewriteCond %{REMOTE_ADDR} !=
+RewriteRule ^(.*)$ - [R=403,L]
+```
+
+Ensure that there are no accessible development leftovers on the server, such as "log files," ".git directories," "database dumps," or "zip files."
+
+## Restricting Unnecessary Files
+
+To restrict access to unnecessary files, add the following code to your **`.htaccess`** file:
+
+```apacheconf
+
+ Require all denied
+
+```
+
+Consider using a Web Application Firewall (WAF) to analyze traffic and detect suspicious patterns, such as credit card information being sent to attackers. Additionally, restrict public access to only ports 80 (HTTP) and 443 (HTTPS), while blocking other ports.
+
+## Restricting PHP Execution Inside Storage
+
+To restrict PHP execution inside the storage directory, modify your Apache configuration file:
+
+```apacheconf
+
+
+ Require all denied
+
+ php_flag engine off
+
+```
+
+Don't forget to restart Apache after making these changes.
+
+## Server Hardening
+
+Take the following measures to harden your server:
+
+- Use the **`mod_security`** module to detect and prevent intrusions.
+- Implement the **`mod_passive`** module to prevent brute force attacks.
+- Allow only specific users to log in.
+- Disable login for users with empty passwords.
+- Review and configure iptable rules to prevent unauthorized access and activity.
+- Regularly back up important files and store them remotely in a secure environment.
+
+## Strong Passwords
+
+Ensure the use of strong and unique passwords and encourage periodic password changes. You can use a password generator tool ([Password Generator](https://passwords-generator.org/)) to create strong passwords. Limit access to the Bagisto admin
+
+ panel by updating the whitelist with authorized IP addresses.
+
+## Implementation of HTTP Security Headers
+
+Implementing the following HTTP security headers enhances web security:
+
+### HTTP Strict Transport Security (HSTS)
+
+Set the **`Strict-Transport-Security`** response header to instruct the browser to only access the application using HTTPS:
+
+```
+Strict-Transport-Security: max-age=
+```
+
+### Cross-Site Scripting Protection (X-XSS Protection)
+
+Set the **`X-XSS-Protection`** response header to enable browsers to detect and prevent cross-site scripting (XSS) attacks:
+
+```
+X-XSS-Protection: 1; mode=block
+```
+
+### X-Frame-Options
+
+The **`X-Frame-Options`** response header protects applications against clickjacking. It specifies whether the content can be displayed within frames:
+
+```
+X-Frame-Options: deny
+```
+
+### X-Content-Type-Options
+
+The **`X-Content-Type-Options`** response header forces the browser to disable MIME sniffing, preventing MIME sniffing vulnerabilities:
+
+```
+X-Content-Type-Options: nosniff
+```
+
+### Content Security Policy (CSP)
+
+Implement a Content Security Policy (CSP) response header to control resources that can be loaded in users' browsers. CSP helps detect and mitigate attacks such as XSS and clickjacking.
+
+### Continuous Logging And Monitoring
+
+Maintain continuous logging and monitoring of all network access and cardholder data activities. Keep an eye out for large volume orders of a single item from new customers, a series of orders shipped to the same address but using different payment methods.
+
+By implementing these best security practices, you can enhance the security of your system and protect it from potential threats.
\ No newline at end of file
diff --git a/docs/1.5.x/architecture/README.md b/docs/1.5.x/architecture/README.md
new file mode 100644
index 00000000..ac1ebe2b
--- /dev/null
+++ b/docs/1.5.x/architecture/README.md
@@ -0,0 +1,12 @@
+# Architecture concepts
+**Bagisto** is very easy framework to understand. The goal of this document to give you overview of how bagisto works.
+
+We love to work with hot [Opensource](https://en.wikipedia.org/wiki/Open_source) softwares so Bagisto is built on technologies such as [PHP](https://php.net), [Laravel](https://laravel.com) and [Vue.js](https://vuejs.org/)
+
+As **Bagisto** targets e-commerce businesses so it provides front and back end features to enable customer account and administrative control simultaneously.
+
+Laravel packages are being used to separate each functionality such as Category, Product, Cart, Checkout, etc.
+
+We developed and used built-in components of Vue.js
+
+**Bagisto** registers useful events that are triggered on most of the pages which could enable to perform some custom operations in the application.
diff --git a/docs/1.5.x/architecture/frontend.md b/docs/1.5.x/architecture/frontend.md
new file mode 100644
index 00000000..f0eaf168
--- /dev/null
+++ b/docs/1.5.x/architecture/frontend.md
@@ -0,0 +1,13 @@
+# Vue and Sass
+
+[Vue.js](https://vuejs.org/) handles the complete UI of **Bagisto**
+
+[Laravel Mix](https://laravel.com/docs/10.x/mix) is a package that provides a fluent API for defining [webpack](https://webpack.js.org/) and it build steps for your [Laravel](https://laravel.com) application using several common CSS and JavaScript [pre-processors](https://en.wikipedia.org/wiki/Preprocessor).
+
+**Bagisto** is using [Vue.js](https://vuejs.org/) and [Sass](https://sass-lang.com/), webpack compiles all of CSS and JavaScript assets that are placed into public directory.
+
+In **webpack.mix.js** file, just define your [Vue.js](https://vuejs.org/) and [Sass](https://sass-lang.com/) assets, [webpack](https://webpack.js.org/) will be responsible to compile all the assets on defined location.
+
+# Blade
+
+**Bagisto** uses blade template engine that is included with **Laravel**. It does not restrict you from using plain PHP code in your templates. [This documentation](http://localhost:8080/1.5.x/packages/views.html#directory-structure) provides an explanation of directory structure and package configuration for implementations.
\ No newline at end of file
diff --git a/docs/1.5.x/architecture/modular-design.md b/docs/1.5.x/architecture/modular-design.md
new file mode 100644
index 00000000..34b05255
--- /dev/null
+++ b/docs/1.5.x/architecture/modular-design.md
@@ -0,0 +1,13 @@
+# Modular Design
+
+**Modular design** is the preferred approach for e-commerce software, as it enables the separation of each package and empowers users to work with self-contained modules.
+
+This architectural style effectively manages the complexity of the system by breaking down problems into smaller, more manageable modules.
+
+To implement this modular approach, Bagisto utilizes the [Concord package](https://github.com/artkonekt/concord).
+
+Concord plays a pivotal role in enabling the modular architecture within **Bagisto**, providing the necessary tools and features.
+
+By leveraging **Concord**, **Bagisto** is able to follow a modular architecture that enhances **flexibility** and **scalability**.
+
+Through Concord, Bagisto users can take advantage of the benefits offered by a modular architecture, enabling them to easily customize and extend the software according to their specific requirements.
\ No newline at end of file
diff --git a/docs/1.5.x/architecture/packages.md b/docs/1.5.x/architecture/packages.md
new file mode 100644
index 00000000..150bb4cb
--- /dev/null
+++ b/docs/1.5.x/architecture/packages.md
@@ -0,0 +1,11 @@
+# Packages
+[Laravel](https://laravel.com) packages are the primary way of adding functionality so the following features are distributed into packages to enhance the application and allow developers to follow the standard way of developing custom functionality.
+
+- Theme
+- Category
+- Product
+- Cart
+- Checkout
+- Payment
+
+Service provider enables features such as loading [routes](/1.5.x/packages/routes.html), [migrations](/1.5.x/packages/create-migrations.html), [languages](/1.5.x/packages/localization.html) or publishing [views](/1.5.x/packages/views.html), etc so **Bagisto** is developed considering these aspects.
diff --git a/docs/1.5.x/architecture/performance.md b/docs/1.5.x/architecture/performance.md
new file mode 100644
index 00000000..21457486
--- /dev/null
+++ b/docs/1.5.x/architecture/performance.md
@@ -0,0 +1,29 @@
+# Performance
+
+[[TOC]]
+
+In the realm of online stores, [web vitals](https://web.dev/vitals/) have become increasingly crucial. **Bagisto** prioritizes good [LCP](https://web.dev/lcp/) and [CLS](https://web.dev/cls/) to ensure optimal user experience.
+
+Additionally, **Bagisto** has seamlessly integrated [ElasticSearch](https://bagisto.com/en/elasticsearch-for-bagisto/) to further enhance user experience.
+
+## Indexing
+
+When dealing with large volumes of data and retrieving complex information like variants and prices, optimizing queries becomes a challenge.
+
+To enhance **Bagisto's** performance, the following indexers play a crucial role:
+
+- Inventory
+- Price
+- ElasticSearch
+
+### Inventory
+
+This indexer focuses on indexing the inventory of the website for various product types such as configurable, grouped, and bundled products.
+
+### Price
+
+The price indexer manages the prices of the aforementioned product types.
+
+### ElasticSearch
+
+As Elastic is designed to handle large amounts of data and provide fast and scalable search capabilities, **Bagisto** leverages its capabilities to index all products, thereby significantly enhancing the search functionality.
\ No newline at end of file
diff --git a/docs/1.5.x/architecture/repository-pattern.md b/docs/1.5.x/architecture/repository-pattern.md
new file mode 100644
index 00000000..3d6f0ad7
--- /dev/null
+++ b/docs/1.5.x/architecture/repository-pattern.md
@@ -0,0 +1,9 @@
+# Repository Pattern
+
+[Eloquent](https://laravel.com/docs/10.x/eloquent), the [ORM](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) in **Laravel**, provide a higher level of abstraction and make working with databases more convenient, as you can focus on manipulating objects rather than dealing with raw SQL queries.
+
+To further enhance flexibility and maintainability, Bagisto incorporates the **Repository pattern** as an additional layer on top of the **ORM**.
+
+By implementing the **Repository pattern**, **Bagisto** restricts the use of raw queries throughout the application. This ensures consistency and promotes better code organization.
+
+Bagisto utilizes the [Prettus Repository](https://github.com/prettus/l5-repository) package to facilitate the implementation of the **Repository pattern**. This choice enhances the flexibility of the application, making it easier to maintain and extend.
\ No newline at end of file
diff --git a/docs/1.5.x/architecture/theme.md b/docs/1.5.x/architecture/theme.md
new file mode 100644
index 00000000..7b5750e5
--- /dev/null
+++ b/docs/1.5.x/architecture/theme.md
@@ -0,0 +1,3 @@
+# Theme
+
+In e-commerce businesses, themes provides an elegant way to attract users. **Bagisto** provides front-end theme i.e. **Velocity** and allow developers to create new theme as per their convenience.
\ No newline at end of file
diff --git a/docs/1.5.x/deploy/README.md b/docs/1.5.x/deploy/README.md
new file mode 100644
index 00000000..6ca0fb29
--- /dev/null
+++ b/docs/1.5.x/deploy/README.md
@@ -0,0 +1,9 @@
+# Deploy
+
+this article will explain how you can deploy your Bagisto store to your production server when you have been developing your Bagisto store on your local system.
+
+## Deploy Bagisto with (S)FTP
+
+## Deploy on Cpanel
+
+## Deploy on Plesk
diff --git a/docs/1.5.x/introduction/README.md b/docs/1.5.x/introduction/README.md
new file mode 100644
index 00000000..c4bdee56
--- /dev/null
+++ b/docs/1.5.x/introduction/README.md
@@ -0,0 +1,45 @@
+# Introduction
+
+## Bagisto: A Powerful Open-Source E-Commerce Platform
+
+Bagisto is a popular open-source e-commerce platform built on the combination of Laravel PHP framework and Vue.js. It provides a comprehensive set of tools and features to help developers and businesses create and manage their online stores effectively. With its flexible and adaptable nature, Bagisto has gained recognition and support from a growing community of users, as evidenced by its impressive 6K+ stars on [GitHub](https://github.com/bagisto/bagisto).
+
+## Key Features of Bagisto
+
+Bagisto comes with a rich set of features that empower developers and businesses to create and manage their online stores effectively:
+
+### Modular Design
+
+Bagisto adopts a modular design approach, providing developers with the flexibility to customize and extend the platform's functionalities to meet specific business requirements. It allows you to tailor your e-commerce store precisely to your needs.
+
+### Multi-Channel and Multi-Vendor Support
+
+With Bagisto, you can easily create and manage multiple sales channels, enabling you to expand your reach and cater to different customer segments. It also supports multi-vendor functionality, allowing various vendors to sell their products on your platform.
+
+### Responsive and Mobile-Friendly
+
+Bagisto ensures that your online store looks great and performs flawlessly across different devices, including mobile phones and tablets. With a responsive design, you can provide a seamless shopping experience to your customers, no matter the device they use.
+
+### Efficient Inventory Management
+
+Bagisto simplifies inventory management by providing tools to effectively track stock levels, set low inventory alerts, and streamline order fulfillment processes. You can efficiently manage your product inventory and ensure a smooth flow of operations.
+
+### Secure Payment Gateways and Shipping Methods
+
+Integrating popular payment gateways and shipping methods is effortless with Bagisto. It offers seamless integration options to ensure secure and convenient transactions for your customers, making the checkout process a breeze.
+
+### Search Engine Optimization (SEO) Capabilities
+
+Bagisto equips you with built-in features to optimize your online store for search engines. You can customize meta tags, URLs, and keywords to improve your store's visibility and attract more organic traffic.
+
+## Community and Support
+
+Bagisto has a vibrant and supportive community of developers and users who actively contribute to its growth and improvement.
+
+- **Explore Bagisto**: Visit our website at [https://bagisto.com](https://bagisto.com) to discover more about Bagisto's features and experience a demo.
+
+- **Stay Updated**: Refer to the [Bagisto roadmap](https://bagisto.com/roadmap) for the latest version and recently added features.
+
+- **GitHub Repository**: Access the Bagisto repository on [GitHub](https://github.com/bagisto/bagisto) with over 6K+ stars, reflecting its popularity and community support.
+
+Join the Bagisto community today and build and manage your online store with ease.
\ No newline at end of file
diff --git a/docs/1.5.x/introduction/docker.md b/docs/1.5.x/introduction/docker.md
new file mode 100644
index 00000000..986e2333
--- /dev/null
+++ b/docs/1.5.x/introduction/docker.md
@@ -0,0 +1,225 @@
+# Docker
+
+[[toc]]
+
+## Introduction
+
+[Docker](https://www.docker.com/) is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. Docker can also be used for defining and running multi-container Docker applications using the Docker Compose tool.
+
+With the help of Docker Compose, you can define containers to be built, their configuration, links, volumes, ports, etc., in a single file, and it gets launched by a single command. You can also add multiple servers and services just by adding them to the Docker Compose configuration file. This configuration file is in [YAML](https://en.wikipedia.org/wiki/YAML) format.
+
+#### Application Data and Database Volume Persistence
+
+It is recommended to keep your application files and database data volume on the Docker host and mount them on the running container. This ensures that the application and database data persistence even in the case of containers' failure or termination. In this way, even if you destroy containers, your data won't get lost unless you remove them forcefully.
+This compose configuration file mounts the application directory **`app`** and database volume **`dbvolume`** from the host to running Docker containers at the time of containers' launch.
+
+## Installation & Setup
+
+### First steps
+
+Before you can launch Bagisto in a Docker environment, you need to install the latest versions of Docker and Docker Compose.
+
+- [Docker](https://docs.docker.com/install/)
+- [Docker Compose](https://docs.docker.com/compose/install/)
+- [Composer](https://getcomposer.org) (optional)
+
+### Configure the Docker container
+
+Once Docker and Docker Compose are installed, you need to create a **`docker-compose.yml`** file. The **`docker-compose.yml`** configuration file requires the following inputs from the user:
+
+#### Webserver configuration
+
+In the **`web_server`** service block, assign your system's working user UID to the **`USER_UID`** environment variable. To find your user ID, run the following command on Linux or macOS:
+```shell
+id -u
+```
+
+#### Database configuration
+
+In the **`database_server`** service block, assign the MySQL database name, MySQL database user name, MySQL database user password, and MySQL root password to the **`MYSQL_DATABASE`**, **`MYSQL_USER`**, **`MYSQL_PASSWORD`**, and **`MYSQL_ROOT_PASSWORD`** environment variables, respectively.
+
+#### Clone configuration from GitHub
+
+You can make use of our repository from GitHub by cloning it into your new directory:
+```shell
+git clone https://github.com/bagisto/bagisto-docker.git .
+```
+
+#### Manual configuration
+
+Alternatively, you can create a new folder, for example, **`bagisto-docker`**, and manually create the **`docker-compose.yml`** file inside it. Add the following content to **`docker-compose.yml`**:
+
+```yml
+version: '3'
+
+services:
+
+ web_server:
+ image: webkul/apache-php:latest
+ container_name: apache2
+ restart: always
+ volumes:
+ - ./app:/var/www/html
+ working_dir: /var/www/html/
+ environment:
+ USER_UID: 'mention your system user ID here. ex: 1001, 1000, 33, etc'
+ networks:
+ - bagisto-network
+ ports:
+ - '80:80'
+ expose:
+ - '80'
+ depends_on:
+ - database_server
+ links:
+ - database_server
+
+ database_server:
+ image: mysql:5.7
+ container_name: mysql
+ restart: always
+ environment:
+ MYSQL_DATABASE: 'mention the name of the database to be created here. eg: mydatabase'
+ MYSQL_USER: 'mention database user here. eg: mydatabase_user'
+ MYSQL_PASSWORD: 'mention database user password here. ex: mystrongPassword'
+ MYSQL_ROOT_PASSWORD: 'mention mysql root password here. ex: mysqlstrongpass'
+ MYSQL_ROOT_HOST: '%'
+ networks:
+ - bagisto-network
+ ports:
+ - '3306:3306'
+ expose:
+ - '3306'
+ volumes:
+ - ./dbvolume:/var/lib/mysql
+
+volumes:
+ dbvolume:
+ app:
+
+networks:
+ bagisto-network:
+ **
+```
+
+#### Downloading the Docker Image
+
+To download the Docker images for Apache-PHP version 7.3 and MySQL version 5.7, execute the following command:
+
+```shell
+docker-compose pull
+```
+
+### Launching the Docker Container
+
+Execute the following command to create a network and launch web server and database containers with the names **`apache2`** and **`mysql`** respectively. It will also create new directories **`app`** and **`dbvolume`** within your current directory and mount them to the respective Docker containers as specified in the **`docker-compose.yml`** file. Additionally, it binds your **`host port 80`** to the Apache2 container's port 80, and your **`host port 3306`** to the MySQL container's port 3306. If you wish to use different ports for the containers, modify their values in the **`docker-compose.yml`** file.
+
+```
+docker-compose up -d
+```
+
+### Monitoring Your Container(s)
+
+To check the running Docker containers, use the following commands:
+
+**`docker ps`** OR **`docker-compose ps`**
+```shell
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+62a10346b84a webkul/apache-php:latest "/usr/bin/supervisord" About an hour ago Up About an hour 0.0.0.0:80->80/tcp apache2
+90a0a2e0e46b mysql:5.7 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
+```
+
+## Configuring Bagisto
+
+After setting up your environment, you can proceed with the installation of Bagisto. There are two ways to install Bagisto: either from [Github](#install-without-composer) or using [composer](#install-with-composer).
+
+### Install without Composer
+
+To install Bagisto without using composer, follow these steps:
+1. Download the [latest release](https://bagisto.com/en/download) and save it in the **`app/bagisto`** directory.
+2. Open the **`.env`** file located inside the **app/bagisto** directory.
+3. Set the following environment variables as shown below:
+
+```editorconfig
+APP_URL=https://127.0.0.1
+DB_CONNECTION=mysql
+DB_HOST=mysql
+DB_PORT=3306
+DB_DATABASE=
+DB_USERNAME=
+DB_PASSWORD=
+```
+
+Run the following commands to install Bagisto.
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan migrate'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan db:seed'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan vendor:publish'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan storage:link'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer dump-autoload -d bagisto'"
+```
+
+Mention the database details same as docker-compose.yml and admin details.
+
+
+### Install with composer
+
+The following commands will be exexcuted within the docker container
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer create-project bagisto/bagisto'"
+```
+
+Open the .env file inside **`app/bagisto`** directory and set the following environment variables listed below:
+
+```editorconfig
+APP_URL=https://127.0.0.1
+DB_CONNECTION=mysql
+DB_HOST=mysql
+DB_PORT=3306
+DB_DATABASE=
+DB_USERNAME=
+DB_PASSWORD=
+```
+
+To install Bagisto, execute the following commands:
+
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan migrate'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan db:seed'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan vendor:publish'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan storage:link'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer dump-autoload -d bagisto'"
+```
+
+Bagisto has been successfully installed and is now ready to use. To access it, open your web browser and enter your server's IP address or domain name.
+
+### Configuring Apache
+
+By default, the Apache document root is set to **/var/www/html/public_html**. Additionally, the **app** directory on your host machine is mapped to the **html** directory inside the container. To ensure proper configuration, we need to create a symlink of **`bagisto/public`** in the **`app`** directory that points to **`/var/www/html/public_html`**.
+
+To create the symlink, follow the steps below:
+
+On Linux or macOS, run the following command:
+```bash
+cd app; ln -snf bagisto/public public_html
+```
+
+On Windows, run the following command:
+```command-line
+cd app
+mklink bagisto/public public_html
+```
+
+### Ready to Use
+
+#### Admin Login:
+
+You can access the admin interface by visiting [http://your_server_endpoint/admin](http://your_server_endpoint/admin/) and logging in with the following credentials:
+
+| Email | Password |
+|----------------------|----------|
+| admin@example.com | admin123 |
+
+#### Customer Login:
+
+To access your store, visit [http://your_server_endpoint/](http://your_server_endpoint/).
\ No newline at end of file
diff --git a/docs/1.5.x/introduction/installation.md b/docs/1.5.x/introduction/installation.md
new file mode 100644
index 00000000..bd08110b
--- /dev/null
+++ b/docs/1.5.x/introduction/installation.md
@@ -0,0 +1,103 @@
+# Installation
+
+[[TOC]]
+
+## Install Using GUI Installer
+
+To install Bagisto using our GUI installer, follow these steps:
+
+1. [Download Bagisto](https://bagisto.com/en/download/) from our website.
+2. Extract the contents of the downloaded zip file.
+3. Navigate to the project root directory.
+4. Run the following command:
+
+ ```sh
+ composer install
+ ```
+
+5. Configure your HTTP server to point to the **`public/`** directory of the project.
+6. Open your browser and access the following URL:
+
+ ```
+ http://localhost/bagisto/public/
+ ```
+
+ This will launch the Bagisto installer.
+
+## Install Using Composer
+
+To install Bagisto using Composer, use the following steps:
+
+1. Run the following command:
+
+ ```sh
+ composer create-project bagisto/bagisto
+ ```
+
+2. Navigate to the project root directory.
+3. Open the **`.env`** file and add your database credentials:
+
+ ```editorconfig
+ DB_DATABASE=
+ DB_USERNAME=
+ DB_PASSWORD=
+ ```
+
+4. Run the following command:
+
+ ```sh
+ php artisan bagisto:install
+ ```
+
+ ::: warning
+ During the installation process, if the **`.env`** file doesn't exist, the installer will prompt you to provide the necessary information.
+ :::
+
+ - Follow the prompts during the installation process to provide the following details:
+
+ ```
+ - Please Enter the APP URL :
+ - Please Enter the Admin URL :
+ - Please select the default locale or press enter to continue [en]:
+ - Please enter the default timezone [Asia/Kolkata]:
+ - Please enter the default currency [USD]:
+ - What is the database name to be used by Bagisto?:
+ - What is your database username?:
+ - What is your database password?:
+ ```
+
+## Start Using Bagisto
+
+### On a Production Server
+
+To access Bagisto on a production server, open your domain in a web browser. For example:
+
+```
+https://example.com/
+```
+
+### On Your Local Server
+
+To access Bagisto on your local server, follow these steps:
+
+1. Configure your HTTP server to point to the **`public/`** directory of the project.
+2. Run the following command:
+
+ ```sh
+ php artisan serve
+ ```
+
+3. Open your browser and access the provided local server URL.
+
+### Login as an Admin
+
+To log in as an admin, visit **`https://example.com/admin/`**. If you used the **`php artisan bagisto:install`** command, use the following credentials:
+
+```
+Email: admin@example.com
+Password: admin123
+```
+
+### Login as a Customer
+
+To log in as a customer, you can directly register on **`https://example.com/customer/register`**. After registration, you can log in using your credentials on the domain.
\ No newline at end of file
diff --git a/docs/1.5.x/introduction/requirements.md b/docs/1.5.x/introduction/requirements.md
new file mode 100644
index 00000000..321128c9
--- /dev/null
+++ b/docs/1.5.x/introduction/requirements.md
@@ -0,0 +1,53 @@
+# Requirements
+
+[[TOC]]
+
+## Server Configuration
+
+- **Server**: Apache 2 or NGINX
+- **RAM**: 4GB or higher
+- **Node**: 18.12.0 LTS or higher
+- **PHP**: 8.1 or higher
+- **Composer**: 2.5 or higher
+
+## PHP Extensions
+
+Ensure the following extensions are installed and enabled. You can check using the **`phpinfo()`** page or the **`php -m`** command.
+
+- **php-intl extension**: This extension is required for internationalization support in Bagisto.
+
+- **php-gd extension**: The **`php-gd`** extension must be properly installed to ensure correct image functionality in the project. If not installed correctly, image-related features may not work as expected.
+
+ ::: tip Note
+ It is important to ensure proper installation of the **`php-gd`** extension to avoid any issues with image manipulation in Bagisto.
+ :::
+
+## PHP Configuration
+
+Open your **`php.ini`** file and modify the following settings.
+
+- **memory_limit**: Set the **`memory_limit`** directive to **`4G`** or higher to ensure sufficient memory allocation for the application.
+
+- **max_execution_time**: Adjust the **`max_execution_time`** directive to **`360`** or higher. This value determines the maximum time (in seconds) a script is allowed to run. Increasing this value ensures that longer operations, such as import/export processes, can be completed successfully.
+
+- **date.timezone**: Set the **`date.timezone`** directive to your specific timezone. For example, **`Asia/Kolkata`**. This ensures that date and time-related functions work accurately based on the specified timezone.
+
+```ini
+memory_limit = 4G
+max_execution_time = 360
+date.timezone = Asia/Kolkata <- Change this to your own timezone.
+```
+
+::: tip Remember to restart your web server
+Whenever you make changes to the PHP configuration file, be sure to restart Apache or NGINX to apply the modifications.
+:::
+
+## Supported Database Servers
+
+Bagisto supports the following database servers:
+
+- **MySQL**: Version 8.0.32 or higher is recommended for optimal performance and compatibility.
+
+- **MariaDB**: Version 10.3 or higher is recommended for optimal performance and compatibility.
+
+- **Database Collation**: The recommended collation for the database is **`utf8mb4_unicode_ci`**, which ensures proper handling of Unicode characters and multilingual support.
\ No newline at end of file
diff --git a/docs/1.5.x/packages/README.md b/docs/1.5.x/packages/README.md
new file mode 100644
index 00000000..104b96d5
--- /dev/null
+++ b/docs/1.5.x/packages/README.md
@@ -0,0 +1,88 @@
+## Package Development
+
+If you are looking to extend the functionalities of Bagisto eCommerce platform, creating a package is the way to go. A package is a self-contained module that adds specific features to the platform. It allows developers to add custom functionality to the platform without modifying the core codebase.
+
+This guide will walk you through the process of developing a package for Bagisto.
+
+In Bagisto, we have created numerous packages located at **`packages/Webkul/`**. Below is a basic tree structure of a package:
+
+~~~directory-structure
+└── Webkul
+ └── Blog
+ ├── publishable
+ │ └── assets
+ │ ├── css
+ │ │ ├── admin.css
+ │ │ ├── default.css
+ │ │ └── velocity.css
+ │ ├── images
+ │ │ └── blog-icon.png
+ │ └── js
+ │ └── app.js
+ └── src
+ ├── Config
+ │ ├── acl.php
+ │ ├── admin-menu.php
+ │ └── system.php
+ ├── Console
+ │ └── Commands
+ ├── Contracts
+ │ └── Post.php
+ ├── Database
+ │ ├── Migrations
+ │ │ └── 2023_04_21_173057_create_posts_table
+ │ └── Seeders
+ ├── Events
+ ├── Http
+ │ ├── Controllers
+ │ │ ├── Admin
+ │ │ │ └── PostController.php
+ │ │ └── Shop
+ │ │ └── PostController.php
+ │ ├── Middleware
+ │ └── Requests
+ ├── Listeners
+ ├── Mail
+ ├── Models
+ │ ├── Post.php
+ │ └── PostProxy.php
+ ├── Providers
+ │ ├── BlogServiceProvider.php
+ │ └── ModuleServiceProvider.php
+ ├── Routes
+ │ ├── admin-routes.php
+ │ └── shop-routes.php
+ ├── Repositories
+ │ └── PostRepository.php
+ └── Resources
+ ├── assets
+ │ ├── images
+ │ │ └── blog-icon.png
+ │ ├── js
+ │ │ └── app.js
+ │ └── sass
+ │ ├── admin.scss
+ │ ├── default.scss
+ │ └── velocity.scss
+ ├── lang
+ │ └── app.php
+ └── views
+ ├── admin
+ │ └── layouts
+ │ └── style.blade.php
+ ├── index.blade.php
+ ├── create.blade.php
+ ├── edit.blade.php
+ ├── shop
+ │ └── default
+ │ └── layouts
+ │ └── style.blade.php
+ │ ├── index.blade.php
+ │ └── blog-details.blade.php
+ └── velocity
+ └── layouts
+ └── style.blade.php
+ ├── index.blade.php
+ └── blog-details.blade.php
+
+~~~
\ No newline at end of file
diff --git a/docs/1.5.x/packages/add-menu-in-admin.md b/docs/1.5.x/packages/add-menu-in-admin.md
new file mode 100644
index 00000000..6ed72274
--- /dev/null
+++ b/docs/1.5.x/packages/add-menu-in-admin.md
@@ -0,0 +1,106 @@
+# Admin Menu
+
+[[TOC]]
+
+## Directory Structure
+
+To ensure that the admin menu includes the necessary configuration, follow these steps:
+
+1. In your package's source directory, which is typically located at **`packages/Webkul/Blog/src`**, create a new folder named **`Config`** if it doesn't already exist.
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Config
+ └── admin-menu.php
+ ```
+
+2. Inside the newly created **`Config`** folder, create a file named **`admin-menu.php`**.
+
+3. Copy and paste the following code into the **`admin-menu.php`** file:
+
+ ```php
+ 'blogs',
+ 'name' => 'Blogs',
+ 'route' => 'blog.admin.index',
+ 'sort' => 2,
+ 'icon-class' => 'blog-icon',
+ ],
+ ];
+ ```
+
+4. In your **`admin-routes.php`** file (located in the same package's source directory), add the named route **`blog.admin.index`** as follows:
+
+ ```php
+ Route::get('/blog', [PostController::class, 'index'])->name('blog.admin.index');
+ ```
+
+ In this step, we define the route that corresponds to the menu item added in the previous step.
+
+## Add Menu Icon
+
+5. To add the menu icon styling, open the **`assets/scss/admin.scss`** file within your package and add the following code:
+
+ ```css
+ .blog-icon {
+ background-image: url("../images/blog.png");
+ width: 45px;
+ height: 45px;
+ opacity: 0.6;
+ margin-left: 4px !important;
+ }
+
+ .active {
+ .blog-icon {
+ opacity: 1;
+ background-image: url("../images/blog-active.png");
+ }
+ }
+ ```
+
+ Ensure that you have the necessary **`.png`** image files (**`blog.png`** and **`blog-active.png`**) and manually place them inside the **`assets/images`** folder of your package.
+
+6. To merge the **`admin-menu.php`** configuration with the core menu file, use the **`mergeConfigFrom()`** method in the **`register()`** method of your package's service provider. Here's an example:
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
+ );
+ }
+ }
+ ```
+
+7. Finally, run the following command to optimize your application:
+
+ ```
+ php artisan optimize
+ ```
+
+ After completing these steps, the menu item should appear in the admin panel.
+
+ ::: details Admin Menu Output
+
+ ![Admin Menu Output](../../assets/1.5.x/images/package-development/admin-menu-output.png)
+
+ :::
\ No newline at end of file
diff --git a/docs/1.5.x/packages/assets.md b/docs/1.5.x/packages/assets.md
new file mode 100644
index 00000000..f4d1a247
--- /dev/null
+++ b/docs/1.5.x/packages/assets.md
@@ -0,0 +1,236 @@
+# Assets
+
+[[TOC]]
+
+## Directory Structure
+
+- To organize our assets, we need to create the following folder structure in the **`Resources`** folder:
+ - Create a folder named **`assets`**.
+ - Inside the **`assets`** folder, create the following folders: **`sass`**, **`js`**, and **`images`**.
+ - In the **sass** folder, add the files **_admin.scss_**, **_default.scss_**, and **_velocity.scss_**.
+ - In the **js** folder, add the file **app.js**.
+
+Here's the updated directory structure:
+
+```
+└── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Resources
+ ├── ...
+ └── assets
+ ├── sass
+ │ ├── admin.scss
+ │ ├── default.scss
+ │ └── velocity.scss
+ ├── js
+ │ └── app.js
+ └── images
+
+```
+
+## Compiling Assets
+
+To compile the assets, perform the following steps:
+
+1. Create a **`package.json`** and **`webpack.mix.js`** file inside the root of your package (**`packages/Webkul/Blog`**).
+
+2. Copy the following code into the **`package.json`** file:
+
+ ```json
+ {
+ "scripts": {
+ "dev": "npm run development",
+ "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "watch-poll": "npm run watch -- --watch-poll",
+ "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "prod": "npm run production",
+ "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
+ },
+ "devDependencies": {
+ "cross-env": "^7.0.2",
+ "laravel-mix": "^5.0.1",
+ "laravel-mix-merge-manifest": "^0.1.2",
+ "sass": "^1.62.0",
+ "sass-loader": "^8.0.2",
+ "vue-template-compiler": "^2.7.14"
+ }
+ }
+ ```
+
+3. Copy the following code into the **`webpack.mix.js`** file:
+
+ ```javascript
+ const mix = require("laravel-mix");
+
+ if (typeof mix == "undefined") {
+ const { mix } = require("laravel-mix");
+ }
+
+ require("laravel-mix-merge-manifest");
+
+ if (mix.inProduction()) {
+ var publicPath = "publishable/assets";
+ } else {
+ var publicPath = "../../../public/vendor/webkul/blog/assets";
+ }
+
+ mix.setPublicPath(publicPath).mergeManifest();
+
+ mix.disableNotifications();
+
+ mix
+ .js([__dirname + "/src/Resources/assets/js/app.js"], "js/blog.js")
+ .copyDirectory(
+ __dirname + "/src/Resources/assets/images",
+ publicPath + "/images"
+ )
+ .sass(
+ __dirname + "/src/Resources/assets/sass/app.scss",
+ "css/admin.css"
+ )
+ .sass(
+ __dirname + '/src/Resources/assets/sass/default.scss',
+ 'css/default.css'
+ )
+ .sass(
+ __dirname + '/src/Resources/assets/sass/velocity.scss',
+ 'css/velocity.css'
+ )
+ .options({
+ processCssUrls: false,
+ });
+
+ if (mix.inProduction()) {
+ mix.version();
+ }
+ ```
+
+4. Run **`npm install`** in the root of your package (**`packages/Webkul/Blog`**) to install all the dependencies.
+
+Now, your **`scss`** and **`js`** files are ready to use. You can write all your CSS and JS code here.
+
+To compile the assets, run **`npm run prod`**. This will compile all your CSS, JS, and images into the publishable folder. Finally, make sure to register your publishable in the **`BlogServiceProvider`**.
+
+::: tip
+You can also use **`npm run watch`**, which watches for changes in your assets and automatically updates the public path. When you're done making changes, run **`npm run prod`** to compile all your changes and move them to the publishable folder.
+:::
+
+## Load Assets From Package
+
+- To load the assets from your package, add the following code to the **`BlogServiceProvider.php`** file:
+
+ ```php
+ publishes([
+ __DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/blog/assets'),
+ ], 'public');
+ }
+ }
+ ```
+
+### Linking Stylesheets
+
+To link the stylesheets to the layouts, follow these steps:
+
+1. Create a **`layouts`** folder within the **`/Resources/views/shop/default`**, **`/Resources/views/shop/velocity`**, and **`/Resources/views/admin`** folders.
+
+2. Inside each **layouts** folder, create a file called **`style.blade.php`**.
+
+3. Copy the following code into the **`admin/layouts/style.blade.php`** file:
+
+ ```html
+
+ ```
+
+4. Copy the following code into the **`shop/default/layouts/style.blade.php`** file:
+
+ ```html
+
+ ```
+
+5. Copy the following code into the **`shop/velocity/layouts/style.blade.php`** file:
+
+ ```html
+
+ ```
+
+### Event Listener
+
+- To ensure that the admin layouts include our CSS, we should add an event listener. You can add the following code to the **`BlogServiceProvider.php`** file:
+
+ ```php
+ publishes([
+ __DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/blog/assets'),
+ ], 'public');
+
+ Event::listen('bagisto.admin.layout.head', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('blog::admin.layouts.style');
+ });
+
+ Event::listen('bagisto.shop.layout.head', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('blog::shop.default.layouts.style');
+ });
+
+ Event::listen('bagisto.shop.layout.head', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('blog::shop.velocity.layouts.style');
+ });
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ }
+ }
+ ```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/controllers.md b/docs/1.5.x/packages/controllers.md
new file mode 100644
index 00000000..d82ac3c9
--- /dev/null
+++ b/docs/1.5.x/packages/controllers.md
@@ -0,0 +1,149 @@
+# Controller
+
+[[TOC]]
+
+To learn in detail about Controllers, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/controllers).
+
+## Directory Structure
+
+- Create an **`Http`** folder in the **`packages/Webkul/Blog/src`** path. Inside the **`Http`** folder, create another folder named **`Controllers`**. Inside the **`Controllers`** folder, we need to create one file named **`Controller.php`** and two folders, namely **`Admin`** and **`Shop`**.
+
+- Inside both the **`Admin`** and **`Shop`** folders, create a **`PostController.php`** file. The updated directory structure will look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Http
+ └── Controllers
+ ├── Controller.php
+ ├── Admin
+ │ └── PostController.php
+ └── Shop
+ └── PostController.php
+ ```
+
+## Base Controller
+
+- **`Controller.php`**: This is the base controller. Add the following code to this file:
+
+ ```php
+ postRepository->all();
+
+ return view('blog::admin.index', ['blogs' => $blogs]);
+ }
+
+ /**
+ * Create.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function create() {
+ //
+ }
+
+ /**
+ * Store.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\View\View
+ */
+ public function store(Request $request) {
+ //
+ }
+ }
+ ```
+
+- **`Shop/PostController.php`**: This file is for shop usage. Add the following code to this file:
+
+ ```php
+ postRepository->with(['author'])->all();
+
+ return view('blog::shop.index', ['blogs' => $blogs]);
+ }
+
+ /**
+ * Blog details.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function blogDetails($id)
+ {
+ //
+ }
+ }
+ ```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/create-acl.md b/docs/1.5.x/packages/create-acl.md
new file mode 100644
index 00000000..cd84246e
--- /dev/null
+++ b/docs/1.5.x/packages/create-acl.md
@@ -0,0 +1,110 @@
+# Access Control List
+
+[[TOC]]
+
+## Introduction
+
+In addition to providing authentication services out of the box, Bagisto also offers an Access Control List (ACL) functionality. This feature allows administrators to control user access to different parts of Bagisto.
+
+## Directory Structure
+
+To configure the ACL, follow these steps:
+
+1. Create a new file named **`acl.php`** in the **`packages/Webkul/Blog/src/Config`** folder of your package.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Config
+ ├── acl.php
+ └── ...
+ ```
+
+2. Add the following code to **`acl.php`**:
+
+ ```php
+ 'blog',
+ 'name' => 'blog',
+ 'route' => 'blog.admin.index',
+ 'sort' => 2
+ ]
+ ];
+ ```
+
+ In the above code, we have defined an array for each menu item with the parameters (key, name, route, and sort). You need to define the menus you want to include in the ACL here.
+
+## Merge Configuration
+
+To merge the ACL configuration, follow these steps:
+
+1. Open the **`BlogServiceProvider`** class in the **`Webkul\Blog\Providers`** namespace.
+
+2. In the **`register`** method, add the following code to merge the ACL configuration:
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/acl.php', 'acl'
+ );
+ }
+ }
+ ```
+
+ This will merge the ACL configuration with the existing configuration.
+
+3. After making the changes, run the following command to cache the latest changes:
+
+ ```sh
+ php artisan optimize
+ ```
+
+ This will ensure that the latest ACL configuration is used.
+
+4. You can now check the updated ACL configuration in the admin panel:
+
+ :::details Admin ACL Output
+
+ ![Admin ACL Output](../../assets/1.5.x/images/package-development/admin-acl-output.png)
+
+ :::
+
+## Checking Roles and Permissions
+
+To check roles and permissions, follow these steps:
+
+1. Open the **`Admin`** model in the **`Webkul\User\Models`** namespace.
+
+2. In this model, you will find a relationship binding with the **`Role`** model in the same namespace. You can use this relationship to access all the permissions of the current user.
+
+3. We have provided the **`bouncer()`** helper function, which allows you to check permissions. Use the following code to check if the current user has a specific permission:
+
+ ```php
+ bouncer()->hasPermission($permission)
+ ```
+
+ Replace `$permission` with the actual permission you want to check.
+
+By following these steps, you can configure and manage the Access Control List (ACL) in Bagisto.
\ No newline at end of file
diff --git a/docs/1.5.x/packages/create-custom-configuration.md b/docs/1.5.x/packages/create-custom-configuration.md
new file mode 100644
index 00000000..75108965
--- /dev/null
+++ b/docs/1.5.x/packages/create-custom-configuration.md
@@ -0,0 +1,305 @@
+# Custom Configuration
+
+[[TOC]]
+
+Creating a custom configuration makes it easier for developers or non-developers to manage settings in Bagisto. In Bagisto, custom configurations can be found in the admin panel under the **Configuration Menu**.
+
+## Directory Structure
+
+To create a custom configuration for your application, follow these steps:
+
+1. Create a **`system.php`** file in the **`Config`** folder of your package:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ ├── ...
+ └── src
+ └── ...
+ └── Config
+ └── system.php
+
+ ```
+
+2. Inside the **`system.php`** file, include the following code:
+
+ ```php
+ 'blog',
+ 'name' => 'Blog',
+ 'sort' => 1
+ ],
+ [
+ 'key' => 'blog.settings',
+ 'name' => 'Blog Settings',
+ 'sort' => 1,
+ ],
+ [
+ 'key' => 'blog.settings.package',
+ 'name' => 'Package Status',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'status',
+ 'title' => 'Status',
+ 'type' => 'boolean',
+ 'validation' => 'required'
+ ]
+ ]
+ ],
+ [
+ 'key' => 'blog.settings.blog-setting',
+ 'name' => 'blog::app.admin.system.blog-setting',
+ 'sort' => 2,
+ 'fields' => [
+ [
+ 'name' => 'pagination',
+ 'title' => 'blog::app.admin.system.pagination',
+ 'type' => 'select',
+ 'validation' => 'required',
+ 'options' => [
+ [
+ 'title' => 'Yes',
+ 'value' => 1,
+ ],
+ [
+ 'title' => 'No',
+ 'value' => 0,
+ ],
+ ]
+ ],
+ [
+ 'name' => 'items',
+ 'title' => 'blog::app.admin.system.items',
+ 'type' => 'number',
+ 'validation' => 'numeric'
+ ]
+ ]
+ ]
+ ];
+ ```
+
+ This code defines the custom configuration settings. Each configuration has a key, name, sort, and fields (if applicable).
+
+## Merge Configuration
+
+To merge the custom configuration, follow these steps:
+
+1. Open the **`BlogServiceProvider`** class in the **`Webkul\Blog\Providers`** namespace.
+
+2. In the **`register`** method, add the following code to merge the custom configuration:
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ```
+
+ This code merges the custom configuration with the existing configuration.
+
+3. After making the changes, run the following command to cache the latest changes:
+
+ ```sh
+ php artisan optimize
+ ```
+
+ This ensures that the latest custom configuration is used.
+
+4. You can now check the updated configuration in the admin panel:
+
+ :::details Custom Configuration
+
+ ![Admin Custom Config Output](../../assets/1.5.x/images/package-development/custom-config-output.png)
+
+ :::
+
+## Supported Field Types
+
+Bagisto supports several field types for custom configurations. Let's explore each of them:
+
+### Text Type
+
+This field type provides an input field of type text.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+
+
+ [
+ 'name' => 'text_type',
+ 'title' => 'admin::app.admin.system.text-type',
+ 'type' => 'text',
+ 'default_value' => '',
+ ],
+ ],
+ ],
+ // ...
+];
+```
+
+### Number Type
+
+This field type provides an input field of type number.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'number_type',
+ 'title' => 'admin::app.admin.system.number-type',
+ 'type' => 'number',
+ ],
+ ],
+ ],
+ // ...
+];
+```
+
+### Boolean Type
+
+This field type provides an enable/disable switch.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'boolean_type',
+ 'title' => 'admin::app.admin.system.boolean-type',
+ 'type' => 'boolean',
+ ],
+ ],
+ ],
+ // ...
+];
+```
+
+### Select Type
+
+This field type provides a select field with specified options.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'select_type',
+ 'title' => 'admin::app.admin.system.select-type',
+ 'type' => 'select',
+ 'options' => [
+ [
+ 'title' => 'option_1',
+ 'value' => 'value_1',
+ ],
+ [
+ 'title' => 'option_2',
+ 'value' => 'vallue_2',
+ ],
+ ],
+ ],
+ ],
+ ],
+ // ...
+];
+```
+
+### Textarea Type
+
+This field type provides a textarea field, mostly used for long text.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'textarea_type',
+ 'title' => 'admin::app.admin.system.textarea-type',
+ 'type' => 'textarea'
+ ],
+ ],
+ ],
+ // ...
+];
+```
+
+### Image Type
+
+This field type provides a file upload option for uploading images.
+
+#### Example
+
+```php
+return [
+ // ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'image_type',
+ 'title' => 'admin::app.admin.system.image-type',
+ 'type' => 'image',
+ 'validation' => 'mimes:bmp,jpeg,jpg,png,webp',
+ ],
+ ],
+ ],
+ // ...
+];
+```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/create-migrations.md b/docs/1.5.x/packages/create-migrations.md
new file mode 100644
index 00000000..928baba8
--- /dev/null
+++ b/docs/1.5.x/packages/create-migrations.md
@@ -0,0 +1,112 @@
+# Migrations
+
+[[TOC]]
+
+To understand Migrations in detail, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/migrations).
+
+## Using Bagisto Package Generator
+
+This command creates a new migration class in the **`packages/Webkul/Blog/src/Database/Migrations`** directory.
+
+```sh
+php artisan package:make-migration CreatePostsTable Webkul/Blog
+```
+
+## Using Laravel Artisan Command
+
+- Create a **`Database`** folder in the **`packages/Webkul/Blog/src`** path. Inside the **`Database`** folder, create **`Migrations`** and **`Seeders`** folders.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Database
+ ├── Migrations
+ └── Seeders
+ ```
+
+- Run the following command with the **`--path`** option to specify where your migration file will be placed.
+
+ ```sh
+ php artisan make:migration create_posts_table --path=packages/Webkul/Blog/src/Database/Migrations
+ ```
+
+- Copy the code provided here and paste it into your migration file.
+
+ ```php
+ id();
+ $table->string('title')->nullable();
+ $table->longText('description')->nullable();
+ $table->integer('user_id');
+ $table->tinyInteger('status')->default(1);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('posts');
+ }
+ };
+ ```
+
+### Loading Migration from Package
+
+- We need to add the migrations to our service provider to load them.
+
+ ```php
+ loadMigrationsFrom(__DIR__ .'/../Database/Migrations');
+ }
+ }
+ ```
+
+### Creating Tables from Migrations
+
+- Run the following command to create the **`posts`** table in your database.
+
+ ```sh
+ php artisan migrate
+ ```
diff --git a/docs/1.5.x/packages/create-models.md b/docs/1.5.x/packages/create-models.md
new file mode 100644
index 00000000..2adc7e9d
--- /dev/null
+++ b/docs/1.5.x/packages/create-models.md
@@ -0,0 +1,192 @@
+# Models
+
+[[TOC]]
+
+To understand Models in detail, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/eloquent).
+
+We are using the [konekt/concord](https://packagist.org/packages/konekt/concord) package, which is an extension of Laravel. It helps in building modular Laravel applications.
+
+## Using Bagisto Package Generator
+
+- This command creates a new **`Post`** Model inside your package.
+
+ ```sh
+ php artisan package:make-model Post Webkul/Blog
+ ```
+
+- This command creates the following files:
+ - New model **`Post.php`** in the **`packages/Webkul/Blog/src/Models`** directory.
+ - New model proxy **`PostProxy.php`** in the **`packages/Webkul/Blog/src/Models`** directory.
+ - New model contract **`Post.php*`** in the **`packages/Webkul/Blog/src/Contracts`** directory.
+
+## Using Laravel Artisan Command
+
+Before creating the model class, we need to create two things: the **`Contract`** and the **`Proxy`**.
+
+### Contract
+
+Laravel's Contracts are a set of interfaces that define the core services provided by the framework. For example, the **`Illuminate\Contracts\Queue\Queue`** contract defines the methods needed for queueing jobs, while the **`Illuminate\Contracts\Mail\Mailer`** contract defines the methods needed for sending an email.
+
+Each contract has a corresponding implementation provided by the framework. For example, Laravel provides a queue implementation with various drivers and a mailer implementation powered by SwiftMailer.
+
+All Laravel contracts are stored in their own GitHub repository. This provides a quick reference for all available contracts and a single, decoupled package that can be used by package developers.
+
+- Now, create a folder named **`Contracts`** inside **`Webkul/Blog/src/`** and create an interface file named **`Post.php`**.
+
+ ```
+ packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Contracts
+ └── Post.php
+ ```
+
+- Copy the following code into the **`Post.php`** file.
+
+ ```php
+ belongsTo(Admin::class, 'user_id');
+ }
+ }
+ ```
+
+### Module Service Provider
+
+- Now, we need to create a provider named **`ModuleServiceProvider.php`** inside **`Webkul/Blog/src/Providers`**.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Providers
+ ├── BlogServiceProvider.php
+ └── ModuleServiceProvider.php
+ ```
+
+- In this file, we register the models used in this package. You can see the code below.
+
+ ```php
+ [
+ // Other service providers
+ \Webkul\Blog\Providers\ModuleServiceProvider::class,
+ ]
+ ];
+ ```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/create-package.md b/docs/1.5.x/packages/create-package.md
new file mode 100644
index 00000000..41b57f56
--- /dev/null
+++ b/docs/1.5.x/packages/create-package.md
@@ -0,0 +1,195 @@
+# Getting Started
+
+[[TOC]]
+
+## Using Bagisto Package Generator
+
+To facilitate package development, you can use the [Bagisto Package Generator](https://github.com/bagisto/bagisto-package-generator). Follow the steps below to install it:
+
+1. Install the Bagisto Package Generator by running the following command in the root folder of your Bagisto application:
+
+ ```shell
+ composer require bagisto/bagisto-package-generator
+ ```
+
+2. Once installed, you can generate your package using the following command:
+
+ - If the package directory does not exist:
+
+ ```shell
+ php artisan package:make Webkul/Blog
+ ```
+
+ - If the package directory already exists, you can use the **`--force`** option to overwrite it:
+
+ ```shell
+ php artisan package:make Webkul/Blog --force
+ ```
+
+ This command will set up the necessary files and directories in the **`packages`** directory.
+
+### Registering Your Package
+
+To register your package, follow these steps:
+
+1. Add your package's namespace to the **`psr-4`** section in the **`composer.json`** file located in the root directory of your Bagisto application. Update it as follows:
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ // Other PSR-4 namespaces
+ "Webkul\\Blog\\": "packages/Webkul/Blog/src"
+ }
+ }
+ ```
+
+2. Register your package's service provider in the **`config/app.php`** file located in the root directory of your Bagisto application. Add the following line to the **`providers`** array:
+
+ ```php
+ ServiceProvider::defaultProviders()->merge([
+ // Other service providers
+ Webkul\Blog\Providers\BlogServiceProvider::class,
+ ])->toArray(),
+
+ // Other configuration options
+ ];
+ ```
+
+3. Run the following commands to autoload your package and publish its assets and configurations:
+
+ ```shell
+ composer dump-autoload
+ php artisan optimize
+ php artisan vendor:publish --force
+ ```
+
+ When prompted to select which items to publish, choose the number corresponding to **`"Webkul\Blog\Providers\BlogServiceProvider"`** and press enter to publish all assets and configurations.
+
+::: details Example Output in the Browser
+
+![helloworld-admin-browser-output](../../assets/1.5.x/images/package-development/blog-package-output.png)
+
+:::
+
+Congratulations! Your package is now registered and ready to use. Start creating something cool!
+
+## Manual Setup of Files
+
+If you prefer to set up your package manually, follow these steps assuming you are familiar with package directory structures and workflows. We'll use the default **`package`** folder in Bagisto as an example.
+
+### Create Package Directory
+
+1. Inside the **`packages/Webkul`** folder, create a folder with your package name. Your structure should look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ ```
+
+2. In your package folder, create a folder named as **`src`**. This is where you'll put all your package-related files. Your updated structure will look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ```
+
+### Create Service Provider
+
+1. In the **`src`** folder, create a folder named as **`Providers`**. Inside that folder, create a file named as **`BlogServiceProvider.php`**. Your structure should look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ └── Providers
+ └── BlogServiceProvider.php
+ ```
+
+2. Copy the following code and paste it into **`BlogServiceProvider.php`**:
+
+ ```php
+ ServiceProvider::defaultProviders()->merge([
+ // Other service providers
+ Webkul\Blog\Providers\BlogServiceProvider::class,
+ ])->toArray(),
+
+ // Other configuration options
+ ];
+ ```
+
+3. Run the following command to autoload your package:
+
+ ```shell
+ composer dump-autoload
+ ```
+
+ Your package is now ready to use!
\ No newline at end of file
diff --git a/docs/1.5.x/packages/customize-hompepage-menu.md b/docs/1.5.x/packages/customize-hompepage-menu.md
new file mode 100644
index 00000000..f294d147
--- /dev/null
+++ b/docs/1.5.x/packages/customize-hompepage-menu.md
@@ -0,0 +1,29 @@
+# Homepage Menu
+
+[[TOC]]
+
+This section provides an overview of menu items, how to access them, and how they can be customized. Both the **`default`** and **`velocity`** themes display categories in the menu items.
+
+## Accessing Categories
+
+To access the menu categories, you can utilize the **`CategoryRepository`** class located in the **`Webkul\Category\Repositories\CategoryRepository`** namespace. This repository class provides useful methods for retrieving and managing categories.
+
+One such method is **`getVisibleCategoryTree`**, which returns a list of all visible categories under the specified root category. You can pass the ID of the main root category as a parameter to this method.
+
+## Example from the Default Theme
+
+In the default theme's blade file, you can find the following code snippet:
+
+```php
+@foreach (app('Webkul\Category\Repositories\CategoryRepository')->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id) as $category)
+ // ...
+@endforeach
+```
+
+You can iterate through the retrieved categories and customize the menu according to your specific requirements.
+
+::: tip
+
+The **`CategoryRepository`** class provides several other methods for working with categories. Take some time to explore and utilize those methods as needed.
+
+:::
\ No newline at end of file
diff --git a/docs/1.5.x/packages/datagrid.md b/docs/1.5.x/packages/datagrid.md
new file mode 100644
index 00000000..f55747b9
--- /dev/null
+++ b/docs/1.5.x/packages/datagrid.md
@@ -0,0 +1,337 @@
+# DataGrid
+
+[[TOC]]
+
+## Introduction
+
+A DataGrid is a concept of displaying your database records in a tabular format. It is a powerful tool that helps you present large amounts of data in an organized way. At Bagisto, we have implemented this feature, which allows you to use it to display data in a tabular format or write code from scratch to display data. In addition to the basic functionality of DataGrid, we have also implemented additional features such as sorting, filtering, and mass action, which are explained in detail below.
+
+## Global Properties of DataGrid
+
+Here are the global properties of the DataGrid:
+
+| Property | Functionality |
+| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **`index`** | This property is defined in the grid, and the value assigned to this property must be unique, typically the primary key, so that data will be uniquely identified and operations performed will be based on your index value. |
+| **`sortOrder`** | The **`sortOrder`** key is used to arrange the results in ascending or descending order. Set the **`sortOrder`** variable to **`asc`** or **`desc`**. |
+| **`queryBuilder`** | This is used to perform database operations in your application. |
+| **`enableMassAction`** | This accepts boolean values **`true`** or **`false`** to enable or disable the mass action in DataGrid. |
+| **`enableAction`** | This accepts boolean values **`true`** or **`false`** to enable or disable the action column of DataGrid. |
+| **`paginate`** | Set the **`paginate`** property to **`true`** to allow pagination on your page. |
+| **`itemsPerPage`** | The **`itemsPerPage`** key is used to display the number of items per page. |
+| **`enableFilterMap`** | This accepts boolean values **`true`** or **`false`** to enable or disable filtering on the basis of columns. |
+
+## How DataGrid Works
+
+The **`DataGrid`** abstract class is created in the **`Webkul\Ui`** package. In the abstract class, a list of properties and methods are declared. To create your own DataGrid, you need to extend the **`Webkul\Ui\DataGrid\DataGrid`** abstract class.
+
+In **`Webkul\Ui\DataGrid\DataGrid.php`** abstract class, two abstract methods are declared **`prepareQueryBuilder()`** and **`addColumns()`**. You can prepare your grid by defining these two methods.
+
+- **`prepareQueryBuilder()`**: In this method, records are retrieved through queries applicable to the database and stored in a collection. When records are retrieved, the **`setQueryBuilder()`** method is called.
+
+- **`setQueryBuilder()`**: This method is used for setting the **`$queryBuilder`**.
+
+ ```php
+ public function prepareQueryBuilder()
+ {
+ $queryBuilder = DB::table('posts')
+ ->select('id', 'title', 'status', 'created_at', 'updated_at')
+ ->where('user_id', '=', auth()->guard('admin')->user()->id);
+
+ $this->setQueryBuilder($queryBuilder);
+ }
+ ```
+
+- **`addColumns()`**: In this method, columns are created which are displayed in the grid. The parameter accepts an array in key-value pairs. Some of the essential keys are described below:
+
+ | Key | Functionality |
+ | ------------- | ------------------------------------------------------------------------ |
+ | **`index`** | This key is defined in the grid, and the value assigned to this key must be unique, typically the primary key, so that data will be uniquely identified and operations performed will be based on your index value. |
+ | **`label`** | This key defines the name of the column. |
+ | **`type`** | This key accepts the type of data in the column. |
+ | **`searchable`** | This accepts boolean values **`true`** or **`false`** to make the column searchable. |
+ | **`sortable`** | This accepts boolean values **`true`** or **`false`** to make the column sortable. |
+ | **`filterable`** | This accepts boolean values **`true`** or **`false`** to make the column filterable. |
+ | **`wrapper`** | Perform actions based on a condition satisfied or apply some customization to the value. |
+
+ ```php
+ public function addColumns()
+ {
+ $this->addColumn([
+ 'index' => 'id',
+ 'label' => trans('blog::app.admin.datagrid.id'),
+ 'type' => 'number',
+ 'searchable' => false,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+ }
+ ```
+
+- **`prepareActions()`**: This method is defined when there is a need to perform any action such as edit or delete on the grid. In this method, the **`addAction()`** method is called to define a particular action.
+
+- **`addAction()`**: This method is used for adding actions (like **`edit`**, **`delete`**, etc.) to each row generated by the DataGrid.
+
+ | Key | Functionality |
+ | ------------- | ------------------------------------------------------------------------ |
+ | **`title`** | The text to be displayed is written here. |
+ | **`method`** | HTTP methods are declared. |
+ | **`route`** | This key accepts the route of the icon. |
+ | **`icon`** | Class of the icon to be displayed in the action column. You may prefer text also. |
+
+ ```php
+ public function prepareActions()
+ {
+ $this->addAction([
+ 'title' => trans('blog::app.admin.datagrid.edit'),
+ 'method' => 'GET',
+ 'route' => 'admin.blog.edit',
+ 'icon' => 'icon pencil-lg-icon'
+ ]);
+ }
+ ```
+
+## Multiple DataGrids
+
+When working with multiple DataGrids, the default DataGrid implementation can handle only a single request at a time. This means that operations such as filtration, sorting, and others can conflict when implementing multiple DataGrids. To overcome this, we provide a trait called **`ProvideDataGridPlus`** in the namespace **`Webkul\Ui\DataGrid\Traits`**.
+
+Follow the steps below to implement multiple DataGrids:
+
+1. Create a folder called **`DataGrids`** inside the **`src`** folder of your package. Within the **`DataGrids`** folder, create a file called **`PostDataGrid.php`** that extends the **`DataGrid`** class from the **`Webkul\Ui`** package. The directory structure will be as follows:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── DataGrids
+ └── PostDataGrid.php
+ ```
+
+2. Add the following code to your DataGrid file, i.e., **`PostDataGrid.php`**:
+
+ ```php
+ namespace Webkul\Blog\DataGrids;
+
+ use Webkul\Ui\DataGrid\DataGrid;
+
+ class PostDataGrid extends DataGrid
+ {
+ // ...
+ }
+ ```
+
+### DataGrid to JSON
+
+3. Import the **`ProvideDataGridPlus`** trait into the **`PostDataGrid`** class:
+
+ ```php
+ namespace Webkul\Blog\DataGrids;
+
+ use Webkul\Ui\DataGrid\Traits\ProvideDataGridPlus;
+
+ class PostDataGrid extends DataGrid
+ {
+ use ProvideDataGridPlus;
+
+ // ...
+ }
+ ```
+
+4. After that, the **`toJson()`** method will be available in the DataGrid instance, which provides data to the component.
+
+5. Now, go to **`Admin/PostController.php`** and locate the **`index`** method. Use the **`toJson()`** method as follows:
+
+ ```php
+ use Webkul\Blog\DataGrids\PostDataGrid;
+
+ class PostController extends Controller
+ {
+ /**
+ * Display a listing of the resource.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function index()
+ {
+ if (request()->ajax()) {
+ return app(PostDataGrid::class)->toJson();
+ }
+
+ return view('blog::admin.index');
+ }
+
+ // ...
+ }
+ ```
+
+### Render DataGrid
+
+6. In the view file **`views/admin/index.blade.php`**, use the **`datagrid-plus`** component and specify the URL from which it will load the JSON data:
+
+ ```php
+
+ ...
+
+
+
+ ...
+
+ ```
+
+ With these steps, your DataGrid is now ready to be used.
+
+::: warning
+Make sure to copy the sample code provided below to your own **`PostDataGrid.php`** file, as we have already included all the necessary methods and functions there. This code can be used later as an example for your implementation.
+:::
+
+## Sample DataGrid
+
+Here's an improved version of the provided DataGrid sample:
+
+```php
+select('id', 'title', 'status', 'created_at', 'updated_at')
+ ->where('user_id', '=', auth()->guard('admin')->user()->id);
+
+ $this->setQueryBuilder($queryBuilder);
+ }
+
+ /**
+ * Add columns.
+ */
+ public function addColumns()
+ {
+ $this->addColumn([
+ 'index' => 'id',
+ 'label' => trans('blog::app.admin.datagrid.id'),
+ 'type' => 'number',
+ 'searchable' => false,
+ 'sortable' => true,
+ 'filterable' => true,
+ ]);
+
+ $this->addColumn([
+ 'index' => 'title',
+ 'label' => trans('blog::app.admin.datagrid.title'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => false,
+ 'wrapper' => function ($value) {
+ return substr($value->title, 0, 30);
+ },
+ ]);
+
+ $this->addColumn([
+ 'index' => 'status',
+ 'label' => trans('blog::app.admin.datagrid.status'),
+ 'type' => 'boolean',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true,
+ 'closure' => function ($value) {
+ $html = '';
+
+ if ($value->status) {
+ $html .= '' . trans('blog::app.admin.datagrid.active') . '';
+ } else {
+ $html .= '' . trans('blog::app.admin.datagrid.inactive') . '';
+ }
+
+ return $html;
+ },
+ ]);
+
+ $this->addColumn([
+ 'index' => 'created_at',
+ 'label' => trans('blog::app.admin.datagrid.created_at'),
+ 'type' => 'datetime',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true,
+ ]);
+
+ $this->addColumn([
+ 'index' => 'updated_at',
+ 'label' => trans('blog::app.admin.datagrid.updated_at'),
+ 'type' => 'datetime',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true,
+ ]);
+ }
+
+ /**
+ * Prepare actions.
+ */
+ public function prepareActions()
+ {
+ $this->addAction([
+ 'title' => trans('blog::app.admin.datagrid.edit'),
+ 'method' => 'GET',
+ 'route' => 'admin.blog.edit',
+ 'icon' => 'icon pencil-lg-icon',
+ ]);
+
+ $this->addAction([
+ 'title' => trans('blog::app.admin.datagrid.delete'),
+ 'method' => 'POST',
+ 'route' => 'admin.blog.delete',
+ 'icon' => 'icon trash-icon',
+ ]);
+ }
+
+ /**
+ * Prepare mass actions.
+ */
+ public function prepareMassActions()
+ {
+ $this->addMassAction([
+ 'type' => 'update',
+ 'action' => route('admin.blog.massupdate'),
+ 'label' => trans('blog::app.admin.datagrid.massupdate'),
+ 'method' => 'POST',
+ 'options' => [
+ trans('blog::app.admin.datagrid.active') => 1,
+ trans('blog::app.admin.datagrid.inactive') => 0,
+ ],
+ ]);
+
+ $this->addMassAction([
+ 'type' => 'delete',
+ 'action' => route('admin.blog.massdelete'),
+ 'label' => trans('blog::app.admin.datagrid.massdelete'),
+ 'method' => 'POST',
+ ]);
+ }
+}
+```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/layouts.md b/docs/1.5.x/packages/layouts.md
new file mode 100644
index 00000000..3b5a4c2e
--- /dev/null
+++ b/docs/1.5.x/packages/layouts.md
@@ -0,0 +1,56 @@
+# Layouts
+
+[[TOC]]
+
+To learn in detail about Layouts, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/blade).
+
+## Extend Admin Layout
+
+Now, let's extend the default layout of the Bagisto admin panel by using **`@extends('admin::layouts.master')`** in the file **`packages/Webkul/Blog/src/Resources/views/admin/index.blade.php`**. You can copy the following template to your **`index.blade.php`** file:
+
+```html
+@extends('admin::layouts.master')
+
+@section('page_title') {{ __('blog::app.admin.index.page-title') }} @stop
+
+@section('content-wrapper')
+
+
+
+
+
{{ __('blog::app.admin.index.page-title') }}
+
+
+
+
+
+
+
+
+@stop
+```
+
+## Extend Shop Layout
+
+Similarly, for the file **`packages/Webkul/Blog/src/Resources/views/shop/velocity/index.blade.php`**, you can extend the shop layout by using **`@extends('shop::layouts.master')`**. You can copy the following template to your **`index.blade.php`** file:
+
+```html
+@extends('shop::layouts.master')
+
+@section('page_title') {{ __('blog::app.shop.blogs.page-title') }} @stop
+
+@section('content-wrapper')
+
+
+
+
+
+
+@stop
+```
+
+::: warning
+Notice that there are translations used in the blade files, so you will also need to add the corresponding translations in **`lang/app.php`**.
+:::
+
+If you don't want to include these layouts, you can create your own master file.
\ No newline at end of file
diff --git a/docs/1.5.x/packages/localization.md b/docs/1.5.x/packages/localization.md
new file mode 100644
index 00000000..0b98ec4e
--- /dev/null
+++ b/docs/1.5.x/packages/localization.md
@@ -0,0 +1,86 @@
+# Localization
+
+[[TOC]]
+
+To learn in detail about Localization, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/localization).
+
+## Directory Structure
+
+- Now, let's create a language file for our package. Create a **`lang`** folder in the **`packages/Webkul/Blog/src/Resources`** path.
+
+- Inside the **`lang`** folder, you can create different folders for language translations. For example, you can create folders for English ('en'), Hindi ('hi'), etc. For now, let's create a folder named **`en`** (representing the language code). Inside the **`en`** folder, create a file named **`app.php`** for language translation.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Resources
+ ├── ...
+ └── lang
+ └── en
+ └── app.php
+ ```
+
+- Now, let's write a translation in **`app.php`** as follows:
+
+ ```php
+ [
+ 'name' => 'John Doe'
+ ]
+ ];
+ ```
+
+## Load Translation from Package
+
+- We need to register the language file in the service provider.
+
+ ```php
+ loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'blog');
+ }
+ }
+ ```
+
+- Add the following code to your Blade file:
+
+ ```html
+ {{ __('blog::app.admin.name') }}
+ ```
+
+ ::: details Admin Output
+
+ ![Translation Output](../../assets/1.5.x/images/package-development/blog-admin-lang-output.png)
+
+ :::
+
+ ::: details Shop Output
+
+ ![Translation Output](../../assets/1.5.x/images/package-development/blog-shop-lang-output.png)
+
+ :::
\ No newline at end of file
diff --git a/docs/1.5.x/packages/routes.md b/docs/1.5.x/packages/routes.md
new file mode 100644
index 00000000..79f8eb58
--- /dev/null
+++ b/docs/1.5.x/packages/routes.md
@@ -0,0 +1,80 @@
+# Routes
+
+[[TOC]]
+
+To learn in detail about Routes, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/routing).
+
+## Directory Structure
+
+- Create a **`Routes`** folder inside **`packages/Webkul/Blog/src`** and create two files named **`admin-routes.php`** and **`shop-routes.php`**. The updated directory structure will look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Routes
+ ├── admin-routes.php
+ └── shop-routes.php
+ ```
+
+- **`admin-routes.php`**: This file is for admin routes. Add the following code to this file:
+
+ ```php
+ ['web', 'admin'], 'prefix' => config('app.admin_url')], function () {
+ Route::get('/blog', [PostController::class, 'index']);
+ });
+ ```
+
+- **`shop-routes.php`**: This file is for shop routes. Add the following code to this file:
+
+ ```php
+ ['web', 'theme', 'locale', 'currency']], function () {
+ Route::get('/blogs', [PostController::class, 'index']);
+ });
+ ```
+
+## Loading Routes
+
+- Now, we need to register our routes in the service provider's boot method, which is located in **`BlogServiceProvider.php`**.
+
+ ```php
+ loadRoutesFrom(__DIR__ . '/../Routes/admin-routes.php');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Routes/shop-routes.php');
+ }
+ }
+ ```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/store-data-through-repositories.md b/docs/1.5.x/packages/store-data-through-repositories.md
new file mode 100644
index 00000000..38fc23ef
--- /dev/null
+++ b/docs/1.5.x/packages/store-data-through-repositories.md
@@ -0,0 +1,78 @@
+# Repository
+
+[[TOC]]
+
+## Introduction
+
+In traditional development, application logic is often written directly in the controller. However, there is an alternative approach that abstracts some of these calls into PHP classes called Repositories. The purpose of repositories is to decouple models from controllers and provide readable names for complex queries.
+
+This file defines our Repository class. Instances of this class have a model property that is bound to an Eloquent model. With this binding in the constructor, we can call Eloquent methods such as findOrFail, update, or all from the class methods.
+
+We are using the Prettus Repository package. You can find all available methods in the Prettus repository [here](https://github.com/andersao/l5-repository). Here are some examples:
+
+Examples:
+
+| Sl. no. | Method | Description |
+| ------- | ------ | ----------- |
+| 1 | all | Find all results in the Repository |
+| 2 | paginate | Find all results in the Repository with pagination |
+| 3 | find | Find a result by ID |
+| 4 | with(['table_name'])| Load the model relationships |
+| 5 | findWhereIn | Find results by multiple values in one field|
+
+```php
+// Bound in constructor
+public function __construct(protected PostRepository $postRepository) {}
+```
+
+```php
+// Find all results in the Repository
+$posts = $this->postRepository->all();
+```
+
+## Using Bagisto Package Generator
+
+- This command creates a new Repository class in the **`packages/Webkul/Blog/src/Repository`** directory.
+
+ ```sh
+ php artisan package:make-repository PostRepository Webkul/Blog
+ ```
+
+## Manual Setup of Files
+
+- Create a **`Repository`** folder inside **`Webkul/Blog/src/`** and create a file named **`PostRepository.php`**. In the repository class, create the **`model()`** method that returns the path of your contract class.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Repository
+ └── PostRepository.php
+ ```
+
+- Copy the following code into your newly created repository file.
+
+ ```php
+ validate([
+ 'title' => 'required|unique:posts|max:255',
+ 'body' => 'required',
+ ]);
+}
+```
+
+Alternatively, you can manually create a validator instance using the Validator facade, as shown in this example:
+
+```php
+ 'required',
+ 'email' => 'required|email',
+ 'message' => 'required|max:250',
+ ];
+
+ $customMessages = [
+ 'required' => 'The :attribute field is required.',
+ ];
+
+ $this->validate($request, $rules, $customMessages);
+ }
+}
+```
+
+## Validation Using Vue
+
+### Introduction
+
+VeeValidate is a validation library for Vue.js that provides plenty of validation rules out of the box, along with support for custom rules. It is template-based and similar to the HTML5 validation API, making it easy to validate HTML5 inputs as well as custom Vue components. VeeValidate also supports localization with 44 languages maintained by the community.
+
+For detailed information about validation in Vue.js using VeeValidate, refer to the [VeeValidate documentation](https://vee-validate.logaretm.com/v2/guide/).
+
+### Installation
+
+Bagisto already comes with the VeeValidate library, so there is no need to install it separately.
+
+### Configuration
+
+Bagisto includes the configuration for **`vee-validate`**. For example, you can find the configuration in the following path: **`bagisto/packages/Webkul/Admin/src/Resources/assets/js/app.js`**.
+
+```js
+import Vue from 'vue';
+import VeeValidate from 'vee-validate';
+
+/**
+ * Language imports.
+*/
+import de from 'vee-validate/dist/locale/en';
+import de from 'vee-validate/dist/locale/de';
+import fa from 'vee-validate/dist/locale/fa';
+
+/**
+ * Vue plugins.
+*/
+Vue.use(VeeValidate, {
+ dictionary: {
+ en: en,
+ de: de,
+ fa: fa,
+ },
+ events: 'input|change|blur'
+});
+```
+
+### Examples
+
+Here are some examples of Vue validation using VeeValidate:
+
+```html
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/docs/1.5.x/packages/views.md b/docs/1.5.x/packages/views.md
new file mode 100644
index 00000000..43b8ba7c
--- /dev/null
+++ b/docs/1.5.x/packages/views.md
@@ -0,0 +1,108 @@
+# Views
+
+[[TOC]]
+
+To learn in detail about Views, you can visit the Laravel documentation [here](https://laravel.com/docs/10.x/views).
+
+## Directory Structure
+
+- Create a **`Resources`** folder in the **`packages/Webkul/Blog/src`** path. Inside the **`Resources`** folder, create another folder named **`views`**. Now, inside the **`views`** folder, we need to create two folders, namely **`admin`** and **`shop`**. Finally, we need to create two more folders, namely **`default`** and **`velocity`**, under the **`shop`** folder. The updated directory structure will look like this:
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Resources
+ └── views
+ ├── admin
+ └── shop
+ ├── default
+ └── velocity
+ ```
+
+ ::: tip The default and velocity folders
+ Whenever you create a Blade file for the shop front, you need to keep the same file in both the **`default`** and **`velocity`** folders. This is because we are using the **`theme`** middleware. When we use the **`default`** theme, the files will be called from the **`default`** folder, and when we use the **`velocity`** theme, the files will be called from the **`velocity`** folder.
+ :::
+
+ ::: warning
+ In this tutorial, we are using the **`theme`** middleware and the **`velocity`** theme. Therefore, it is necessary to keep the files in the **`velocity`** folder. However, if we are not using the **`default`** theme, it is not necessary to keep the same files in the **`default`** folder.
+ :::
+
+- Inside each folder, **`admin`** and **`velocity`**, create a file named **`index.blade.php`** and add some HTML to it.
+
+ ```
+ └── packages
+ └── Webkul
+ └── Blog
+ └── src
+ ├── ...
+ └── Resources
+ └── views
+ ├── admin
+ │ └── index.blade.php
+ └── shop
+ ├── default
+ └── velocity
+ └── index.blade.php
+
+ ```
+
+ - **`admin/index.blade.php`**
+
+ ```html
+
+ ```
+
+## Load Views from Package
+
+- Now, we need to register our views in the service provider's `boot` method. Open the file **`packages/Webkul/Blog/src/Providers/BlogServiceProvider.php`** and update it as follows:
+
+ ```php
+ loadViewsFrom(__DIR__ . '/../Resources/views', 'blog');
+ }
+ }
+ ```
+
+- Now, check the routes in your browser.
+
+ ::: details Shop Output
+
+ ![Shop Browser Output](../../assets/1.5.x/images/package-development/blog-shop-output.png)
+
+ :::
+
+ ::: details Admin Output
+
+ ![Admin Browser Output](../../assets/1.5.x/images/package-development/blog-admin-output.png)
+
+ :::
diff --git a/docs/1.5.x/products/simple.md b/docs/1.5.x/products/simple.md
new file mode 100644
index 00000000..6ca0fb29
--- /dev/null
+++ b/docs/1.5.x/products/simple.md
@@ -0,0 +1,9 @@
+# Deploy
+
+this article will explain how you can deploy your Bagisto store to your production server when you have been developing your Bagisto store on your local system.
+
+## Deploy Bagisto with (S)FTP
+
+## Deploy on Cpanel
+
+## Deploy on Plesk
diff --git a/docs/1.5.x/prologue/README.md b/docs/1.5.x/prologue/README.md
new file mode 100644
index 00000000..08f5cdf6
--- /dev/null
+++ b/docs/1.5.x/prologue/README.md
@@ -0,0 +1,23 @@
+# Prologue
+
+## Introduction to Bagisto
+
+[Bagisto](https://bagisto.com/) is a fantastic open-source eCommerce platform that allows businesses to create modern online stores easily. Bagisto offers a wide range of customizable features to meet the specific needs of any online business.
+
+The platform is built on top of the reliable [Laravel](https://laravel.com/) framework and [Vue.js](https://vuejs.org/), a user-friendly JavaScript framework. It provides businesses with a user-friendly interface and powerful tools to manage their online stores, handle inventory and orders, and create a smooth shopping experience for customers.
+
+## Customization and Branding
+
+With Bagisto, businesses have the flexibility to customize the look and feel of their online stores, from choosing themes and layouts to adding unique branding elements. The platform offers a comprehensive set of marketing and promotional tools, enabling businesses to attract customers and drive sales effectively.
+
+## SEO Optimization
+
+One of Bagisto's standout features is its robust SEO capabilities. It includes built-in SEO tools and optimization options, empowering businesses to improve their search engine rankings and increase organic traffic to their online stores.
+
+## Payment and Shipping Integration
+
+Moreover, Bagisto supports a wide range of payment gateways, allowing businesses to offer convenient and secure payment options to their customers. It also integrates seamlessly with popular shipping providers, streamlining the order fulfillment process and ensuring reliable and timely deliveries.
+
+## Summary
+
+In summary, Bagisto is a powerful and flexible eCommerce platform that empowers businesses to build and manage online stores efficiently. With its customizable features, user-friendly interface, reliable framework, robust SEO capabilities, and comprehensive set of tools, Bagisto is the perfect choice for businesses looking to establish a strong online presence, drive sales growth, and deliver exceptional customer experiences.
\ No newline at end of file
diff --git a/docs/1.5.x/prologue/contribution-guide.md b/docs/1.5.x/prologue/contribution-guide.md
new file mode 100644
index 00000000..7763c460
--- /dev/null
+++ b/docs/1.5.x/prologue/contribution-guide.md
@@ -0,0 +1,64 @@
+# Contribution Guide
+
+[[Toc]]
+
+## Bug Reports
+
+To encourage active collaboration, Bagisto welcomes both bug reports and pull requests. Instead of just reporting bugs, we encourage you to submit pull requests that include fixes or negative test cases demonstrating the issue. When filing a bug report, please provide a clear title and description of the problem. Include as much relevant information as possible, along with a code sample that reproduces the bug. The goal is to make it easy for everyone to understand and fix the issue.
+
+Bug reports are meant to foster collaboration and find solutions. By reporting bugs, you can engage others in solving the problem and contribute to the project's improvement.
+
+## Projects to Contribute
+
+You can contribute to the following projects:
+
+- Bagisto
+- Bagisto docs
+- Laravel-aliexpress-dropship
+- Laravel-aliexpress-dropship-chrome-extension
+- Bagisto-custom-style-extension
+
+## Feature Requests
+
+We welcome proposals for new features and enhancements to the existing Bagisto app. If you have a new feature in mind, please be prepared to contribute some of the code required to implement it.
+
+## Branch Selection
+
+Before submitting a pull request, it's important to consider the following points to help you choose the appropriate branch:
+
+- **Bug Fixes**: If you're fixing a bug, make sure to port the fix to the latest version that supports it (currently v1.5.1).
+- **Minor Feature Requests**: For minor features compatible with the current release, push your changes to the latest stable branch (currently v1.x).
+- **Major Feature Requests**: If your request involves a major new feature with potential breaking changes, send it to the master branch, which corresponds to the upcoming release (v2.x).
+
+## Compiled Assets
+
+When submitting a change that includes compiled files, please avoid committing the compiled files directly. Maintainers find it difficult to review compiled files, and they may contain malicious code. To prevent this issue, the Bagisto maintainers will generate and commit the compiled files themselves.
+
+## Security Vulnerabilities
+
+If you discover a security vulnerability within Bagisto, please notify us immediately by sending an email to Jitendra Singh at [jitendra@webkul.in](mailto:jitendra@webkul.in). We take security vulnerabilities seriously and will address them promptly.
+
+## Coding Style
+
+Bagisto follows the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standard and the [PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md) autoloading standard. These standards ensure consistency and readability in the codebase, similar to Laravel.
+
+## PHPDoc
+
+Below is an example of a valid Bagisto doc block that follows the coding style:
+
+```php
+/**
+ * Register a service with CoreServiceProvider.
+ *
+ * @param string|array $loader
+ * @param \Closure|string|null $concrete
+ * @param bool $shared
+ * @return void
+ *
+ * @throws \Exception
+ */
+protected function registerFacades($loader, $concrete = null, $shared = false)
+{
+ //
+}
+```
\ No newline at end of file
diff --git a/docs/1.5.x/prologue/upgrade-guide.md b/docs/1.5.x/prologue/upgrade-guide.md
new file mode 100644
index 00000000..93ea4d99
--- /dev/null
+++ b/docs/1.5.x/prologue/upgrade-guide.md
@@ -0,0 +1,83 @@
+# Upgrade Guide
+
+[[TOC]]
+
+## Upgrade Steps
+
+To upgrade your current version to the latest version of Bagisto, follow these steps:
+
+1. Download the latest version of Bagisto from one of the following links:
+ - [Download From Official Bagisto Site](https://bagisto.com/en/download/)
+ - [Download From GitHub](https://github.com/bagisto/bagisto)
+
+2. Extract the downloaded Bagisto zip file to the desired deployment location.
+
+3. Open the terminal and navigate to the root folder of the extracted Bagisto folder.
+
+4. Run the following command in the terminal:
+
+ ```sh
+ composer create-project
+ ```
+
+ This command will install the necessary dependencies for the latest version of Bagisto.
+
+5. Open the **`.env`** file in your project's root folder. Provide the database credentials of your old project, which you want to upgrade using Bagisto.
+
+6. Run one of the following commands to cache the new changes:
+
+ ```sh
+ php artisan optimize
+
+ # -- OR --
+
+ php artisan config:cache
+ ```
+
+ These commands will cache the configuration files and optimize the project.
+
+7. Now, your project is ready to run the migration command. Execute the following command in the terminal:
+
+ ```sh
+ php artisan migrate
+ ```
+
+ ::: danger
+ Be cautious when using the seeder command as it may reset settings and categories. Add default settings manually if necessary.
+ :::
+
+8. Create a symbolic link to link public assets to the storage folder by running the following command:
+
+ ```sh
+ php artisan storage:link
+ ```
+
+9. Copy the contents of the previous version's folder (e.g., **`old-project/storage/app/public`**) to the corresponding folder in the latest version (e.g., **`new-project/storage/app/public`**).
+
+ ::: tip
+ If your existing project depends on local storage, has changed paths, or requires previous logs, ensure to include those as well.
+ :::
+
+10. Once the copying is complete, publish the new files by running the following command:
+
+ ```sh
+ php artisan vendor:publish --all
+ ```
+
+ ::: warning
+ Avoid using the **`--force`** flag, as it will reset all your views. Only use it if you understand the consequences.
+ :::
+
+11. Congratulations! Your project is now upgraded to the latest version of Bagisto. However, keep in mind that if you have made significant customizations, ensure compatibility with the latest version.
+
+## New Changes
+
+The following changes have been implemented in Bagisto from version 1.4.5 to 1.5.1:
+
+- Implemented Elasticsearch for improved search functionality.
+- Added a count of selected products in Datagrid. ([GitHub](https://github.com/bagisto/bagisto/pull/7437))
+- Changed the appearance of checkboxes in dark mode. ([GitHub](https://github.com/bagisto/bagisto/pull/7304))
+- Modified routes in Packages. ([GitHub](https://github.com/bagisto/bagisto/pull/7345))
+- Removed Triggers feature. ([GitHub](https://github.com/bagisto/bagisto/pull/7334))
+- Consistent mail configuration as per Laravel standards. ([GitHub](https://github.com/bagisto/bagisto/pull/7509))
+- Removed REST API and JWT package related dependencies. ([GitHub](https://github.com/bagisto/bagisto/pull/7546))
\ No newline at end of file
diff --git a/docs/1.5.x/themes/README.md b/docs/1.5.x/themes/README.md
new file mode 100644
index 00000000..050378c7
--- /dev/null
+++ b/docs/1.5.x/themes/README.md
@@ -0,0 +1,27 @@
+# Themes
+
+If you are looking to customize the appearance and design of your Bagisto e-commerce store, creating a custom theme is the way to go. Bagisto offers a flexible and straightforward approach to theme development, allowing you to tailor the look and feel of your store to align with your brand and meet your specific requirements.
+
+## Package Development Prerequisite
+
+Before diving into theme development, it is recommended to have knowledge of creating packages in Laravel. If you are new to package development, you can refer to the [Package Development](../packages) section for a primer on creating and managing packages in Laravel. Understanding package development concepts will greatly assist you in creating and organizing your custom theme.
+
+## Creating a Custom Theme
+
+Creating a custom theme for Bagisto involves a few simple steps. Here's an overview of the process:
+
+1. **Create a Package**: As themes in Bagisto are treated as packages, the first step is to create a new package specifically for your theme. This package will serve as the container for your theme files and configuration.
+
+2. **Configure the Package**: Once the package is created, you need to configure it by defining the necessary details such as the package name, author, description, and other relevant information. This configuration ensures that Bagisto recognizes your package as a theme.
+
+3. **Define the Theme Assets**: In Bagisto, themes are primarily composed of assets such as CSS stylesheets, JavaScript files, and image files. You will need to create the appropriate directories within your theme package to store these assets.
+
+4. **Create Blade Views**: Blade views are the templates used to render the frontend of your store. You can create your own custom views within your theme package, allowing you to customize the appearance of different pages and components.
+
+5. **Configure Theme Layout**: Bagisto provides a layout system that defines the structure and organization of your store's pages. You can configure the layout for your theme by specifying the positions of various components, such as the header, footer, sidebar, and content sections.
+
+6. **Customize Theme Styles**: To achieve a unique and visually appealing design, you can customize the CSS stylesheets of your theme. This includes modifying colors, typography, spacing, and other visual elements to match your branding and aesthetic preferences.
+
+7. **Activate and Test the Theme**: Once your custom theme is ready, you can activate it in the Bagisto admin panel. This will make your theme the active theme for your store, reflecting the changes and customizations you have made. It is crucial to thoroughly test your theme to ensure its compatibility and responsiveness across different devices and browsers.
+
+By following these steps, you can create a fully customized theme for your Bagisto e-commerce store. This empowers you to create a unique and engaging shopping experience for your customers, aligning with your brand identity and enhancing your online presence.
\ No newline at end of file
diff --git a/docs/1.5.x/themes/create-admin-theme.md b/docs/1.5.x/themes/create-admin-theme.md
new file mode 100644
index 00000000..1ad7a16c
--- /dev/null
+++ b/docs/1.5.x/themes/create-admin-theme.md
@@ -0,0 +1,101 @@
+# Admin Theme
+
+[[TOC]]
+
+## Configuration
+
+To configure the admin theme in Bagisto, follow these steps:
+
+1. In the Bagisto root directory, navigate to the **config** folder and open the **`themes.php`** file. Look for the keys **`admin-default`** and **`admin-themes`**. The configuration will appear as follows:
+
+ ```php
+ 'default',
+
+ 'admin-themes' => [
+ 'default' => [
+ 'views_path' => 'resources/admin-themes/default/views',
+ 'assets_path' => 'public/admin-themes/default/assets',
+ 'name' => 'Default'
+ ]
+ ]
+ ];
+ ```
+
+ | Key | Description |
+ | -------------- | ---------------------------------------- |
+ | admin-default | Sets the current theme for the admin area |
+ | admin-themes | Stores a list of available themes |
+
+## Creating a Theme
+
+To create a new admin theme, follow these steps:
+
+1. Add a new theme entry to the **`admin-themes`** array in the **`themes.php`** file:
+
+ ```php
+ 'default',
+
+ 'admin-themes' => [
+ 'default' => [
+ 'views_path' => 'resources/admin-themes/default/views',
+ 'assets_path' => 'public/admin-themes/default/assets',
+ 'name' => 'Default'
+ ],
+
+ 'theme1' => [
+ 'views_path' => 'resources/admin-themes/theme1/views',
+ 'assets_path' => 'public/admin-themes/theme1/assets',
+ 'name' => 'Theme 1'
+ ]
+ ]
+ ];
+ ```
+
+2. In the new theme entry, specify the path to the views and assets folders according to your desired structure. For example:
+
+ - Views structure:
+
+ ```
+ - resources
+ └── admin-themes
+ └── theme1
+ └── views
+ ```
+
+ - Assets structure:
+
+ ```
+ - public
+ └── admin-themes
+ └── theme1
+ └── assets
+ ```
+
+3. To replace the dashboard page with a custom version, create the same directory structure for the dashboard in the **`theme1`** folder as it exists in the **`default`** folder. For example:
+
+ ```
+ - resources
+ └── admin-themes
+ └── theme1
+ └── views
+ └── dashboard
+ └── index.blade.php
+ ```
+
+4. In the newly created **`index.blade.php`** file, add the desired content for the dashboard page. For example:
+
+ ```php
+ Theme 1 Sample
+ ```
+
+5. Finally, activate the new theme by changing the value of the **`admin-default`** key in the **`config/themes.php`** file:
+
+ ```php
+ 'admin-default' => 'theme1',
+ ```
+
+Now, when you access the dashboard page in the admin area, you should see the customized version provided by the new theme (Theme 1).
\ No newline at end of file
diff --git a/docs/1.5.x/themes/create-theme.md b/docs/1.5.x/themes/create-theme.md
new file mode 100644
index 00000000..3c24c36e
--- /dev/null
+++ b/docs/1.5.x/themes/create-theme.md
@@ -0,0 +1,82 @@
+# Store Theme
+
+[[TOC]]
+
+## Configuration
+
+To configure the store theme in Bagisto, follow these steps:
+
+1. Go to your project's root directory and locate the **`config`** folder. Inside the **`config`** folder, you will find a file named **`themes.php`**.
+
+ ```
+ - app
+ - bin
+ - bootstrap
+ - config
+ ├── ...
+ └── themes.php
+ - database
+ - packages
+ └── Webkul
+ ```
+
+2. Open the **`themes.php`** file to examine its contents. This file contains all the necessary information for creating a custom theme in Bagisto.
+
+ ```php
+ 'default',
+
+ 'themes' => [
+ 'default' => [
+ 'views_path' => 'resources/themes/default/views',
+ 'assets_path' => 'public/themes/default/assets',
+ 'name' => 'Default'
+ ],
+
+ 'velocity' => [
+ 'views_path' => 'resources/themes/velocity/views',
+ 'assets_path' => 'public/themes/velocity/assets',
+ 'name' => 'Velocity',
+ 'parent' => 'default'
+ ],
+ ],
+ ];
+ ```
+
+3. Let's go through the parameters defined in the **`themes.php`** file as understanding them will help you in creating a custom theme.
+
+### Explanation of Parameters:
+
+- **default**: This parameter at the top of the file indicates the currently active or default theme in Bagisto. It is set to **`'default'`**, representing the name of the currently active theme.
+
+- **themes**: This parameter allows you to define the configurations for your custom themes. You can create and use multiple themes simultaneously in Bagisto.
+
+ - Inside the **`'themes'`** array, there is another array named **`'default'`**, which represents your currently active theme. It contains several key-value pairs that are explained below:
+
+ - **views_path**: This parameter specifies the path to the views or blade files for your custom theme.
+
+ - **assets_path**: It determines the path to the assets such as images, CSS files, and JavaScript files for your theme.
+
+ - **name**: This parameter defines a global name for your theme inside Bagisto.
+
+ - **parent**: This is an optional parameter that allows you to customize existing themes in Bagisto. By setting the **`'parent'`** parameter to the value of the **`'name'`** parameter listed above, you can inherit the configuration of the parent theme and make further customizations.
+
+4. Once you have defined the paths and names for your custom theme in the **`themes.php`** file, you can start creating your view files. Make sure to cover all the GET routes of the shop package that include a parameter called **`'view'`**. You can find the route file of the shop package located at **`packages/Webkul/Shop/src/Http/routes.php`**.
+
+5. Ensure that the name of your blade file matches the value passed in the GET route file. For example:
+
+ ```php
+ // Store front header nav-menu fetch
+ Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')
+ ->defaults('_config', [
+ 'view' => 'shop::products.index'
+ ])->name('shop.categories.index');
+ ```
+
+ In this example, the view file should be named **`index.blade.php`** and placed in the appropriate directory within your custom theme.
+
+6. For all the views, check all the GET routes as they include a **`'view'`** parameter with the corresponding value to be used.
+
+By following these steps, you can configure and create custom view files for your store theme in Bagisto. This allows you to personalize the appearance and layout of your storefront to align with your branding and provide an enhanced user experience.
\ No newline at end of file
diff --git a/docs/1.5.x/themes/integrate-image-search-in-theme.md b/docs/1.5.x/themes/integrate-image-search-in-theme.md
new file mode 100644
index 00000000..b753e6b0
--- /dev/null
+++ b/docs/1.5.x/themes/integrate-image-search-in-theme.md
@@ -0,0 +1,72 @@
+# Image Search
+
+[[TOC]]
+
+## Introduction
+
+In this section, we will guide you on integrating image search with your new theme. Our **`Default Theme`** and **`Velocity Theme`** utilize [TensorFlow.js](https://www.tensorflow.org/js) and load the **`TensorFlow`** MobileNet model.
+
+The **`TensorFlow`** JS model doesn't require any machine learning expertise. You simply need to pass browser-based image elements, such as **``**, and it will return an array containing the best predictions along with their confidences.
+
+## Usage
+
+Ensure that all your scripts are loaded in the footer. If you examine the **`default theme`** and **`velocity theme`**, you will notice that we use the `yielding` feature. You can also use the same approach by including a `scripts` yield in your main layouts.
+
+Let's begin by loading the library and model:
+
+```php
+@push('scripts')
+
+
+@endpush
+```
+
+Since the **`TensorFlow`** model only requires an image element, we will use a sample image element:
+
+```php
+@push('scripts')
+
+
+
+
+@endpush
+```
+
+::: tip
+This is a sample image element. You can add a file input to allow users to select an image.
+:::
+
+Now, for the main part, pass your image element to the model:
+
+```php
+@push('scripts')
+
+
+
+
+
+
+@endpush
+```
+
+Now you have all the predictions. Simply pass your predictions to your search input.
+
+::: tip
+Create a query string from the predictions and redirect to the search route.
+:::
+
+## Conclusion
+
+By following the entire flow, you can see that we pass an image element to the **`TensorFlow`** model. In return, we receive an array of predictions. From these predictions, we can generate query strings and redirect to the search route.
\ No newline at end of file
diff --git a/docs/1.5.x/themes/notification.md b/docs/1.5.x/themes/notification.md
new file mode 100644
index 00000000..72bb22d7
--- /dev/null
+++ b/docs/1.5.x/themes/notification.md
@@ -0,0 +1,21 @@
+# Real-Time Notification
+
+To enable real-time notifications in the updated admin theme, you need to configure your project by following these steps:
+
+1. Create an account on [Pusher](https://dashboard.pusher.com/accounts/sign_up?_ga=2.266851022.1754006062.1647430118-1332525715.1647430118&_gl=1*jiq2no*_ga*MTMzMjUyNTcxNS4xNjQ3NDMwMTE4*_ga_V7TRZJDKDQ*MTY0NzQzMDExOC4xLjAuMTY0NzQzMDE0MC4w).
+
+2. Once you have created an account, create a Channels app for your application. In the app settings, go to the **`"App Keys"`** menu and copy the app ID, key, secret, and cluster.
+
+3. Open your application's **`.env`** file and replace the respective values with the credentials generated by Pusher.
+
+4. After updating the **`.env`** file, run the following command in your terminal to start the queue listener:
+
+ ```
+ php artisan queue:listen --queue=broadcastable
+ ```
+
+ This command ensures that the queue broadcasts are processed, making your application more responsive and providing a real-time experience.
+
+ Note: Make sure you have set up the required configurations for queues and broadcasting in your Laravel application.
+
+By implementing real-time notifications, whenever an order is created or updated, you will receive immediate updates in the admin notification menu without having to wait for the process to complete or refresh the page. This enhances the responsiveness and user experience of your application.
\ No newline at end of file
diff --git a/docs/1.x/admin-theme/README.md b/docs/1.x/admin-theme/README.md
new file mode 100644
index 00000000..a8f53ba2
--- /dev/null
+++ b/docs/1.x/admin-theme/README.md
@@ -0,0 +1,7 @@
+# Themes
+
+We hope that now you know how to create a package, if not then you may refer to [Package Development](../packages) section.
+
+Creating a custom admin theme for Bagisto had been a hot topic lately. More and more users are actively trying our framework and we’re genuinely overwhelmed by it.
+
+Creating a custom admin theme for Bagisto is super easy with just a few lines of configuration code. Similarly following the traditional way of creating view files in Laravel would be enough.
diff --git a/docs/1.x/admin-theme/notification.md b/docs/1.x/admin-theme/notification.md
new file mode 100644
index 00000000..03656ba8
--- /dev/null
+++ b/docs/1.x/admin-theme/notification.md
@@ -0,0 +1,9 @@
+### Real time notification
+
+In the updated admin theme, we have introduced an option of getting real time notifications upon order creation and updation. For the real time notification, you need to have some of the configuration within your project as mentioned below:
+
+- [Create an account](https://dashboard.pusher.com/accounts/sign_up?_ga=2.266851022.1754006062.1647430118-1332525715.1647430118&_gl=1*jiq2no*_ga*MTMzMjUyNTcxNS4xNjQ3NDMwMTE4*_ga_V7TRZJDKDQ*MTY0NzQzMDExOC4xLjAuMTY0NzQzMDE0MC4w), then create a Channels app for your application. Go to the “App Keys” menu for that app, and copy the app_id, key, secret and cluster.
+- Upon successfull generation of pusher credentials, go to your application .env file and replace the respective values with generated credentials.
+- After that run queue listener command i.e. php artisan queue:listen --queue=broadcastable
+
+Queue broadcasts actually make your application more responsive and allows a realtime experience. When you have any action for order creation or updation, then you can immediately get respond to the admin notification menu instead of having to wait on the process to complete or page to refresh.
diff --git a/docs/1.x/advanced/README.md b/docs/1.x/advanced/README.md
new file mode 100644
index 00000000..5efcfa7b
--- /dev/null
+++ b/docs/1.x/advanced/README.md
@@ -0,0 +1,3 @@
+# Advanced Topics
+
+In this section, we will discuss the advanced topics of Bagisto like creating payment methods, shipping methods, data grids, and many more. Before diving into this, we are assuming that you are familiar with Laravel.
diff --git a/docs/1.x/advanced/create-payment-method.md b/docs/1.x/advanced/create-payment-method.md
new file mode 100644
index 00000000..c488d8d9
--- /dev/null
+++ b/docs/1.x/advanced/create-payment-method.md
@@ -0,0 +1,269 @@
+# Create a new payment method
+
+We hope that now you know how to create a package, if not refer to [Package Development](../packages).
+
+Bagisto eases the task of creating payment methods. So, a novice developer or a professional developer can easily create payment methods.
+
+As the diversity of payment methods provide the options to customer for payment when they proceed to checkout.
+
+On another perspective, multiple payment methods are a great strategy to reach out to the global marketplace.
+
+In this section, we will explain how to create a payment method. You can create a payment method in two ways.
+
+1. By using Bagisto Package Generator (**Recommended**)
+2. By manually setting up all files (**Expert Level**)
+
+## 1. By using Bagisto Package Generator
+
+- For creating payment method package, you need to use these commands in bagisto root directory,
+
+ - If package directory not present,
+
+ ```php
+ php artisan package:make-payment-method ACME/Stripe
+ ```
+
+ - If somehow package directory already present then you can use force command as well. For that you just need to pass the '**--force**' command.
+
+ ```php
+ php artisan package:make-payment-method ACME/Stripe --force
+ ```
+
+ - This will generate whole directory structures. You don't need to do manually.
+
+- After that, you need to register your service provider in `config/app.php` which is located Bagisto root directory.
+
+ ```php
+ [
+ ...
+ ACME\Stripe\Providers\StripeServiceProvider::class,
+ ...
+ ]
+ ...
+ ];
+ ```
+
+- After that, add you payment method namespace in `psr-4` key in `composer.json` file for auto loading which is located Bagisto root directory.
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ ...
+ "ACME\\Stripe\\": "packages/ACME/Stripe/src"
+ ...
+ }
+ ...
+ }
+ ```
+
+- Run `composer dump-autoload`.
+
+- After that run `php artisan config:cache`.
+
+- This will setup the configuration in the admin panel. Now start creating routes, controllers and make some cool stuff.
+
+## 2. By manually setting up all files
+
+### Steps to create a payment method
+
+- Create respective directory structure to create your payment method.
+
+ ```file-structure
+ - ACME/Stripe/src/
+ - Config/
+ - system.php
+ - paymentmethods.php
+ - Payment/
+ - Stripe.php
+ - Providers/
+ - StripeServiceProvider.php
+ ```
+
+- Within `Config` folder, it contains application's configuration files. Let's just create two files i.e. `system.php` and `paymentmethods.php`. In `system.php` file, you have to include the array keys in the file as shown below,
+
+ ```php
+ 'sales.paymentmethods.stripe',
+ 'name' => 'Stripe',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'title',
+ 'title' => 'admin::app.admin.system.title',
+ 'type' => 'text',
+ 'validation' => 'required',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ], [
+ 'name' => 'description',
+ 'title' => 'admin::app.admin.system.description',
+ 'type' => 'textarea',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ], [
+ 'name' => 'active',
+ 'title' => 'admin::app.admin.system.status',
+ 'type' => 'boolean',
+ 'validation' => 'required',
+ 'channel_based' => false,
+ 'locale_based' => true,
+ ]
+ ]
+ ]
+ ];
+ ```
+
+ - Let's discuss what these keys are,
+
+ - `key`: Value which is provided in this key should be unique and concatenated with '.' (dot) operator.
+
+ - `name`: This key accept the value as a placeholder for your configuration. Generally, in Bagisto, we consider writing it using translation.
+
+ - `sort`: This key accept the sort position for your configuration menu.
+
+ - `fields`: This key accept the list of arrays representing your custom configurations and fields. Right now you are seeing that it only holding 3 array i.e. title, description and status. If you need some other settings than you can add one more array to this.
+
+- Similarly in `paymentmethods.php`,
+
+ ```php
+ [
+ 'code' => 'stripe',
+ 'title' => 'Stripe',
+ 'description' => 'Stripe',
+ 'class' => 'ACME\Stripe\Payment\Stripe',
+ 'active' => true,
+ 'sort' => 1,
+ ],
+ ];
+ ```
+
+ - Now, let's look into this what these keys are,
+ - `code`: A text to represent payment method.
+ - `title`: Name of the payment method.
+ - `description`: A brief description of the payment method.
+ - `class`: This key includes the class namespace where all functions of payment method are written.
+ - `active`: This key accepts true/false to enable or disable the module.
+ - `sort`: This key accept the sort position of the payment.
+
+- If you check the above point, we have discussed the key `class` which includes the class namespace. So let's create that class in the respective file. In `Stripe.php`, add the below code,
+
+ ```php
+ registerConfig();
+ }
+
+ /**
+ * Register package config.
+ *
+ * @return void
+ */
+ protected function registerConfig()
+ {
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/paymentmethods.php', 'paymentmethods'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ```
+
+- After that, you need to register your service provider in `config/app.php` which is located Bagisto root directory.
+
+ ```php
+ [
+ ...
+ ACME\Stripe\Providers\StripeServiceProvider::class,
+ ...
+ ]
+ ...
+ ];
+ ```
+
+- After that, add payment method namespace in `psr-4` key in `composer.json` file for auto loading which is located Bagisto root directory.
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ ...
+ "ACME\\Stripe\\": "packages/ACME/Stripe/src"
+ ...
+ }
+ ...
+ }
+ ```
+
+- Run `composer dump-autoload`.
+
+- After that run `php artisan config:cache`.
+
+::: tip
+
+If `composer dump-autoload` giving some error than in that case delete all files from the `bootstrap/cache` and again run `composer dump-autoload`.
+
+:::
diff --git a/docs/1.x/advanced/create-product-type.md b/docs/1.x/advanced/create-product-type.md
new file mode 100644
index 00000000..85a521bd
--- /dev/null
+++ b/docs/1.x/advanced/create-product-type.md
@@ -0,0 +1,77 @@
+# Create your own product type
+
+By default Bagisto provides the following product types: simple, configurable, virtual, grouped, downloadable, bundled and bookings.
+If the default product types do not meet your requirements, you can create your own product type.
+
+## Steps to create your own product-types
+
+You may access this super-functionality of creating your own product-types by following the points listed below.
+
+**Note**: To demonstrate the process here, we will be creating a new product-type say "`coupon`"
+
+1. Create your own package, you can check out the [Package Development](../packages) section if you need help with this.
+2. Within the Config folder of your package, create a file `product_types.php`
+3. Write the below piece of code in it, which is will be used to add product-type in your project.
+
+ ```php
+ [
+ 'key' => 'coupon',
+ 'name' => 'Coupon',
+ 'class' => 'ACME\Coupon\Type\Coupon',
+ 'sort' => 7
+ ],
+ ];
+ ```
+4. After that, we need to merge this `Config/product_types.php` with a core product_types option. For this, we use the method mergeConfigFrom() in the register method of the service provider(`ACME\Coupon\Providers\CouponServiceProvider.php`).
+
+
+ ```php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/product_types.php', 'product_types'
+ );
+ }
+ }
+
+ ```
+
+5. In 3rd point above, that have mentioned key `class` which loads coupon product type. So, you need to create a file `Coupon.php` within your package under Type folder and add the below code.
+
+```php
+
+
+```
+
+6. After successfully completion of above steps, your product type will get created. But, still we don't have any code written for coupon type product in the `Type/Coupon.php`. To inherit basic functionality of any product to your product type, we need to inherit the classes from the Product package `type/AbstractType.php` file.
+
+7. Extending `AbstractType.php` class within your product_type (`Type\Coupon.php`) class let you to provide some core functionality of product. But, in addition, if user need to defined it's own custom methods, then he can define within their `Coupon.php` file.
diff --git a/docs/1.x/advanced/create-shipping-method.md b/docs/1.x/advanced/create-shipping-method.md
new file mode 100644
index 00000000..4dcf7f90
--- /dev/null
+++ b/docs/1.x/advanced/create-shipping-method.md
@@ -0,0 +1,257 @@
+# Create a new shipping method
+
+We hope that now you know how to create a package, if not refer to [Package Development](../packages).
+
+In this section, we will understand how to create a shipping method.
+
+You can create a shipping method in two ways.
+
+1. By using Bagisto Package Generator (**Recommended**)
+2. By manually setting up all files (**Expert Level**)
+
+## 1. By using Bagisto Package Generator
+
+For creating shipping method package, you need to use this command in bagisto root directory,
+
+~~~php
+php artisan package:make-shipping-method ACME/FedEx
+~~~
+
+If somehow package directory already present then you can use force command as well. For that you just need to pass the '**--force**' command.
+
+~~~php
+php artisan package:make-shipping-method ACME/FedEx --force
+~~~
+
+This will generate whole directory structures. You don't need to do manually.
+
+## 2. By manually setting up all files
+
+- User needs to create a `carriers.php` file in the `src/Config` path in the package (say FedEx). Here, we are going to specify what to include in your `carriers.php` file.
+
+ ::: details Directory structure
+
+ ~~~
+ - ACME/FedEx/
+ - FedEx/
+ - src/
+ - Config/
+ - carriers.php
+ ~~~
+
+ :::
+
+ ~~~php
+ [
+ 'code' => 'fedex',
+ 'title' => 'FedEx',
+ 'description' => 'FedEx Shipping',
+ 'active' => true,
+ 'type' => 'per_unit',
+ 'class' => 'ACME\FedEx\Carriers\FedEx',
+ ]
+ ];
+ ~~~
+
+ - Explanation
+ - **code**: Unique value used for referring the particular menu.
+ - **title**: Label or name to display at the user interface.
+ - **description**: About your shipping method.
+ - **active**: Enable or disable option for shipping method.
+ - **type**: This field specifies that the shipping method applies as `per_unit` or
+ `per_order`.
+ - **class**: Path specified with filename `namespace\package-name\Carriers-folder\filename`
+
+- Create `Carriers` folder inside the `src` folder. Now, create `Fedex.php` in `Carriers` folder and add the below code to `Fedex.php` file.
+
+~~~php
+ isAvailable()) {
+ return false;
+ }
+
+ $object = new CartShippingRate;
+
+ $object->carrier = 'fedex';
+ $object->carrier_title = $this->getConfigData('title');
+ $object->method = 'fedex_fedex';
+ $object->method_title = $this->getConfigData('title');
+ $object->method_description = $this->getConfigData('description');
+ $object->price = 0;
+ $object->base_price = 0;
+
+ return $object;
+ }
+ }
+ ~~~
+
+ - File `Fedex.php` will extends `AbstractShipping` class which is defined at `Webkul\Shipping\Carriers\AbstractShipping`. In `Fedex.php`, methods are defined that you can use while creating a shipping method.
+
+ - Now, you can write all the operations needed for your shipping method in `Fedex.php` file.
+
+ - To render the shipping methods in checkout process, you need to define `calculate()` within your `Fedex.php` and return shipping rate, shipping title, shipping description within an object.
+
+ ::: tip
+ May refer [FlatRate](https://github.com/bagisto/bagisto/blob/master/packages/Webkul/Shipping/src/Carriers/FlatRate.php#L28) `calculate()` method.
+ :::
+
+- After creating all the necessary files and configurations, you need to create the form which will appear on the config section. So for that create file `system.php` in `src/Config`. Add below code to following file,
+
+ ~~~php
+ 'sales.carriers.Fedex',
+ 'name' => 'admin::app.admin.system.fedex-shipping',
+ 'sort' => 2,
+ 'fields' => [
+ [
+ 'name' => 'title',
+ 'title' => 'admin::app.admin.system.title',
+ 'type' => 'text',
+ 'validation' => 'required',
+ 'channel_based' => true,
+ 'locale_based' => true
+ ], [
+ 'name' => 'description',
+ 'title' => 'admin::app.admin.system.description',
+ 'type' => 'textarea',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'default_rate',
+ 'title' => 'admin::app.admin.system.rate',
+ 'type' => 'text',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'base_amount',
+ 'title' => 'admin::app.admin.system.minimum-amount',
+ 'type' => 'text',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ], [
+ 'name' => 'active',
+ 'title' => 'admin::app.admin.system.status',
+ 'type' => 'select',
+ 'options' => [
+ [
+ 'title' => 'Active',
+ 'value' => true
+ ], [
+ 'title' => 'Inactive',
+ 'value' => false
+ ]
+ ],
+ 'validation' => 'required',
+ 'channel_based' => false,
+ 'locale_based' => true
+ ]
+ ]
+ ]
+ ~~~
+
+- Now merge all your config in `packages/ACME/FedEx/src/Providers/FedExServiceProvider.php`,
+
+ ~~~php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/carriers.php', 'carriers'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ~~~
+
+- After that, you need to register your service provider in `config/app.php` which is located in Bagisto root directory.
+
+ ~~~php
+ [
+ ...
+ ACME\FedEx\Providers\FedExServiceProvider::class,
+ ...
+ ]
+ ...
+ ];
+ ~~~
+
+- After that, add you shipment method namespace in `psr-4` key in `composer.json` file for auto loading which is located in Bagisto root directory.
+
+ ~~~json
+ "autoload": {
+ ...
+ "psr-4": {
+ ...
+ "ACME\\FedEx\\": "packages/ACME/FedEx/src"
+ ...
+ }
+ ...
+ }
+ ~~~
+
+- Run `composer dump-autoload`.
+
+- After that run `php artisan config:cache`.
+
+::: tip
+
+If `composer dump-autoload` giving some error than in that case delete all files from the `bootstrap/cache` and again run `composer dump-autoload`.
+
+:::
diff --git a/docs/1.x/advanced/datagrid.md b/docs/1.x/advanced/datagrid.md
new file mode 100644
index 00000000..56ff73e2
--- /dev/null
+++ b/docs/1.x/advanced/datagrid.md
@@ -0,0 +1,434 @@
+# DataGrid
+
+DataGrid is just a concept of displaying your database records in tabular format. We have implemented this in Bagisto either you can use it to display data in tabular format or write code from scratch to display data in tabular format. In addition to DataGrid, we have implemented additional features such as sorting, filtering, mass action. You may refer to the table below for detailed information about the features.
+
+Let us take a sample of one DataGrid,
+
+~~~php
+select('id')
+ ->addSelect('id', 'code', 'admin_name', 'type', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel');
+
+ $this->setQueryBuilder($queryBuilder);
+ }
+
+ /**
+ * Add columns.
+ */
+ public function addColumns()
+ {
+ $this->addColumn([
+ 'index' => 'id',
+ 'label' => trans('admin::app.datagrid.id'),
+ 'type' => 'number',
+ 'searchable' => false,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'code',
+ 'label' => trans('admin::app.datagrid.code'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'admin_name',
+ 'label' => trans('admin::app.datagrid.admin-name'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'type',
+ 'label' => trans('admin::app.datagrid.type'),
+ 'type' => 'string',
+ 'sortable' => true,
+ 'searchable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'is_required',
+ 'label' => trans('admin::app.datagrid.required'),
+ 'type' => 'boolean',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'wrapper' => function ($value) {
+ if ($value->is_required == 1)
+ return 'True';
+ else
+ return 'False';
+ }
+ ]);
+
+ $this->addColumn([
+ 'index' => 'is_unique',
+ 'label' => trans('admin::app.datagrid.unique'),
+ 'type' => 'boolean',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true,
+ 'wrapper' => function ($value) {
+ if ($value->is_unique == 1)
+ return 'True';
+ else
+ return 'False';
+ }
+ ]);
+
+ $this->addColumn([
+ 'index' => 'value_per_locale',
+ 'label' => trans('admin::app.datagrid.per-locale'),
+ 'type' => 'boolean',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true,
+ 'wrapper' => function ($value) {
+ if ($value->value_per_locale == 1)
+ return 'True';
+ else
+ return 'False';
+ }
+ ]);
+
+ $this->addColumn([
+ 'index' => 'value_per_channel',
+ 'label' => trans('admin::app.datagrid.per-channel'),
+ 'type' => 'boolean',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true,
+ 'wrapper' => function ($value) {
+ if ($value->value_per_channel == 1)
+ return 'True';
+ else
+ return 'False';
+ }
+ ]);
+ }
+
+ /**
+ * Prepare actions.
+ */
+ public function prepareActions()
+ {
+ $this->addAction([
+ 'title' => trans('admin::app.datagrid.edit'),
+ 'method' => 'GET',
+ 'route' => 'admin.catalog.attributes.edit',
+ 'icon' => 'icon pencil-lg-icon'
+ ]);
+
+ $this->addAction([
+ 'title' => trans('admin::app.datagrid.delete'),
+ 'method' => 'POST',
+ 'route' => 'admin.catalog.attributes.delete',
+ 'icon' => 'icon trash-icon'
+ ]);
+ }
+
+ /**
+ * Prepare mass actions.
+ */
+ public function prepareMassActions()
+ {
+ $this->addMassAction([
+ 'type' => 'delete',
+ 'action' => route('admin.catalog.attributes.massdelete'),
+ 'label' => 'Delete',
+ 'method' => 'DELETE'
+ ]);
+ }
+}
+~~~
+
+## Global properties of DataGrid
+
+As you see the above sample Datagrid, now let us discuss some properties,
+
+| Name | Functionality |
+| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| index | This property is defined in the grid, and the value assigned to this property must be unique i.e. `id`, so that data will be uniquely identified and operations performed will be based on your index value. |
+| sortOrder | The `sortOrder` key is used to arrange the results in ascending or descending order, we have to set the sort order variable to `asc` or `desc`. |
+| queryBuilder | It is used to perform database operations in your application. |
+| enableMassAction | This accepts boolean values `true` or `false` to enable or disable the mass action in Datagrid. |
+| enableAction | This accepts boolean values `true` or `false` to enable or disable the action column of Datagrid. |
+| paginate | While creating your grid file you have to declare paginate property and set it to `true` to allow pagination on your page. |
+| itemsPerPage | The `itemsPerPage` key is used to display the number of items per page. |
+| enableFilterMap | This accepts boolean values `true` or `false` to enable or disable the filter on the basis of columns. |
+
+## Steps to create DataGrid
+
+You can create a DataGrid in two ways.
+
+1. By using Bagisto Package Generator (**Recommended**)
+2. By manually setting up all files (**Expert Level**)
+
+### 1. By using Bagisto Package Generator
+
+This command will create a new data grid class in `packages/ACME/TestPackage/src/Datagrids` directory.,
+
+~~~php
+php artisan package:make-datagrid TestDataGrid ACME/TestPackage
+~~~
+
+If data grid class already present then you can use force command for overwriting.
+
+~~~php
+php artisan package:make-datagrid TestDataGrid ACME/TestPackage --force
+~~~
+
+This will generate whole directory structures. You don't need to do manually.
+
+### 2. By manually setting up all files
+1. We assume that you have created package let's say `ACME\TestPackage` with the below directory structure.
+~~~directory-structure
+- ACME/TestPackage/
+ - publishable/assets
+ - css/
+ - images/
+ - js/
+ - src/
+ - Config/
+ - acl.php
+ - admin-menu.php
+ - Console/
+ - Commands/
+ - Contracts/
+ - Database/
+ - Migrations/
+ - Seeders/
+ - Events/
+ - Http/
+ - Controllers/
+ - Admin/
+ - TestPackageController.php
+ - Shop/
+ - TestPackageController.php
+ - Middleware/
+ - Requests/
+ - admin-routes.php
+ - shop-routes.php
+ - Listeners/
+ - Mail/
+ - Models/
+ - Providers/
+ - TestPackageServiceProvider.php
+ - TestPackageProvider.php
+ - Repositories/
+ - Resources/
+ - assets/
+ - images/
+ - js/
+ - app.js
+ - sass/
+ - admin.scss
+ - default.scss
+ - velocity.scss
+ - lang/
+ - views/
+ - admin/
+ - layouts/
+ - style.blade.php
+ - index.blade.php
+ - shop/
+ - default/
+ - index.blade.php
+ - velocity/
+ - index.blade.php
+ - package.json
+ - webpack.mix.js
+~~~
+2. Create a folder **Datagrids** in your package inside `src` folder, inside **Datagrids** folder, create a class let's say `TestDataGrid.php` that extends DataGrid class from Webkul `Ui` package.
+
+3. We have created `DataGrid` abstract class in Webkul `Ui` package. In the DataGrid abstract class, a list of properties and methods are declared. So, while creating your own DataGrid you need to only extends the `Webkul\Ui\DataGrid\DataGrid` abstract class inside your `TestDataGrid.php` class.
+
+4. In `Webkul\Ui\DataGrid\DataGrid.php` abstract class, two abstract methods are declared `prepareQueryBuilder()` and `addColumns()`. We can prepare grid by defining these two methods
+
+ - `prepareQueryBuilder()`: In this method, records are retrieved through queries that is applicable on database and stored in a collection. When records are retrieved, `$this->setQueryBuilder($queryBuilder)` setQueryBuilder method is called.
+
+ - `setQueryBuilder()`: This method is written in DataGrid abstract class of Webkul `Ui` package. This is used for setting the `$queryBuilder`.
+
+ ~~~php
+ public function prepareQueryBuilder()
+ {
+ $queryBuilder = DB::table('attributes')
+ ->select('id')
+ ->addSelect('id', 'code', 'admin_name', 'type', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel');
+
+ $this->setQueryBuilder($queryBuilder);
+ }
+ ~~~
+
+ - `addColumns()`: In this method, the columns are created which are displayed in the grid. In this method, the parameter accepts the array in key-value pairs. Some of the essential keys are described below,
+
+ | Name | functionality |
+ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+ | index | This key is defined in the grid, and the value assigned to this key must be unique, so that data will be uniquely identified and operations performed will be based on your index value. |
+ | label | In this key, the name of the column is defined. |
+ | type | This key accepts the type of data in column. |
+ | searchable | This accepts boolean values `true` or `false` to make the column searchable. |
+ | sortable | This accepts boolean values `true` or `false` to make the column sortable. |
+ | filterable | This accepts boolean values `true` or `false` to make the column filterable. |
+ | wrapper | Perform actions based on condition satisfied or some customization to value. |
+
+ ~~~php
+ public function addColumns()
+ {
+ $this->addColumn([
+ 'index' => 'id',
+ 'label' => trans('admin::app.datagrid.id'),
+ 'type' => 'number',
+ 'searchable' => false,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'code',
+ 'label' => trans('admin::app.datagrid.code'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+ }
+ ~~~
+
+ - `prepareActions()`: Additionally, this method is defined when there is a need to perform any action such as edit or delete on the grid. In this method, `addAction()` is called to define particular action.
+
+ - `addAction()`: It is used for adding actions (like `edit`, `delete`, etc) to each row generated by Datagrid.
+
+ | Name | Functionality |
+ | ------------ | ------------------------------------------------------------------------ |
+ | title | The text to be displayed in written here. |
+ | method | HTTP methods are declared. |
+ | route | This key accepts the route of icon. |
+ | icon | Class of icon to be displayed in action column you may prefer text also. |
+
+ ~~~php
+ public function prepareActions()
+ {
+ $this->addAction([
+ 'title' => trans('admin::app.datagrid.edit'),
+ 'method' => 'GET',
+ 'route' => 'admin.catalog.attributes.edit',
+ 'icon' => 'icon pencil-lg-icon'
+ ]);
+
+ $this->addAction([
+ 'title' => trans('admin::app.datagrid.delete'),
+ 'method' => 'POST',
+ 'route' => 'admin.catalog.attributes.delete',
+ 'icon' => 'icon trash-icon'
+ ]);
+ }
+ ~~~
+
+::: warning
+
+- Use JavaScript with wrapper property set to true when needed.
+- Return static blade files loaded with scripts in it with caution.
+
+:::
+
+## Multiple DataGrids
+
+As the default Datagrid will handle only a single request at a time which means filtration, sorting and many other operations will get conflicted when you try to implement the multiple DataGrids. To overcome this we have provided a trait `ProvideDataGridPlus` in the namespace `Webkul\Ui\DataGrid\Traits`.
+
+- Just take any of the Datagrid, let say `ProductDataGrid` in the namespace `Webkul\Admin\DataGrids`,
+
+ ~~~php
+ namespace Webkul\Admin\DataGrids;
+
+ class ProductDataGrid extends DataGrid
+ {
+ ...
+ }
+ ~~~
+
+- Import the `ProvideDataGridPlus` trait in the mentioned class,
+
+ ~~~php
+ namespace Webkul\Admin\DataGrids;
+
+ use Webkul\Ui\DataGrid\Traits\ProvideDataGridPlus;
+
+ class ProductDataGrid extends DataGrid
+ {
+ use ProvideDataGridPlus;
+
+ ...
+ }
+ ~~~
+
+- After that `toJson()` method will be available in the Datagrid instance which will provide data to the component.
+
+- Now you need to create one route and method from where the response will come. Let us take an example of the product listing page. Now go to `ProductController` in the namespace `Webkul\Product\Http\Controllers`, there is an index method, just use the `toJson`.
+
+ ~~~php
+ use Webkul\Admin\DataGrids\ProductDataGrid;
+
+ class ProductController extends Controller
+ {
+ /**
+ * Display a listing of the resource.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function index()
+ {
+ if (request()->ajax()) {
+ return app(ProductDataGrid::class)->toJson();
+ }
+
+ return view($this->_config['view']);
+ }
+
+ ...
+ }
+ ~~~
+
+- Now, in the view portion use this component i.e. `datagrid-plus` and add the url from where it will load the json data,
+
+ ~~~php
+
+ ...
+
+
+
+ ...
+
+ ~~~
+
+- Done, your datagrid is ready.
diff --git a/docs/1.x/advanced/events.md b/docs/1.x/advanced/events.md
new file mode 100644
index 00000000..6db88d38
--- /dev/null
+++ b/docs/1.x/advanced/events.md
@@ -0,0 +1,245 @@
+# Events
+Events are an implementation of observer pattern such that whenever an event takes place, then one or more listener(s) associated with that event responds. Imagine something like making an announcement to your application, and then actions being taken due to that announcement. All the event classes in Bagisto are stored in the **Providers** folder and the listeners are stored in the **Listeners** folder.
+
+## How to create Event Class?
+
+If you have the Bagisto Package Generator installed, then you can use the following command which will create a new event class in `packages/ACME/TestPackage/src/Events` directory.
+
+Please follow the following steps to create a new event class in your `packages/ACME/TestPackage`
+
+1. We assume that you have created a new TestPackage using Bagisto Package Generator like the below command.
+
+`php artisan package:make ACME/TestPackage`
+
+2. Now, you can create a event `Events\TestEvent.php` class using the below command.
+
+`php artisan package:make-event TestEvent ACME/TestPackage`
+
+If event class already present then you can use force command for overwriting by passing `--force` option.
+
+`php artisan package:make-event TestEvent ACME/TestPackage --force`
+
+Or if you don't have package generator then, you can create file manually also.
+
+## How to create Listener Class?
+
+If you have the Bagisto Package Generator installed, then you can use the following command which will create a new listener class in `packages/ACME/TestPackage/src/Listeners` directory.
+
+`php artisan package:make-listener TestListener ACME/TestPackage`
+
+If listener class already present then you can use force command for overwriting.
+
+`php artisan package:make-listener TestListener ACME/TestPackage --force`
+
+Or if you don't have package generator then, you can create file manually also.
+
+## Manually Registering Events
+
+For the sake of simplicity, in bagisto, we register events manually in the boot method of your **_EventServiceProvider.php_** as below:
+
+~~~php
+/**
+* Register any other events for your application.
+*
+* @return void
+*/
+
+public function boot()
+{
+ parent::boot();
+
+ Event::listen('event.name', 'path-upto-listener@function');
+}
+~~~
+
+## Manually Registering Listeners
+
+In registering events, we specify listener function to be executed when an event is called so on every event a listener function is to be executed
+
+~~~php
+class EventServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstrap services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Event::listen('checkout.order.save.after', 'Webkul\Admin\Listeners\Order@sendNewOrderMail');
+ }
+}
+~~~
+
+### How we specify events?
+
+In most of **CRUD** operation, we had fired an event before and after the execution of function. So, that if some one want to perform any operation after or before product create/update/delete can perform by simply calling a listener function in event registration
+
+## Events Fired in Bagisto
+
+Events fired in bagisto but not listened such that if any user wants to perform any action on event fire, then they may create listener file and perform the respective operation.
+
+| Events name | Functionality|
+| ------------------------------- | ------------- |
+|core.configuration.save.after|This event will be fired after core configuration form data gets saved, then you may create a listener file and perform the respective operation when that event fires |
+|core.configuration.save.after|This event will be fired after core configuration form data gets saved, then you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.add.before |This event will be fired before saving into the database of item added in checkout and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.add.after|This event will be fired after saving into the database of item added in checkout and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.update.before|This event will be fired before updating the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires |
+|checkout.cart.item.update.after|This event will be fired after updating the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.delete.before|This event will be fired before deleting the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.delete.after|This event will be fired after deleting the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.delete.before|This event will be fired before deleting the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.delete.after|This event will be fired after deleting the database item of checkout table of respective passed `id` and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.move-to-wishlist.before|This event will be fired before adding cart item to wishlist added in checkout and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.item.move-to-wishlist.after|This event will be fired after adding cart item to wishlist added in checkout and you may create a listener file and perform the respective operation when that event fires|
+|customer.registration.before|This event will be fired before registration of customer details and you may create a listener file and perform the respective operation when that event fires|
+|customer.registration.after|This event will be fired after registration of customer details and you may create a listener file and perform the respective operation when that event fires|
+|customer.after.login|This event will be fired after login of customer and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.create.before|This event will be fired before attribute family gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.create.after|This event will be fired after attribute family gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.update.before|This event will be fired before updating attribute family and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.update.after|This event will be fired after updating attribute family and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.delete.before|This event will be fired before deleting attribute family and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute_family.delete.after|This event will be fired after deleting attribute family and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.create.before|This event will be fired before attribute gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.create.after|This event will be fired after attribute gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.update.before|This event will be fired before attribute gets updated and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.update.after|This event will be fired after attribute gets updated and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.delete.before|This event will be fired before attribute gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|catalog.attribute.delete.after|This event will be fired after attribute gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.delete.after|This event will be fired after deleting category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.delete.before|This event will be fired before deleting category with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.delete.after|This event will be fired after deleting category with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.create.before|This event will be fired before creating category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.create.after|This event will be fired after creating category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.update.before|This event will be fired before updating category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.update.after|This event will be fired after updating category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.delete.before|This event will be fired before deleting category and you may create a listener file and perform the respective operation when that event fires|
+|catalog.category.delete.after|This event will be fired after deleting category and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.create.before|This event will be fired before channel gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.create.after|This event will be fired after channel gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.update.before|This event will be fired before channel gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.update.after|This event will be fired after channel gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.delete.before|This event will be fired before channel gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.channel.delete.after|This event will be fired after channel gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.create.before|This event will be fired before currency gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.create.after|This event will be fired after currency gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.update.before|This event will be fired before currency gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.update.after|This event will be fired after currency gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.delete.before|This event will be fired before currency gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.delete.after|This event will be fired after currency gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.delete.before|This event will be fired before currency gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|core.currency.delete.after|This event will be fired after currency gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.create.before|This event will be fired before exchange rate gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.create.after|This event will be fired after exchange rate gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.update.before |This event will be fired before exchange rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.update.after|This event will be fired after exchange rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.delete.before|This event will be fired before exchange rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.exchange_rate.delete.after|This event will be fired after exchange rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.create.before|This event will be fired before locale gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.create.after|This event will be fired after locale gets created and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.update.before|This event will be fired before locale gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.update.after|This event will be fired after locale gets updated and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.delete.before|This event will be fired before locale gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|core.locale.delete.after|This event will be fired after locale gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|customer.registration.before|This event will be fired before customer gets registered and you may create a listener file and perform the respective operation when that event fires|
+|customer.registration.after|This event will be fired after customer gets registered and you may create a listener file and perform the respective operation when that event fires|
+|customer.after.login|This event will be fired after customer successfully logins in store and you may create a listener file and perform the respective operation when that event fires|
+|customer.after.logout|This event will be fired after customer successfully logouts from store and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.create.before|This event will be fired before inventory source gets created and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.create.after|This event will be fired after inventory source gets created and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.update.before|This event will be fired before inventory source gets updated and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.update.after|This event will be fired after inventory source gets updated and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.delete.before|This event will be fired before inventory source gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|inventory.inventory_source.delete.after|This event will be fired after inventory source gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.update.before|This event will be fired before customer review gets updated and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.update.after|This event will be fired after customer review gets updated and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.delete.before|This event will be fired before customer review gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.delete.after|This event will be fired after customer review gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.delete.before|This event will be fired before customer review gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.delete.after|This event will be fired after customer review gets deleted with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.update.before|This event will be fired before customer review gets updated with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|customer.review.update.after|This event will be fired after customer review gets updated with mass selection and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.create.before|This event will be fired before product gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.create.after|This event will be fired after product gets created and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.update.before|This event will be fired before product gets updated and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.update.after|This event will be fired after product gets updated and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.delete.before|This event will be fired before product gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.delete.after|This event will be fired after product gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|sales.invoice.save.before|This event will be fired before invoice gets created and you may create a listener file and perform the respective operation when that event fires|
+|sales.invoice.save.after|This event will be fired after invoice gets created and you may create a listener file and perform the respective operation when that event fires|
+|checkout.order.save.before|This event will be fired before order gets created and you may create a listener file and perform the respective operation when that event fires|
+|checkout.order.save.after|This event will be fired after order gets created and you may create a listener file and perform the respective operation when that event fires|
+|sales.order.cancel.before|This event will be fired before order gets cancelled and you may create a listener file and perform the respective operation when that event fires|
+|sales.order.cancel.after|This event will be fired after order gets cancelled and you may create a listener file and perform the respective operation when that event fires|
+|catalog.product.update.after|This event will be fired after product gets updated and you may create a listener file and perform the respective operation when that event fires|
+|sales.shipment.save.before|This event will be fired before shipment for product gets created and you may create a listener file and perform the respective operation when that event fires|
+|sales.shipment.save.after|This event will be fired after shipment for product gets created and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.add.before|This event will be fired before product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.add.after|This event will be fired after product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.delete.before|This event will be fired before product get deleted from cart and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.delete.after|This event will be fired after product get deleted from cart and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.update.before|This event will be fired before cart item get updated and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.update.after|This event will be fired after cart item get updated and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.add.before|This event will be fired before configurable product get added in cart and you may create a listener file and perform the respective operation when that event fires|
+|checkout.cart.add.after|This event will be fired after configurable product get added in cart and proceeded to but the product and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.create.before|This event will be fired before tax category gets created and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.create.after|This event will be fired after tax category gets created and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.update.before|This event will be fired before tax category gets updated and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.update.after|This event will be fired after tax category gets updated and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.delete.before|This event will be fired before tax category gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_category.delete.after|This event will be fired after tax category gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.create.before|This event will be fired before tax rate gets created and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.create.after|This event will be fired after tax rate gets created and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.update.before|This event will be fired before tax rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.update.after|This event will be fired after tax rate gets updated and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.delete.before|This event will be fired before tax rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|tax.tax_rate.delete.after|This event will be fired after tax rate gets deleted and you may create a listener file and perform the respective operation when that event fires|
+|user.role.create.before|This event will be fired before user role gets created. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.role.create.after|This event will be fired after user role gets created. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.role.update.before|This event will be fired before user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.role.update.after|This event will be fired after user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.role.delete.before|This event will be fired before user role gets updated. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.role.delete.after|This event will be fired after user role gets deleted. The role of user in created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.create.before|This event will be fired before user gets created. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.update.before|This event will be fired before user gets updated. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.update.after|This event will be fired after user gets updated. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.delete.before|This event will be fired before user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.delete.before|This event will be fired before user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+|user.admin.delete.after|This event will be fired after user gets deleted. The user gets created from admin panel and you may create a listener file and perform the respective operation when that event fires|
+
+## Events Listen in Bagisto
+
+| Events name | functionality |
+| ------------------------------- | ------------- |
+| checkout.order.save.after | This event will be fired after order creation and listen in `ProductFlat` listener file to send new order mail from `sendNewOrderMail` function |
+| sales.invoice.save.after | This event will be fired after invoice details have been saved and listen in `ProductFlat` listener file to send new invoice mail from `sendNewInvoiceMail` function |
+| sales.shipment.save.after | This event will be fired after shipment details have been saved and listen in `ProductFlat` listener file to send new shipment mail from `sendNewShipmentMail` function |
+| checkout.order.save.after | This event will be fired after order has been created and will listen in `ProductFlat` listener file to update product inventory from `updateProductInventory` function |
+| catalog.attribute.create.after | This event will be fired after attribute has been created and listen in `ProductFlat` listener file from `afterAttributeCreatedUpdated` function |
+| catalog.attribute.update.after | This event will be fired after attribute has updated and listen in `ProductFlat` listener file from `afterAttributeCreatedUpdated` function |
+| catalog.attribute.delete.before | This event will be fired before attribute has been delete and listen in `ProductFlat` listener file from `afterAttributeDeleted` function |
+| catalog.product.create.after | This event will be fired after product has been creation and listen in `ProductFlat` listener file from `afterProductCreatedUpdated` function |
+| catalog.product.update.after | This event will be fired after product has been updated and listen in `ProductFlat` listener file from `afterProductCreatedUpdated` function |
+
+## Listen Existing Event
+
+As above, all events used in bagisto are listed here so you may change or edit the listener function such as- `sendNewOrderMail` that is defined in `productFlat` listener file, so you can edit and perform the required operation
+
+~~~php
+class EventServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstrap services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ Event::listen('checkout.order.save.after', 'Webkul\Admin\Listeners\Order@sendNewOrderMail');
+ }
+}
+~~~
\ No newline at end of file
diff --git a/docs/1.x/advanced/helpers.md b/docs/1.x/advanced/helpers.md
new file mode 100644
index 00000000..8a26e243
--- /dev/null
+++ b/docs/1.x/advanced/helpers.md
@@ -0,0 +1,181 @@
+# Helpers
+
+In Bagisto, there are several packages have been used. We have provided useful helper methods in the packages which can help developers to develop their projects with ease.
+
+## Core Helpers
+
+All the mentioned helper methods are from Bagisto's core package class named `Core` in the `Webkul\Core` namespace. Let's discuss some common methods,
+
+- Get all the channels,
+
+ ~~~php
+ core()->getAllChannels();
+ ~~~
+
+- Get the current channel,
+
+ ~~~php
+ core()->getCurrentChannel();
+ ~~~
+
+- Set the current channel, this method will take one argument i.e. instance of this class `Webkul\Core\Models\Channel`,
+
+ ~~~php
+ core()->setCurrentChannel($channel);
+ ~~~
+
+- Get the current channel code,
+
+ ~~~php
+ core()->getCurrentChannelCode();
+ ~~~
+
+- Get the default channel,
+
+ ~~~php
+ core()->getDefaultChannel();
+ ~~~
+
+- Get the default channel code,
+
+ ~~~php
+ core()->getDefaultChannelCode();
+ ~~~
+
+- Get requested channel code, this method is useful when you need to fetch the channel from the request, and no need to worry about the fallback as well. This method also has the optional parameter `$fallback`, which means the developer can use this with or without fallback,
+
+ ~~~php
+ core()->getRequestedChannelCode();
+ ~~~
+
+- Get the channel name, yeah we know that you can chain it with the `Channel` instance but the purpose of this method is to handle the fallback case as well. This method will first check the name in the property, if not found then it will proceed further with app locale code, if still not found then it will check from the config key name as `app.fallback_locale`,
+
+ ~~~php
+ core()->getChannelName($channel);
+ ~~~
+
+- Get all the locales,
+
+ ~~~php
+ core()->getAllLocales();
+ ~~~
+
+- Get all locales by requested channel, this method will provide you all the locales associated with the requested channel,
+
+ ~~~php
+ core()->getAllLocalesByRequestedChannel();
+ ~~~
+
+- Get the current locale,
+
+ ~~~php
+ core()->getCurrentLocale();
+ ~~~
+
+- Get the requested locale code, this method is useful when you need to fetch the locale code from the request, and no need to worry about the fallback as well. This method also has the optional parameter `$localeKey` and `$fallback`, which means the developer can use this with or without fallback,
+
+ ~~~php
+ core()->getRequestedLocaleCode();
+ ~~~
+
+- Get all the customer groups,
+
+ ~~~php
+ core()->getAllCustomerGroups();
+ ~~~
+
+- Get requested customer group code, this method will fetch you customer group code from the request,
+
+ ~~~php
+ core()->getRequestedCustomerGroupCode();
+ ~~~
+
+- Get all the currencies,
+
+ ~~~php
+ core()->getAllCurrencies();
+ ~~~
+
+- Get the base currency,
+
+ ~~~php
+ core()->getBaseCurrency();
+ ~~~
+
+- Get the base currency code,
+
+ ~~~php
+ core()->getBaseCurrencyCode();
+ ~~~
+
+- Get the channel based currency,
+
+ ~~~php
+ core()->getChannelBaseCurrency();
+ ~~~
+
+- Get the channel based currency code,
+
+ ~~~php
+ core()->getChannelBaseCurrencyCode();
+ ~~~
+
+- Get the current currency,
+
+ ~~~php
+ core()->getCurrentCurrency();
+ ~~~
+
+- Get the current currency code,
+
+ ~~~php
+ core()->getCurrentCurrencyCode();
+ ~~~
+
+- Get the exchange rate based on the currency id,
+
+ ~~~php
+ core()->getExchangeRate($targetCurrencyId);
+ ~~~
+
+- Get the formatted amount,
+
+ ~~~php
+ core()->currency($amount = 0);
+ ~~~
+
+- Get the configuration date based on the key, channel and locale,
+
+ ~~~php
+ core()->getConfigData($field, $channel = null, $locale = null);
+ ~~~
+
+- Get all the countries,
+
+ ~~~php
+ core()->countries();
+ ~~~
+
+- Get the country name by country code,
+
+ ~~~php
+ core()->country_name($countryCode);
+ ~~~
+
+- Get all the country's state,
+
+ ~~~php
+ core()->states($countryCode);
+ ~~~
+
+- Get sender email details,
+
+ ~~~php
+ core()->getSenderEmailDetails();
+ ~~~
+
+- Get admin email details,
+
+ ~~~php
+ core()->getAdminEmailDetails();
+ ~~~
diff --git a/docs/1.x/advanced/indexing-products-to-elasticsearch.md b/docs/1.x/advanced/indexing-products-to-elasticsearch.md
new file mode 100644
index 00000000..e5bf70e0
--- /dev/null
+++ b/docs/1.x/advanced/indexing-products-to-elasticsearch.md
@@ -0,0 +1,96 @@
+# Indexing products to Elasticsearch
+
+In this section, we will explain the indexing of products from the database to the Elasticsearch engine.
+
+## Setting up environment
+
+To continue with this make sure you have [Elasticseach](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) installed on your system. By default, Elasticsearch uses the `9200` port. So, we are using the same port.
+
+Just hit this route `http://localhost:9200`, if you see the below image then Elasticsearch is successfully installed on your system,
+
+![Elasticsearch Installation Info](../../assets/1.x/images/advanced-topics/elastic-search/installed-elastic-info.png)
+
+::: tip
+
+If you want to use curl, you can hit this command,
+
+~~~sh
+curl -X GET 'http://localhost:9200'
+~~~
+
+:::
+
+You can use [Kibana](https://www.elastic.co/guide/en/kibana/7.10/index.html) for visualization also, but in this section, we are using only the Elasticsearch engine.
+
+## Setting up config
+
+The most simple way to set up your environment is by just setting the key in the `.env` file.
+
+- Now, open the `.env` file in your project and this line,
+
+ ~~~env
+ SCOUT_DRIVER=elastic
+ ELASTIC_HOST="localhost:9200"
+ ~~~
+
+- After that run `php artisan config:cache`.
+
+- Done! Now you are all set to index your products.
+
+::: tip
+
+If still it is not working, then you can directly set your config in the following files i.e.,
+
+- `config/elastic.client.php`
+
+ ~~~php
+ ...
+
+ 'hosts' => [
+ env('ELASTIC_HOST', 'localhost:9200'),
+ ]
+
+ ...
+ ~~~
+
+- `config/scout.php`
+
+ ~~~php
+ ...
+
+ 'driver' => env('SCOUT_DRIVER', 'elastic'),
+
+ ...
+ ~~~
+
+Then run `php artisan config:cache`.
+
+:::
+
+## Indexing
+
+Now, after setting up the environment and config, your product gets automatically indexed when you create a new one.
+
+If you want to index the existing products, then you need to run the below command,
+
+~~~php
+php artisan scout:import Webkul\\Product\\Models\\ProductFlat
+~~~
+
+This command will index all your data from `product_flat` table to Elasticsearch index.
+
+## Checking index
+
+Now, let's check our imported index in the Elasticsearch by hitting this URL `http://localhost:9200/_cat/indices?v`,
+
+![Product Index Info](../../assets/1.x/images/advanced-topics/elastic-search/product-index.png)
+
+::: tip
+
+If you want to use curl, you can hit this command,
+
+~~~sh
+curl -X GET 'http://localhost:9200/_cat/indices?v'
+~~~
+
+:::
diff --git a/docs/1.x/advanced/override-core-model.md b/docs/1.x/advanced/override-core-model.md
new file mode 100644
index 00000000..6ad2c19e
--- /dev/null
+++ b/docs/1.x/advanced/override-core-model.md
@@ -0,0 +1,61 @@
+# Override core model
+
+Concord is a Laravel Extension that helps building modules on top of Laravel's built-in Service Providers.
+Bagisto uses Concord for managing their modules.
+The concept of model proxies has been introduced. Proxies, as the name suggests will drive you to the actual model class.
+
+Concord's concept also requires to have an interface **_Product_** and this way it's possible to freely bind a concrete class to it using Concord's **registerModel()** method.
+
+`Models\Product` class gets bound to the `Contracts\Product` interface within the module (consider it as a default). If the application wants to extend that class, it invokes Concord's **registerModel()** again, and that's all.
+
+The **registerModel()** method also silently binds the interface to the implementation with Laravel's service container so you can simply type-hint the interface at any point where automatic injection happens.
+
+**Note** : _For more details check_ Concord _on github or refer to its_ Documentation
+
+Overriding Model class in the application:
+
+Concord modules generally define an interface for every eloquent model. If you want to override a model you can tell concord to use another class for that interface. Below, you may have a look at code
+
+```php
+ namespace App\Providers;
+
+ use Illuminate\Support\ServiceProvider;
+ use Illuminate\Support\Facades\Schema;
+
+ class AppServiceProvider extends ServiceProvider
+ {
+
+ /**
+ * Bootstrap any application services.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ $this->app->concord->registerModel(
+ \Webkul\Product\Contracts\Product::class, \App\Http\Product::class
+ );
+ }
+ }
+```
+
+In the code shown above, **registerModel()** method accepts two parameters, described below:
+
+- The first parameter states your Contracts path which you want to override.
+
+- The second parameter states the model path from where you will override the model.
+
+The model from which you want to override must extend your model path as shown below
+
+```php
+field('home_page_content')
+ ->with(['sliderData' => $sliderData])->render() !!}
+
+ {!! view_render_event('bagisto.shop.home.content.after') !!}
+
+ @endsection
+```
+
+To render any template before or after any function we may use 'view_render_event'.
+You can define any event view_render_event() in the template by following steps:
+
+## Steps to render View
+
+- Create an event in the blade file in which you want to render any content before or after any content of that template:
+
+```php
+ {!! view_render_event('bagisto.shop.test.before') !!}
+```
+
+As you can see, `bagisto.shop.test` is the event name here that is defined in a random blade file of the project.
+
+- Now you have to listen to the event at **_EventServiceProvider.php_** file and in the boot method like:
+
+```php
+ Event::listen('bagisto.shop.test.before', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('template file path that you want to inject');
+ });
+```
+
+As you can see, you have to add the path of the template that you want to render.
+After that, this will automatically fire and your template will be injected before the content.
+Make sure that you have registered EventServiceProvider in your ServiceProvider.
diff --git a/docs/1.x/advanced/security-practice.md b/docs/1.x/advanced/security-practice.md
new file mode 100644
index 00000000..72e052c3
--- /dev/null
+++ b/docs/1.x/advanced/security-practice.md
@@ -0,0 +1,151 @@
+# Best Security Practices
+
+## Keep your software up-to-date
+
+- Using HTTPS (Google now uses HTTPS as a ranking factor).
+
+- Keep all software on the server up-to-date.
+ - Bagisto
+ - Database
+ - Adminer/phpMyAdmin
+ - Apache
+ - Redis, etc.
+
+- Make sure the server operating system is up-to-date for available security patches.
+
+- Manage files only with secure communication protocols (SSH/ SFTP/ HTTPs), disable FTP.
+
+- [ .htaccess ] file to protect system files, when using apache webserver.
+
+- Disable unused ports, and stop services running unnecessarily.
+
+- Restrict access to certain IPs to the admin panel and use Admin logins with two-factor authorization.
+
+- Use of strong and unique passwords.
+
+- Use a properly configured and updated firewall between the payment card data and the public network.
+
+## Limiting error messages
+
+![limiting-error-messages](../../assets/1.x/images/advanced-topics/best-security-practices/limiting-error-messages.png)
+
+- Edit your apache configuration file to avoid displaying server and os details.
+
+- Set “ServerSignature” to OFF as by default it is ON.
+
+- Add “ServerTokens Prod” to display Apache as product only.
+
+## Allow admin access to certain IPs
+
+- Edit your .htaccess file with the following code
+
+~~~
+RewriteEngine On
+RewriteCond %{REQUEST*URI} .*/admin
+RewriteCond %{REMOTE*ADDR} !=
+RewriteCond %{REMOTE_ADDR} !=
+RewriteRule ^(.*)\$ - [R=403,L]
+~~~
+
+- Review your server for development leftovers. Make sure there are no accessible "log files", ".git directories", "database dumps", "zip files".
+
+## Restrict files with .git, .zip, .gz, and .sql extensions
+
+- Edit your .htaccess file
+
+~~~
+
+ Require all denied
+
+~~~
+
+- Use a Web application firewall to analyze traffic and discover suspicious patterns such as credit card information being sent to an attacker.
+
+- Make sure only port 80 and 443 are publicly accessible and the rest of the ports are restricted.
+
+
+## Restrict php execution inside storage directory
+
+- Edit your apache configuration file
+
+ ~~~
+
+
+ Require all denied
+
+ php_flag engine off
+
+ ~~~
+
+ ::: tip
+
+ Don't forget to restart apache.
+
+ :::
+
+## Harden your server
+
+- Use of mod_security module to detect and prevent intrusions.
+
+- Use of mod_passive module to prevent brute force attack.
+
+- Allow only specific users to login.
+
+- Disable login to users with empty passwords.
+
+- Check iptable rules to prevent unauthorized access and activity.
+
+- Take regular backup of important files and also save them remotely in a secure environment.
+
+## Use strong and unique passwords
+
+- Use strong and unique passwords, and change them periodically.
+
+ ::: tip
+
+ Use password generator. ([Password Generator](https://passwords-generator.org/))
+
+ :::
+
+- Limit access to the Bagisto admin by updating the whitelist with the IP address of each computer that is authorized to use the admin.
+
+## Implementation of HTTP Security Headers
+
+- In addition, Headers play a key role in communication between the client and the server, some of
+them have been mentioned in order to enhance the web security.
+
+### HTTP Strict Transport Security (HSTS)
+
+- This response header will tell the browser that the application is only to be accessed using https instead of http.
+
+ `Strict-Transport-Security: max-age=`
+
+### Cross Site Scripting Protection (X-XSS Protection)
+
+- This response header will enforce browsers to detect cross site scripting attacks and not to execute malicious js script in response.
+
+ `X-XSS-Protection: 1; mode=block`
+
+### X-Frame-Options
+
+- This response header enables the protection of applications against clickjacking. It tells the browser whether the content can be displayed within frames.
+
+ `X-Frame-Options: deny`
+
+### X-Content-Type-Options
+
+- This header will force the browser to disable MIME sniffing.
+
+- MIME sniffing vulnerability occurs when an attacker uploads an HTML file as a different file type such as jpg.
+
+ `X-Content-Type-Options: nosniff`
+
+### Content Security Policy (CSP)
+
+- This response header allows application administrators to control resources that can be loaded in users' browsers and helps to detect and mitigate attacks such as xss, clickjacking.
+
+### Continuous Logging And Monitoring
+
+- Likewise, monitor all access to the network and cardholder data environment.
+- Keep an eye on large volume orders for a single item from a new customer.
+- A series of orders, shipped to the same address using different payment methods.
diff --git a/docs/1.x/api/README.md b/docs/1.x/api/README.md
new file mode 100644
index 00000000..6c1ba515
--- /dev/null
+++ b/docs/1.x/api/README.md
@@ -0,0 +1,21 @@
+# Bagisto Web APIs
+
+Bagisto Web API is a medium to use the features of the core Bagisto System. By using Bagisto Web API, you can integrate your application to serve the default content of Bagisto.
+
+## Key Features
+
+- Bagisto APIs supports REST (Representational State Transfer).
+- Authentication: Customer Authentication with Login Details.
+- Provide access to performed CRUD operations.
+- Also Provide the option to filter the responses based on attribute fields.
+- The Framework supports the pagination which helps to increase the performance of application.
+
+## Where can I use Bagisto Web APIs?
+
+We can use the Bagisto APIs in different areas. Some of them are:
+
+- To build a PWA (Progressive Web Application) application, which uses modern web capabilities to deliver an application like experience to the users and provide more user friendly experience than a web application.
+
+- Use to integrate an Online-Shopping Mobile Application with the Bagisto Store to help the customers make purchase.
+
+- Use to integrate with CRM (Customer Relationship Management) systems Like: HubSpot, Salesforce etc. which allows you to manage the business relationships with your customers to help you grow your business.
diff --git a/docs/1.x/api/addresses.md b/docs/1.x/api/addresses.md
new file mode 100644
index 00000000..dfbf4754
--- /dev/null
+++ b/docs/1.x/api/addresses.md
@@ -0,0 +1,278 @@
+# Addresses
+
+In this section, we will use all the addresses' API. We will check the creation of address, fetching of addresses, and updation of address.
+
+## Create a new address
+
+To add an address, you have to use the `addresses/create` endpoint url and have to pass the address fields in the request payload. This `addresses/create` API call resource will create a new address of the customer, only if that customer has logged in the store.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/addresses/create`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------ | ------------ | ------ |
+ | address1 | Address | Array |
+ | city | City | String |
+ | country | Country | String |
+ | country_name | Country Name | String |
+ | phone | Phone | String |
+ | postcode | Post Code | String |
+ | state | State | String |
+
+### Examples
+
+Let's take an example of creating an address,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/addresses/create`
+
+- Params
+
+ | Name | Value |
+ | ------------ | --------------- |
+ | address1 | ['Clock Tower'] |
+ | city | Dehradun |
+ | country | IN |
+ | country_name | India |
+ | phone | 0123456798 |
+ | postcode | 248001 |
+ | state | UT |
+
+ ~~~json
+ {
+ "address1": [
+ "Clock Tower"
+ ],
+ "city": "Dehradun",
+ "country": "IN",
+ "country_name": "India",
+ "phone": "0123456798",
+ "postcode": "248001",
+ "state": "UT"
+ }
+ ~~~
+
+::: details Response
+
+ ~~~json
+ {
+ "message":"Address has been created successfully.",
+ "data": {...} // This contains the data you send to the api.
+ }
+ ~~~
+
+:::
+
+## Get all addresses
+
+To get all the address of a customer, that customer must be logged in to the store. You can achieve this job by using `addresses` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/addresses`
+
+### Examples
+
+Let's take an example,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/addresses`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 3,
+ "address1": [...],
+ "country": "IN",
+ "country_name": "India",
+ "state": "UT",
+ "city": "Dehradun",
+ "postcode": 248001,
+ "phone": "01345679",
+ },
+ {
+ "id": 2,
+ "address1": [...],
+ "country": "IN",
+ "country_name": "India",
+ "state": "UP",
+ "city": "Noida",
+ "postcode": 201301,
+ "phone": "012345679",
+ },
+ ]
+ }
+ ~~~
+
+:::
+
+## Get address by id
+
+To get the customer's specific address, you have to pass an `address_id` as a request payload like `addresses/{address_id}` in API URL. By using this resource and request payload, you will get only a single object under the `data` object in response.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/addresses/{address_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ------- | ------ |
+ | address_id | Address | Number |
+
+### Examples
+
+Let's take an example,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/addresses/1`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 1,
+ "address1": [
+ "Block H-ARP Park, Sector 63 "
+ ],
+ "country": "IN",
+ "country_name": "India",
+ "state": "UP",
+ "city": "Noida",
+ "postcode": 201301,
+ "phone": "0132456789",
+ "created_at": {
+ "date": "",
+ "timezone_type": 3,
+ "timezone": "Asia/Kolkata"
+ },
+ "updated_at": {
+ "date": "",
+ "timezone_type": 3,
+ "timezone": "Asia/Kolkata"
+ },
+ }
+ }
+ ~~~
+
+:::
+
+## Update address
+
+To update the customer's specific address, you have to pass an `address_id` as a request payload like `addresses/{address_id}` in API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT /api/addresses/1`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------ | ------------ | ------ |
+ | address1 | Address | Array |
+ | city | City | String |
+ | country | Country | String |
+ | country_name | Country Name | String |
+ | phone | Phone | String |
+ | postcode | Post Code | String |
+ | state | State | String |
+
+### Examples
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT http(s)://example.com/api/addresses/1`
+
+- Params
+
+ ~~~json
+ {
+ "id": 1,
+ "address1": [
+ "Clock Tower"
+ ],
+ "city": "New Delhi",
+ "country": "IN",
+ "country_name": "India",
+ "phone": "9876543210",
+ "postcode": "248001",
+ "state": "DL"
+ }
+ ~~~
+
+::: details Response
+
+ ~~~json
+ {
+ "message":"Your address has been updated successfully.",
+ "data": {...} // Address' detail.
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/attribute-families.md b/docs/1.x/api/attribute-families.md
new file mode 100644
index 00000000..a686e627
--- /dev/null
+++ b/docs/1.x/api/attribute-families.md
@@ -0,0 +1,239 @@
+# Attribute Families
+
+Attribute families are the group of attributes that can be assigned to the product according to the product's needs.
+
+## Get all attribute familes
+
+This api request will fetch all the attribute families.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/families(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get attribute families of the specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/families?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/families`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 1,
+ "code": "default",
+ "name": "Default",
+ "status": 0,
+ "groups": [...]
+ "created_at": null,
+ "updated_at": null
+ }
+ ],
+ "links": {
+ "first": "https://example.com/api/families?page=1",
+ "last": "https://example.com/api/families?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "links": [
+ { "url": null, "label": "« Previous", "active": false },
+ {
+ "url": "https://example.com/api/families?page=1",
+ "label": "1",
+ "active": true
+ },
+ { "url": null, "label": "Next »", "active": false }
+ ],
+ "path": "https://example.com/api/families",
+ "per_page": 10,
+ "to": 1,
+ "total": 1
+ }
+ }
+ ~~~
+
+:::
+
+#### 2. Get attribute families of the specific page with limit
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/families?page=1&limit=5`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 1,
+ "code": "default",
+ "name": "Default",
+ "status": 0,
+ "groups": [...],
+ "created_at": null,
+ "updated_at": null
+ }
+ ],
+ "links": {
+ "first": "https://example.com/api/families?limit=5&page=1",
+ "last": "https://example.com/api/families?limit=5&page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "links": [
+ { "url": null, "label": "« Previous", "active": false },
+ {
+ "url": "https://example.com/api/families?limit=5&page=1",
+ "label": "1",
+ "active": true
+ },
+ { "url": null, "label": "Next »", "active": false }
+ ],
+ "path": "https://example.com/api/families",
+ "per_page": "5",
+ "to": 1,
+ "total": 1
+ }
+ }
+ ~~~
+
+:::
+
+#### 3. Get all attribute families without pagination
+
+If you don't want to use the pagination and want to access all the store's attribute families at once, then you have to send a filter parameter named as`pagination` with value `zero`. By doing this you will get all attributes objects at once in the data object and this will not give you link and meta objects.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/families?pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 1,
+ "code": "default",
+ "name": "Default",
+ "status": 0,
+ "groups": [...],
+ "created_at": null,
+ "updated_at": null
+ }
+ ]
+ }
+ ~~~
+
+:::
+
+## Get attribute family by id
+
+For fetching any specific attribute family, you have to provide the attribute family's id as an input parameter.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/families/{id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---- | --------------------- | ------ |
+ | id | Attribute Family's id | Number |
+
+### Examples
+
+#### 1. Let's try to fetch attribute family by id
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/families/1`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 1,
+ "code": "default",
+ "name": "Default",
+ "status": 0,
+ "groups": [...],
+ "created_at": null,
+ "updated_at": null
+ }
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/attributes.md b/docs/1.x/api/attributes.md
new file mode 100644
index 00000000..9181c9b5
--- /dev/null
+++ b/docs/1.x/api/attributes.md
@@ -0,0 +1,355 @@
+# Attributes
+
+In this section, we are using the attributes' API. An Attribute is a specification or characteristics of a product for example color, size, pattern are an attribute of T-Shirt. You can as create many attributes for a single product. Product Attribute plays a major factor in buying decision of the Customer.
+
+## Get all attributes
+
+This api request will fetch all the attributes.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/attributes(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get attributes of the specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/attributes?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/attributes`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id":27,
+ "code":"product_number",
+ "type":"text",
+ "name":"Product Number",
+ "swatch_type":null,
+ "options":[],
+ "created_at":"2021-05-24T05:09:12.000000Z",
+ "updated_at":"2021-05-24T05:09:12.000000Z"
+ },
+ {...},
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/attributes?page=1",
+ "last": "https://example.com/api/attributes?page=3",
+ "prev": null,
+ "next": "https://example.com/api/attributes?page=2"
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 3,
+ "links": [...],
+ "path": "https://example.com/api/attributes",
+ "per_page": 10,
+ "to": 10,
+ "total": 27
+ }
+ }
+ ~~~
+
+:::
+
+#### 2. Get attributes of the specific page with limit
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/attributes?page=1&limit=5`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 27,
+ "code": "product_number",
+ "type": "text",
+ "name": "Product Number",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {
+ "id": 26,
+ "code": "guest_checkout",
+ "type": "boolean",
+ "name": "Allow Guest Checkout",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {
+ "id": 25,
+ "code": "brand",
+ "type": "select",
+ "name": "Brand",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {
+ "id": 24,
+ "code": "size",
+ "type": "select",
+ "name": "Size",
+ "swatch_type": null,
+ "options": [
+ { "id": 6, "admin_name": "S", "label": "S", "swatch_value": null },
+ { "id": 7, "admin_name": "M", "label": "M", "swatch_value": null },
+ { "id": 8, "admin_name": "L", "label": "L", "swatch_value": null },
+ { "id": 9, "admin_name": "XL", "label": "XL", "swatch_value": null }
+ ],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {
+ "id": 23,
+ "code": "color",
+ "type": "select",
+ "name": "Color",
+ "swatch_type": null,
+ "options": [
+ { "id": 1, "admin_name": "Red", "label": "Red", "swatch_value": null },
+ {
+ "id": 2,
+ "admin_name": "Green",
+ "label": "Green",
+ "swatch_value": null
+ },
+ {
+ "id": 3,
+ "admin_name": "Yellow",
+ "label": "Yellow",
+ "swatch_value": null
+ },
+ {
+ "id": 4,
+ "admin_name": "Black",
+ "label": "Black",
+ "swatch_value": null
+ },
+ {
+ "id": 5,
+ "admin_name": "White",
+ "label": "White",
+ "swatch_value": null
+ }
+ ],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ }
+ ],
+ "links": {
+ "first": "https://example.com/api/attributes?limit=5&page=1",
+ "last": "https://example.com/api/attributes?limit=5&page=6",
+ "prev": null,
+ "next": "https://example.com/api/attributes?limit=5&page=2"
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 6,
+ "links": [
+ {
+ "url": null,
+ "label": "« Previous",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=1",
+ "label": "1",
+ "active": true
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=2",
+ "label": "2",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=3",
+ "label": "3",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=4",
+ "label": "4",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=5",
+ "label": "5",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=6",
+ "label": "6",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/attributes?limit=5&page=2",
+ "label": "Next »",
+ "active": false
+ }
+ ],
+ "path": "https://example.com/api/attributes",
+ "per_page": "5",
+ "to": 5,
+ "total": 27
+ }
+ }
+ ~~~
+
+:::
+
+#### 3. Get all attributes without pagination
+
+If you don't want to use the pagination and want to access all the store's attributes at once, then you have to send a filter parameter named as`pagination` with value `zero`. By doing this you will get all attributes objects at once in the data object and this will not give you link and meta objects.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/attributes?pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 27,
+ "code": "product_number",
+ "type": "text",
+ "name": "Product Number",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {
+ "id": 26,
+ "code": "guest_checkout",
+ "type": "boolean",
+ "name": "Allow Guest Checkout",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ },
+ {...},
+ {...},
+ {...},
+ {...}
+ ]
+ }
+ ~~~
+
+:::
+
+## Get attribute by id
+
+For fetching any specific attribute, you have to provide the attribute's id as an input parameter.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/attributes/{id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---- | -------------- | ------ |
+ | id | Attribute's id | Number |
+
+### Examples
+
+#### 1. Let's try to fetch attribute by id
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/attributes/1`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 1,
+ "code": "sku",
+ "type": "text",
+ "name": "SKU",
+ "swatch_type": null,
+ "options": [],
+ "created_at": "2021-05-24T05:09:12.000000Z",
+ "updated_at": "2021-05-24T05:09:12.000000Z"
+ }
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/cart.md b/docs/1.x/api/cart.md
new file mode 100644
index 00000000..32c6dfd5
--- /dev/null
+++ b/docs/1.x/api/cart.md
@@ -0,0 +1,1104 @@
+# Cart
+
+In this section, we will use the cart's API. We will see how to add the product to the cart, fetching cart details, updating cart, and many more things related to the cart.
+
+## Add product to cart
+
+By using this API call you can add new products to the cart and also you can add quantity to the existing product in the cart. To do this task, you have to use the `checkout/cart/add/{product_id}` as a request payload in the API URL. This API call will work with both customer's authentication or without customer's authentication.
+
+Currently,Bagisto support the following types of product,
+
+- [Simple](#simple-and-virtual-product)
+- [Configurable](#configurable-product)
+- [Bundle](#bundle-product)
+- [Grouped](#grouped-product)
+- [Downloadable](#downloadable-product)
+- [Virtual](#simple-and-virtual-product)
+
+Let us discuss each product,
+
+### Simple And Virtual Product
+
+A simple product is a physical item with no configurable option like size, color, etc. Whereas virtual product is slightly same as simple but is not a physical item.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ------------ | ------ |
+ | product_id | Product's ID | Number |
+ | quantity | Quantity | Number |
+
+ ```json
+ {
+ "product_id": "product_id",
+ "quantity": "quantity"
+ }
+ ```
+
+### Configurable Product
+
+A Configurable product allows the seller to sell the product in a different variation in Bagisto.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------------------------- | --------------------------------- | ------ |
+ | product_id | Product's ID | Number |
+ | quantity | Quantity | Number |
+ | selected_configurable_option | Configurable product variant's ID | Number |
+ | super_attribute | Attribute's ID collections | Object |
+
+ ```json
+ {
+ "product_id": "product_id",
+ "quantity": "quantity",
+ "selected_configurable_option": "configurable_product_variant_id",
+ "super_attribute": {
+ "attribute_id": "attribute_option_id",
+ "attribute_id": "attribute_option_id"
+ }
+ }
+ ```
+
+### Bundle Product
+
+A bundle product includes a customizable product that you can build for your own.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------------- | -------------------------- | ------ |
+ | product_id | Product's ID | Number |
+ | quantity | Quantity | Number |
+ | bundle_options | Bundle options collections | Object |
+ | bundle_option_qty | Bundle options qunatity | Object |
+
+ ```json
+ {
+ "product_id": "product_id",
+ "quantity": "quantity",
+ "bundle_options": {
+ "first_option_id": {
+ "index_0": "option_product_id"
+ },
+ "second_option_id": {
+ "index_0": "option_product_id",
+ "index_1": "another_option_product_id"
+ }
+ },
+ "bundle_option_qty": {
+ "first_option_id": "quantity"
+ }
+ }
+ ```
+
+### Grouped Product
+
+A grouped product is a group of simple products that can be combined together.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ----------------------------------- | ------ |
+ | product_id | Product's ID | Number |
+ | quantity | Quantity | Number |
+ | qty | Collection of product with quantity | Object |
+
+ ```json
+ {
+ "product_id": "product_id",
+ "quantity": "quantity",
+ "qty": {
+ "product_id_1": "quantity",
+ "product_id_2": "quantity",
+ "product_id_3": "quantity",
+ "product_id_4": "quantity"
+ }
+ }
+ ```
+
+### Downloadable Product
+
+Downloadable product allows you to sell digital products, such as eBooks, software applications, music, updates, games, etc.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ------------------- | ------ |
+ | product_id | Product's ID | Number |
+ | quantity | Quantity | Number |
+ | links | Collection of links | Object |
+
+ ```json
+ {
+ "product_id": "product_id",
+ "quantity": "quantity",
+ "links": {
+ "0": "link_id_1",
+ "1": "link_id_2"
+ }
+ }
+ ```
+
+### Examples
+
+#### 1. For simple product
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/cart/add/24`
+
+- Params
+
+ ```json
+ {
+ "product_id": 24,
+ "quantity": 2
+ }
+ ```
+
+#### 2. For configurable product
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/cart/add/6`
+
+- Params
+
+ ```json
+ {
+ "product_id": 6,
+ "quantity": 1,
+ "selected_configurable_option": 26,
+ "super_attribute": {
+ "23": 2,
+ "24": 6
+ }
+ }
+ ```
+
+::: details Response
+
+```json
+{
+ "message": "Product added to cart successfully.",
+ "data": {
+ "id": 4,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": null,
+ "items_qty": "1.0000",
+ "grand_total": "50.0000",
+ "sub_total": "50.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 0,
+ "items": [
+ {...}, // Cart Item 1
+ {...}, // Cart Item 2
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![bagisto_cart_add](../../assets/1.x/images/api/bagisto_cart_add.jpg)
+
+:::
+
+#### 3. Adding more products to the same cart
+
+For this, you need to pass the `product_id` in the request body also.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/cart/add/25`
+
+- Params
+
+ ```json
+ {
+ "product_id": 25,
+ "quantity": 2
+ }
+ ```
+
+## Get complete cart details
+
+To get the current cart details, you have to use the `checkout/cart` resource in the API URL. You will see in all the `cart` related API, we used the `checkout` prefix. This API call will work with both customer's authentication or without customer's authentication. If the customer is not logged-in to the store, then this API resource will return the guest's cart detail.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/checkout/cart`
+
+### Examples
+
+#### 1. In case of guest customer
+
+In, Bagisto guest cart is handled by session, and Laravel handles session by cookies. So you need to save the cookies for the guest cart when you are adding product to the cart and then send it as a header when you want to fetch.
+
+- Headers
+
+ | Key | Value |
+ | ------ | ------------------- |
+ | Accept | application/json |
+ | Cookie | bagisto_session=key |
+
+- Request
+
+ `GET http(s)://example.com/api/checkout/cart`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 7,
+ "customer_email": null,
+ "customer_first_name": null,
+ "customer_last_name": null,
+ "shipping_method": null,
+ "items_qty": "1.0000",
+ "grand_total": "50.0000",
+ "sub_total": "50.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 1,
+ "items": [
+ {...}, // Cart Item 1
+ {...} // Cart Item 2
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![bagisto_cart_guest](../../assets/1.x/images/api/bagisto_cart_guest.jpg)
+
+:::
+
+#### 2. In case of logged in customer
+
+In the case of the logged-in user, no need for cookies as the cart is in the database and linked with the customer.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/checkout/cart`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 6,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": null,
+ "items_count": 2,
+ "items_qty": "2.0000",
+ "grand_total": "170.0000",
+ "sub_total": "170.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 0,
+ "items": [
+ {...}, // Cart Item 1
+ {...} // Cart Item 2
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![bagisto_cart](../../assets/1.x/images/api/bagisto_cart.jpg)
+
+:::
+
+## Empty cart
+
+By using this API call you can remove all the products from the cart. To do this task, you have to use the `checkout/cart/empty` resource in the API URL. This API call will work both with customer's authentication or without customer's authentication.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/checkout/cart/empty`
+
+### Examples
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/checkout/cart/empty`
+
+::: details Response
+
+```json
+{
+ "message": "Cart removed successfully.",
+ "data": null
+}
+```
+
+:::
+
+## Update cart
+
+By using this API call you can update the cart's product(s) quantity. To do this task, you have to use the `checkout/cart/update` resource in the API URL. This API call will work with both customer's authentication or without customer's authentication.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT /api/checkout/cart/update`
+
+- Params
+
+ ```json
+ {
+ "qty": {
+ "cart_item_id": "quantity"
+ }
+ }
+ ```
+
+### Examples
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT http(s)://example.com/api/checkout/cart/update`
+
+- Params
+
+ ```json
+ {
+ "qty": {
+ "4": 2
+ }
+ }
+ ```
+
+::: details Response:
+
+```json
+{
+ "message": "Cart updated successfully.",
+ "data": {
+ "id": 7,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": null,
+ "items_qty": "7.0000",
+ "grand_total": "450.0000",
+ "sub_total": "450.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 0,
+ "items": [
+ {...}, // Cart Item 1
+ {...}, // Cart Item 2
+ {...} // Cart Item 3
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![Bagisto Cart Update](../../assets/1.x/images/api/bagisto_cart_update.jpg)
+
+:::
+
+## Apply coupon
+
+You can also apply the coupon by using the `checkout/cart/coupon` endpoint.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/cart/coupon`
+
+- Params
+
+ ```json
+ {
+ "code": "OFFER20"
+ }
+ ```
+
+### Examples
+
+Now, let's apply the coupon and check the responses,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/cart/coupon`
+
+- Params
+
+ ```json
+ {
+ "code": "OFFER20"
+ }
+ ```
+
+::: details Response
+
+```json
+{
+ "success": true,
+ "message": "Coupon code applied successfully."
+}
+```
+
+:::
+
+## Remove coupon
+
+For removing the coupon, you just need to hit the `checkout/cart/coupon` endpoint with the `DELETE` method.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `DELETE /api/checkout/cart/coupon`
+
+### Examples
+
+Let's remove the coupon and check the responses,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `DELETE http(s)://example.com/api/checkout/cart/coupon`
+
+::: details Response
+
+```json
+{
+ "success": true,
+ "message": "Remove Coupon"
+}
+```
+
+:::
+
+## Remove specific product from cart
+
+You can remove any particular product from the cart. To do this task, you have to use the `checkout/cart/remove-item/{cart_item_id}` as request payload in the API URL. This API call will work with both customer's authentication or without customer's authentication.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/checkout/cart/remove-item/{cart_item_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------ | -------------- | ------ |
+ | cart_item_id | Cart item's ID | Number |
+
+### Examples
+
+- Request
+
+ `GET http(s)://example.com/api/checkout/cart/remove-item/15`
+
+::: details Response
+
+```json
+{
+ "message": "Cart removed successfully.",
+ "data": {
+ "id": 6,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": null,
+ "items_count": 2,
+ "items_qty": "5.0000",
+ "grand_total": "210.0000",
+ "sub_total": "210.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 0,
+ "items": [
+ {...},
+ {...}
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![bagisto_cart_remove_item](../../assets/1.x/images/api/bagisto_cart_remove_item.jpg){:class="screenshot-dimension center"}
+
+:::
+
+## Move product from cart to wishlist
+
+You can move a product from cart to wishlist. To do this task, you have to use the `checkout/cart/move-to-wishlist/{cart_item_id}` as request payload in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/checkout/cart/move-to-wishlist/{cart_item_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------ | -------------- | ------ |
+ | cart_item_id | Cart item's ID | Number |
+
+### Examples
+
+- Request
+
+ `http(s)://example.com/api/checkout/cart/move-to-wishlist/16`
+
+::: details Response:
+
+```json
+{
+ "message": "Cart item moved to wishlist successfully.",
+ "data": {
+ "id": 1,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": null,
+ "items_qty": "1.0000",
+ "grand_total": "50.0000",
+ "sub_total": "50.0000",
+ "tax_total": "0.0000",
+ "discount": "0.0000",
+ "checkout_method": null,
+ "is_guest": 0,
+ "items": [
+ {...} // Remaining Cart Item
+ ],
+ "selected_shipping_rate": null,
+ "payment": null,
+ "billing_address": null,
+ "shipping_address": null,
+ }
+}
+```
+
+![bagisto_move_to_wishlist](../../assets/1.x/images/api/bagisto_move_to_wishlist.jpg)
+
+:::
+
+## Save addresses to cart
+
+At the checkout step, customers can create new addresses or select from the existing addresses for billing & shipping the cart's item. You can achieve this task by using the `checkout/save-address` resource in the API URL. This API will work for both logged-in customers and guest users.
+
+- Request
+
+ `POST /api/checkout/save-address`
+
+### Examples
+
+#### 1. For logged in user,
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/save-address`
+
+- Params
+
+ ```json
+ {
+ "billing": {
+ "address1": {
+ "0": ""
+ },
+ "use_for_shipping": "false",
+ "first_name": "john",
+ "last_name": "doe",
+ "email": "john@gmail.com",
+ "address_id": 1
+ },
+ "shipping": {
+ "address1": {
+ "0": ""
+ },
+ "first_name": "john",
+ "last_name": "doe",
+ "email": "john@gmail.com",
+ "address_id": 2
+ }
+ }
+ ```
+
+#### 2. For guest user
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/save-address`
+
+- Params
+
+ ```json
+ {
+ "billing": {
+ "address1": {
+ "0": "H 23"
+ },
+ "use_for_shipping": "true",
+ "first_name": "john",
+ "last_name": "doe",
+ "email": "john@webkul.com",
+ "city": "noida",
+ "state": "DL",
+ "postcode": "110092",
+ "country": "IN",
+ "phone": "8802097347"
+ },
+ "shipping": {
+ "address1": {
+ "0": ""
+ }
+ }
+ }
+ ```
+
+::: details Response
+
+```json
+{
+ "data": {
+ "rates": [{...},{...}],
+ "cart": {
+ "id": 6,
+ "customer_email": "johndoe@example.com",
+ "items": [{...}, {...}],
+ "billing_address": {
+ "id": 7,
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "email": "johndoe@example.com",
+ "address1": [
+ "Block H-ARP Park, Sector 63 "
+ ],
+ "country": "IN",
+ "country_name": "India",
+ "state": "UP",
+ "city": "Noida",
+ "postcode": 201301,
+ "phone": "0132456789"
+ },
+ "shipping_address": {
+ "id": 8,
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "email": "johndoe@example.com",
+ "address1": [
+ "Block H-ARP Park, Sector 63 "
+ ],
+ "country": "IN",
+ "country_name": "India",
+ "state": "UP",
+ "city": "Noida",
+ "postcode": 201301,
+ "phone": "0132456789"
+ }
+ }
+ }
+}
+```
+
+![bagisto_save_address](../../assets/1.x/images/api/bagisto_save_address.jpg)
+
+:::
+
+## Save shipping method to cart
+
+After saving the customer's addresses to the cart, you have to select a shipping method to proceed for completing the order. You can achieve this task by using the `checkout/save-shipping` resource in the API URL. The shipping method and changes will apply to the cart through this API call. This API will work for both logged-in customers and guest users.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/save-shipping`
+
+- Params
+
+ ```json
+ {
+ "shipping_method": "shipping_method_key"
+ }
+ ```
+
+### Examples
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/save-shipping`
+
+- Params
+
+ ```json
+ {
+ "shipping_method": "flatrate_flatrate"
+ }
+ ```
+
+::: details Response
+
+```json
+{
+ "data": {
+ "methods": [{...},{...}],
+ "cart": {
+ "id": 6,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": "flatrate_flatrate",
+ "items": [{...}],
+ "selected_shipping_rate": {
+ "id": 9,
+ "carrier": "flatrate",
+ "carrier_title": "Flat Rate",
+ "method": "flatrate_flatrate",
+ "method_title": "Flat Rate",
+ "method_description": "This is a flat rate",
+ "price": 20,
+ },
+ "payment": null,
+ "billing_address": {...},
+ "shipping_address": {...}
+ }
+ }
+}
+```
+
+![bagisto_save_shipping](../../assets/1.x/images/api/bagisto_save_shipping.jpg)
+
+:::
+
+## Save payment method to cart
+
+After applying the shipping method to the cart, you have to select a payment method to proceed for completing the order. You can achieve this task by using the `checkout/save-payment` resource in the API URL. By using this API payment method will apply to the cart and will work with both logged-in customers and as well as guest users.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/save-payment`
+
+- Params
+
+ ```json
+ {
+ "payment": {
+ "method": "payment_method_key"
+ }
+ }
+ ```
+
+### Examples
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/save-payment`
+
+- Params
+
+ ```json
+ {
+ "payment": {
+ "method": "cashondelivery"
+ }
+ }
+ ```
+
+::: details Response
+
+```json
+{
+ "data": {
+ "cart": {
+ "id": 6,
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_method": "flatrate_flatrate",
+ "items": [{...}],
+ "selected_shipping_rate": {...},
+ "payment": {
+ "id": 4,
+ "method": "cashondelivery",
+ "method_title": "Cash On Delivery"
+ },
+ "billing_address": {...},
+ "shipping_address": {...}
+ }
+ }
+}
+```
+
+![bagisto_save_payment](../../assets/1.x/images/api/bagisto_save_payment.jpg)
+
+:::
+
+## Save Order
+
+After applying shipping addresses, shipping methods, and payment methods to the cart, now finally you have to create/save the order. You can achieve this task by using the `checkout/save-order` resource in the API URL. By using this API order will be placed and save to the current store and this API will work for both logged-in customers and with guest users.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `POST /api/checkout/save-order`
+
+### Examples
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/checkout/save-order`
+
+::: details Response
+
+```json
+{
+ "success": true,
+ "order": {
+ "id": 4,
+ "status": "pending",
+ "customer_email": "johndoe@example.com",
+ "customer_first_name": "John",
+ "customer_last_name": "Doe",
+ "shipping_title": "Flat Rate - Flat Rate",
+ "payment_title": "Cash On Delivery",
+ "total_qty_ordered": "2.0000",
+ "grand_total": "120.0000",
+ "shipping_amount": 20,
+ "customer": {...},
+ "shipping_address": {...},
+ "billing_address": {...},
+ "items": [{...}],
+ "invoices": [],
+ "shipments": []
+ }
+}
+```
+
+![bagisto_save_order](../../assets/1.x/images/api/bagisto_save_order.jpg)
+
+:::
diff --git a/docs/1.x/api/categories.md b/docs/1.x/api/categories.md
new file mode 100644
index 00000000..e4b1012a
--- /dev/null
+++ b/docs/1.x/api/categories.md
@@ -0,0 +1,363 @@
+# Categories
+
+In this section, we are using the categories' API. We will fetch all the categories based on `id` and `parent_id` as well.
+
+## Get all categories
+
+This api request will fetch all the categories.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/categories(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get categories of the specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/categories?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/categories`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 3,
+ "code": null,
+ "name": "Laptops",
+ "slug": "laptops",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "Laptops",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-08T23:41:24.000000Z",
+ "updated_at": "2020-09-08T23:41:24.000000Z"
+ },
+ {...},
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/categories?page=1",
+ "last": "https://example.com/api/categories?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "path": "https://example.com/api/categories",
+ "per_page": 10,
+ "to": 3,
+ "total": 3
+ }
+ }
+ ~~~
+
+:::
+
+#### 2. Get categories of the specific page with limit
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/categories?page=1&limit=10`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 10,
+ "code": null,
+ "name": "Lights",
+ "slug": "lights",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-24T11:44:42.000000Z",
+ "updated_at": "2020-09-24T11:44:42.000000Z"
+ },
+ {...},
+ {...},
+ {...},
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/categories?limit=5&page=1",
+ "last": "https://example.com/api/categories?limit=5&page=2",
+ "prev": null,
+ "next": "https://example.com/api/categories?limit=5&page=2"
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 2,
+ "path": "https://example.com/api/categories",
+ "per_page": "5",
+ "to": 5,
+ "total": 10
+ }
+ }
+ ~~~
+
+:::
+
+#### 3. Get all categories without pagination
+
+If you don't want to use the pagination and want to access all the store's categories at once, then you have to send a filter parameter named as`pagination` with value `zero`. By doing this you will get all categories objects at once in the data object and this will not give you link and meta objects.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/categories?pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 10,
+ "code": null,
+ "name": "Lights",
+ "slug": "lights",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-24T11:44:42.000000Z",
+ "updated_at": "2020-09-24T11:44:42.000000Z"
+ },
+ {...},
+ {...},
+ {...},
+ {...},
+ {...},
+ {...},
+ {...},
+ {...},
+ {...}
+ ]
+ }
+ ~~~
+
+:::
+
+## Get category by id
+
+For fetching any specific category, you have to provide the category's id as an input parameter.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/categories/{id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---- | ------------- | ------ |
+ | id | Category's id | Number |
+
+### Examples
+
+#### 1. Let's try to fetch category by id
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/categories/6`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 6,
+ "code": null,
+ "name": "Kitchen Appliances",
+ "slug": "kitchen-appliances",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-24T11:42:17.000000Z",
+ "updated_at": "2020-09-24T11:42:17.000000Z"
+ }
+ }
+ ~~~
+
+:::
+
+## Get descendant categories of specific category
+
+This api request will fetch all the descendant categories based on the `parent_id`.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/descendant-categories(?parent_id)`
+
+- Params
+
+ | Name | Info | Type |
+ | --------- | ------------------------------------ | ------ |
+ | parent_id | Parent id of the descendant category | Number |
+
+### Examples
+
+#### 1. Get data based on the `parent_id` which have descendant categories
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/descendant-categories?parent_id=2`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 3,
+ "code": null,
+ "name": "Bike Accessories",
+ "slug": "bike-accessories",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-22T07:16:32.000000Z",
+ "updated_at": "2020-09-24T13:08:21.000000Z"
+ },
+ {
+ "id": 11,
+ "code": null,
+ "name": "Bike Tyres",
+ "slug": "bike-tyres",
+ "display_mode": "products_only",
+ "description": "",
+ "meta_title": "",
+ "meta_description": "",
+ "meta_keywords": "",
+ "status": 1,
+ "image_url": null,
+ "additional": null,
+ "created_at": "2020-09-24T13:20:01.000000Z",
+ "updated_at": "2020-09-24T13:20:01.000000Z"
+ }
+ ]
+ }
+ ~~~
+
+:::
+
+#### 2. Let's try with `parent_id` which have no descendant categories
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/descendant-categories?parent_id=3`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": []
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/customers.md b/docs/1.x/api/customers.md
new file mode 100644
index 00000000..71c111a1
--- /dev/null
+++ b/docs/1.x/api/customers.md
@@ -0,0 +1,524 @@
+# Customers
+
+In this section, we will use all APIs which relates to customer like registration, authentication, details and reset password.
+
+Let's start with registration first,
+
+## Registration
+
+You can create/register a new customer in the Bagisto store. To achieve this task, you can use the `customer/register` API call resource.
+
+- Headers
+
+ | Key | Value |
+ | --------------------- | ---------------- |
+ | Accept | application/json |
+ | Content-Type | application/json |
+
+- Request
+
+ `POST /api/v1/customer/register`
+
+- Params
+
+ | Name | Info | Type |
+ | --------------------- | ---------------- | ------ |
+ | email | Email | String |
+ | first_name | First Name | String |
+ | last_name | Last Name | String |
+ | password | Password | String |
+ | password_confirmation | Confirm Password | String |
+
+### Examples
+
+#### 1. Let's register/create a new customer
+
+- Headers
+
+ | Key | Value |
+ | --------------------- | ---------------- |
+ | Accept | application/json |
+ | Content-Type | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/v1/customer/register`
+
+- Params
+
+ | Name | Value |
+ | --------------------- | ------------------------- |
+ | email | customer@example.com |
+ | first_name | John |
+ | last_name | Doe |
+ | password | customer123 |
+ | password_confirmation | customer123 |
+
+::: details Response
+
+ ~~~json
+ {
+ message: "Your account has been created successfully."
+ }
+ ~~~
+
+:::
+
+#### 2. If customer is already in the Bagisto store with the same email address
+
+Now, hit the above request one more time. Now, we are going to see the following response.
+
+::: details Response
+
+ ~~~json
+ {
+ "message": "The email has already been taken.",
+ "errors": {
+ "email": [
+ "The email has already been taken."
+ ]
+ }
+}
+ ~~~
+
+:::
+
+## Authentication
+
+To authenticate any customer at the Bagisto store, the customer needs to have a valid email address and password.
+
+- Headers
+
+ | Key | Value |
+ | --------------------- | ---------------- |
+ | Accept | application/json |
+ | Content-Type | application/json |
+
+- Request
+
+ Now here is your choice, whether you want to use **JWT API guard** or normal **customer guard**.
+
+ ::: tip
+
+ If you want to know more about the JWT Authentication, please check here [JWT Authentication](./getting-started-with-the-api#_1-jwt-authentication).
+
+ :::
+
+ For JWT API guard, you need to pass the token key in the query string.
+
+ `POST /api/customer/login?token=true`
+
+ For normal customer guard,
+
+ `POST /api/customer/login`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | --------------------- | ------ |
+ | email | Email for customer | String |
+ | password | Password for customer | String |
+
+### Both Examples
+
+#### 1. Let's try the customer authentication with JWT API guard
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/customer/login?token=true`
+
+- Params
+
+ | Key | Value |
+ | -------- | ---------------- |
+ | email | john@example.com |
+ | password | john123 |
+
+::: details Response
+
+ Once you send the request, you will get some random token string that will be used to access the API data.
+
+ ~~~json
+ {
+ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3RcL2RldmVsb3BtZW50XC9iYWdpc3RvLW1hc3RlclwvcHVibGljXC9hcGlcL2N1c3RvbWVyXC9sb2dpbiIsImlhdCI6MTYxMDY5Njk2MSwiZXhwIjoxNjEwNzAwNTYxLCJuYmYiOjE2MTA2OTY5NjEsImp0aSI6IkpuMU9aUWoxd1BVaXlLaHQiLCJzdWIiOjEsInBydiI6IjhmY2EwODhhYmFlMmY5YThmODRhNWYwYmY2YTY1MjQ0OTA1NWJlMDAifQ.6mKgyRgMHxi_W6gf2cgb7Rdcut73L1YEBauYZ8soKSU",
+ "message": "Logged in successfully.",
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+ }
+ ~~~
+
+:::
+
+#### 2. Let's try without token
+
+By removing the token key from request will activate the **customer guard**.
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/customer/login`
+
+- Params
+
+ | Key | Value |
+ | -------- | ---------------- |
+ | email | john@example.com |
+ | password | john123 |
+
+::: details Response
+
+ Once you send the request, then you will get data without token because now the **customer guard** is active.
+
+ ~~~json
+ {
+ "token": true,
+ "message": "Logged in successfully.",
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+ }
+ ~~~
+
+:::
+
+## Details
+
+You can get the customer's details only for the logged-in customer. To retrieve the customer's information you can use the `customer/get` resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/customer/get`
+
+### Examples
+
+Let's fetch the customer data,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/customer/get`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+ }
+ ~~~
+
+:::
+
+## Details by id
+
+You can also get the customer information by using `customer_id` as a request payload. To achieve this, you can use the `customers/{id}` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/customers/{id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---- | ----------- | ------ |
+ | id | Customer ID | Number |
+
+::: warning
+
+ This request will return the current logged in customer's details.
+
+:::
+
+### Examples
+
+Let's fetch the customer data,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/customers/1`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+ }
+ ~~~
+
+:::
+
+## Profile details
+
+To update the current logged in customer's account information, you need to use the `customer/profile` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT /api/customer/profile`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | ------------- | ------ |
+ | first_name | First Name | String |
+ | last_name | Last Name | String |
+ | gender | Gender | String |
+ | date_of_birth | Date Of Birth | Date |
+ | email | E-Mail | String |
+ | password | Password | String |
+
+### Examples
+
+#### 1. Updating current logged in user
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `PUT http(s)://example.com/api/customer/profile`
+
+- Params
+
+ | Name | Value |
+ | ---------- | ---------------- |
+ | first_name | John |
+ | last_name | Doe |
+ | name | John Doe |
+ | email | john@example.com |
+
+::: details Response
+
+ ~~~json
+ {
+ "message": "Your account has been updated successfully.",
+ "data": {...}
+ }
+ ~~~
+
+:::
+
+## Logout
+
+You can logout the customer from the Bagisto store with the help of `customer/logout` resources. No need to provide any request payload in the API call.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/customer/logout`
+
+### Examples
+
+- Request
+
+ `GET http(s)://example.com/api/customer/logout`
+
+::: details Response
+
+ ~~~json
+ {
+ "message": "Logged out successfully!"
+ }
+ ~~~
+
+:::
+
+## Reset password
+
+You can also use the API to reset the customer's password by providing the valid customer's email address. In this API request, you have to use the `customer/forgot-password` resource with `email` as a request payload. An email will be sent on the provided email address, only if the same email address exists in the Bagisto store.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST /api/customer/forgot-password`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | ----- | ------ |
+ | email | Email | String |
+
+### Examples
+
+#### 1. Let's try the customer forgot password request
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/customer/forgot-password`
+
+- Params
+
+ | Name | Value |
+ | ----- | ---------------- |
+ | email | john@example.com |
+
+::: details Response
+
+ ~~~json
+ {
+ "message": "We have e-mailed your password reset link!"
+ }
+ ~~~
+
+:::
+
+#### 2. In case you provide an invalid or unregistered email address, then no email will be sent to the provided email address
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/customer/forgot-password`
+
+- Params
+
+ | Name | Value |
+ | ----- | ----------------- |
+ | email | peter@example.com |
+
+::: details Response
+
+ ~~~json
+ {
+ "error": "We can't find a user with that e-mail address."
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/explanation.md b/docs/1.x/api/explanation.md
new file mode 100644
index 00000000..2a3fd87f
--- /dev/null
+++ b/docs/1.x/api/explanation.md
@@ -0,0 +1,63 @@
+# Explanation
+
+If you check all the sections in which we have used pagination, in all the responses, you will find that there are three objects key i.e. `data`, `links`, and `meta`. In this section, we will explain all the three keys.
+
+Let's take an example of the categories section, we have some response in which we got these three keys.
+
+~~~json
+{
+ "data": [{...},{...},...,{...}],
+ "links": {...},
+ "meta": {...}
+}
+~~~
+
+## 1. Data Object `data`
+
+In the data object key, you will find the collection of many objects which represent the Bagisto store's categories.
+
+## 2. Links Object `links`
+
+In the links object, you will find four more object keys, which will be used according to pagination,
+
+ ~~~json
+ "links": {
+ "first": "https://example.com/api/categories?limit=5&pagination=342234&page=1",
+ "last": "https://example.com/api/categories?limit=5&pagination=342234&page=2",
+ "prev": null,
+ "next": "https://example.com/api/categories?limit=5&pagination=342234&page=2"
+ }
+ ~~~
+
+ | Name | Info |
+ | ------------- | ------------------------------------------------------------------------------------------------------------------- |
+ | first | Display the first url link of the called API with filter variable. |
+ | last | Display the last url link of the called API with filter variable. |
+ | prev | Display the previous url of the current called API url. |
+ | next | Display the next url of the current called API url. If no next url available then it will contain the `null` value. |
+
+## 3. Meta Object `meta`
+
+`meta` object will only used with pagination. Under meta object, you will find seven object keys,
+
+ ~~~json
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 2,
+ "path": "https://example.com/api/categories",
+ "per_page": "5",
+ "to": 5,
+ "total": 10
+ }
+ ~~~
+
+ | Name | Info |
+ | ------------- | -------------------------------------------------------------------------------------------------- |
+ | current_page | Display the current page number. |
+ | from | Display the first count of the returned data object based on the provided page and limit filters. |
+ | last_page | Display the last page number. |
+ | path | Display the current api url without input parameters. |
+ | per_page | Display the total of records in a single page. |
+ | to | Display the last count of the returned data object based on the provided page and limit filters. |
+ | total | Display the total number of records in the store. |
\ No newline at end of file
diff --git a/docs/1.x/api/getting-started-with-the-api.md b/docs/1.x/api/getting-started-with-the-api.md
new file mode 100644
index 00000000..d3925186
--- /dev/null
+++ b/docs/1.x/api/getting-started-with-the-api.md
@@ -0,0 +1,200 @@
+# Authentication
+
+[[toc]]
+
+## Introduction
+
+By default the [Bagisto](https://bagisto.com) API makes use of the [JWT package](https://jwt.io/) for token-based authentication.
+You can however choose either if you want to authenticate via. **JWT API guard** or with the normal **customer guard**.
+When you are going through the api documentation, you will see one of the examples i.e. with or without tokens. Let discuss both of them.
+
+## Auth Guards
+
+::: warning
+You are required to send a valid **User Agent** header in your request.
+:::
+
+### JWT Authentication
+
+To activate the **JWT** authentication, you just need to pass one extra key-value pair in your request i.e. `token=true`.
+
+ | Key | Value |
+ | ----- | ----- |
+ | token | true |
+
+This will tell the Bagisto api to use the **JWT API guard**. If you are not passing this, the normal **customer guard** will be activated.
+
+So, let's try to authenticate the user by using **JWT**. Please send valid **User Agent** header in your request whether you are using postman, curl or some other clients.
+
+::: tip Reminder
+
+ Here we are showing just a sample of API for the usage of **JWT** token. If you are familiar with all these things you can start with the [Customer](./customers) API section.
+
+:::
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/customer/login?token=true`
+
+- Params
+
+ | Key | Value |
+ | -------- | ---------------- |
+ | email | john@example.com |
+ | password | john123 |
+
+- Response
+
+ - Once you send the request, you will get some random token string that will be used to access the API data.
+
+ ~~~json
+ {
+ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3RcL2RldmVsb3BtZW50XC9iYWdpc3RvLW1hc3RlclwvcHVibGljXC9hcGlcL2N1c3RvbWVyXC9sb2dpbiIsImlhdCI6MTYxMDY5Njk2MSwiZXhwIjoxNjEwNzAwNTYxLCJuYmYiOjE2MTA2OTY5NjEsImp0aSI6IkpuMU9aUWoxd1BVaXlLaHQiLCJzdWIiOjEsInBydiI6IjhmY2EwODhhYmFlMmY5YThmODRhNWYwYmY2YTY1MjQ0OTA1NWJlMDAifQ.6mKgyRgMHxi_W6gf2cgb7Rdcut73L1YEBauYZ8soKSU",
+ "message": "Logged in successfully.",
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+ }
+ ~~~
+
+### Customer Guard
+
+By removing the token key from your request the **customer guard** will be activated.
+
+#### Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST http(s)://example.com/api/customer/login`
+
+#### Params
+
+ | Key | Value |
+ | -------- | ---------------- |
+ | email | john@example.com |
+ | password | john123 |
+
+#### Response
+
+Once you send the request, you will get data without any token because now the **customer guard** is active.
+
+~~~json
+{
+ "token": true,
+ "message": "Logged in successfully.",
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+}
+~~~
+
+## Accessing Data
+
+Once you are authenticated, try to access the current customer data by using **JWT**, use the customer API endpoint for this,
+
+::: tip
+
+Here we are just showing a example of how to collect data from the API with the usage of a **JWT** token.
+If you are familiar with all these things you can start with the [Customer](./customers) API section.
+
+:::
+
+#### Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+::: tip
+
+As you check the **JWT** authentication we got some token string, we just need to put that token in the request header. For e.g.,
+
+~~~request-header
+ Accept:application/json
+ Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
+~~~
+
+:::
+
+#### Request
+
+ `GET http(s)://example.com/api/customer/get?token=true`
+
+::: details Response
+
+~~~json
+{
+ "data": {
+ "id": 1,
+ "email": "john@example.com",
+ "first_name": "John",
+ "last_name": "Doe",
+ "name": "John Doe",
+ "gender": null,
+ "date_of_birth": null,
+ "phone": null,
+ "status": 1,
+ "group": {
+ "id": 2,
+ "name": "General",
+ "created_at": null,
+ "updated_at": null
+ },
+ "created_at": "2020-09-28T05:13:42.000000Z",
+ "updated_at": "2020-09-28T05:13:42.000000Z"
+ }
+}
+~~~
+
+:::
+
+If you don't want to use **JWT**, then just remove the token key from the query string.
+
+::: warning
+
+ You have to re-login again to access without the **JWT** token because currently it will use the **customer guard**.
+
+:::
diff --git a/docs/1.x/api/invoices.md b/docs/1.x/api/invoices.md
new file mode 100644
index 00000000..fe4d0828
--- /dev/null
+++ b/docs/1.x/api/invoices.md
@@ -0,0 +1,258 @@
+# Invoices
+
+In this section, we will check all the invoices' API.
+
+## Get invoices from all orders
+
+You can get all the invoices for the Bagisto store's orders. To get the invoices of the store, the customer must be logged-in to the Bagisto store. You can achieve this job by using the `invoices` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/invoices(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get invoices with pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/invoices?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/invoices`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 8,
+ "state": "paid",
+ "email_sent": 0,
+ "total_qty": 4,
+ "sub_total": "190.0000",
+ "base_sub_total": "190.0000",
+ "grand_total": "230.0000",
+ "order_address": {...},
+ "transaction_id": null,
+ "items": [
+ {...},
+ {...}
+ ],
+ },
+ {...},
+ ...
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/invoices?page=1",
+ "last": "https://example.com/api/invoices?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {...}
+ }
+ ~~~
+
+:::
+
+#### 2. Get all invoices without pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/invoices?pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 8,
+ "state": "paid",
+ "email_sent": 0,
+ "total_qty": 4,
+ "sub_total": "190.0000",
+ "base_sub_total": "190.0000",
+ "grand_total": "230.0000",
+ "order_address": {...},
+ "transaction_id": null,
+ "items": [
+ {...},
+ {...}
+ ],
+ },
+ {...},
+ ...
+ {...}
+ ]
+ }
+ ~~~
+
+:::
+
+## Get invoices by order's id
+
+To get the details of a specific order's invoice, you have to pass an `order_id` as a query parameter like `invoices?order_id={id}` in API URL. By using this resource and query parameter, you will get only a single invoice detail regarding the provided `order_id` in response.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/invoices(?order_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | -------------------------------------------- | ------ |
+ | order_id | Order's ID | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. Get all invoices by order's id
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/invoices?order_id=3&pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 1,
+ "state": "paid",
+ "email_sent": 0,
+ "total_qty": 2,
+ "sub_total": "60.0000",
+ "grand_total": "80.0000",
+ "shipping_amount": "20.0000",
+ "items": [
+ {...},
+ {...}
+ ],
+ }
+ ]
+ }
+ ~~~
+
+:::
+
+## Get invoice by id
+
+To get the details of a specific invoice, you have to pass an `invoice_id` as a request payload in API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/invoices/{invoice_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ------------- | ------------ | ------ |
+ | invoice_id | Invoice's ID | Number |
+
+### Examples
+
+#### 1. Let's fetch specific invoice
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/invoices/2`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 2,
+ "state": "paid",
+ "email_sent": 0,
+ "total_qty": 4,
+ "sub_total": "190.0000",
+ "grand_total": "230.0000",
+ "shipping_amount": "40.0000",
+ "tax_amount": "0.0000",
+ "discount_amount": "0.0000",
+ "order_address": {...},
+ "transaction_id": null,
+ "items": [
+ {...},
+ {...}
+ ],
+ }
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/locales.md b/docs/1.x/api/locales.md
new file mode 100644
index 00000000..4094cf72
--- /dev/null
+++ b/docs/1.x/api/locales.md
@@ -0,0 +1,227 @@
+# Locales
+
+In this section, we will see all the APIs which are related to locales.
+
+## Get all locales
+
+You can get all the locales from the Bagisto store. You can achieve this job by using the `locales` API call resource.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/locales(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Records for specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/locales?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/locales`
+
+ :::
+
+::: details Response
+
+~~~json
+{
+ "data": [
+ {
+ "id": 4,
+ "code": "tr",
+ "name": "Türkçe",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 3,
+ "code": "nl",
+ "name": "Dutch",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 2,
+ "code": "fr",
+ "name": "French",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 1,
+ "code": "en",
+ "name": "English",
+ "created_at": null,
+ "updated_at": null
+ }
+ ],
+ "links": {
+ "first": "https://example.com/api/locales?page=1",
+ "last": "https://example.com/api/locales?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "links": [
+ {
+ "url": null,
+ "label": "« Previous",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/locales?page=1",
+ "label": "1",
+ "active": true
+ },
+ {
+ "url": null,
+ "label": "Next »",
+ "active": false
+ }
+ ],
+ "path": "https://example.com/api/locales",
+ "per_page": 10,
+ "to": 4,
+ "total": 4
+ }
+}
+~~~
+
+:::
+
+#### 2. Get all locales without pagination
+
+You can also get all the locales at once from the Bagisto store without pagination. For this, you have to pass `pagination=0` in the query parameter with the `locales` resource in the API URL.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/public/api/locales?pagination=0`
+
+::: details Response
+
+~~~json
+{
+ "data": [
+ {
+ "id": 4,
+ "code": "tr",
+ "name": "Türkçe",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 3,
+ "code": "nl",
+ "name": "Dutch",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 2,
+ "code": "fr",
+ "name": "French",
+ "created_at": null,
+ "updated_at": null
+ },
+ {
+ "id": 1,
+ "code": "en",
+ "name": "English",
+ "created_at": null,
+ "updated_at": null
+ }
+ ]
+}
+~~~
+
+:::
+
+## Get locale by id
+
+To get the specific locale details, you have to pass an `locale_id` as a request payload in the API URL.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/locales/{locale_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | --------- | ----------- | ------ |
+ | locale_id | Locale's ID | Number |
+
+### Examples
+
+Let's fetch specific locale,
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/locales/1`
+
+::: details Response
+
+~~~json
+{
+ "data": {
+ "id": 1,
+ "code": "en",
+ "name": "English",
+ "created_at": null,
+ "updated_at": null
+ }
+}
+~~~
+
+:::
diff --git a/docs/1.x/api/orders.md b/docs/1.x/api/orders.md
new file mode 100644
index 00000000..37766893
--- /dev/null
+++ b/docs/1.x/api/orders.md
@@ -0,0 +1,355 @@
+# Orders
+
+In this section, we will see all the APIs which are related to order. As after order placement tracking of order is also important.
+
+## Get all orders
+
+You can get all the orders of the Bagisto store. To get the orders of the store, the customer must be logged in to the Bagisto Store. You can achieve this job by using `orders` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/orders(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Records for specific page
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/orders?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/orders`
+
+ :::
+
+::: details Response
+
+```json
+{
+ "data": [
+ {...},
+ {...},
+ ...
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/orders?page=1",
+ "last": "https://example.com/api/orders?page=2",
+ "prev": null,
+ "next": "https://example.com/api/orders?page=2"
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 2,
+ "path": "https://example.com/api/orders",
+ "per_page": 10,
+ "to": 10,
+ "total": 11
+ }
+}
+```
+
+:::
+
+#### 2. Records for specific page with limit
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/public/api/orders?limit=5&page=2`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {...},
+ {...},
+ {...},
+ {...},
+ {...}
+ ]
+ "links": {
+ "first": "https://example.com/api/orders?limit=5&page=1",
+ "last": "https://example.com/api/orders?limit=5&page=3",
+ "prev": "https://example.com/api/orders?limit=5&page=1",
+ "next": "https://example.com/api/orders?limit=5&page=3"
+ },
+ "meta": {
+ "current_page": 2,
+ "from": 6,
+ "last_page": 3,
+ "path": "https://example.com/api/orders",
+ "per_page": "5",
+ "to": 10,
+ "total": 11
+ }
+}
+```
+
+:::
+
+#### 3. Get all orders without pagination,
+
+You can also get all the orders at once from the Bagisto store without pagination. To get the orders, the customer must be logged in to the Bagisto store. For this, you have to pass `pagination=0` in the query parameter with the `orders` resource in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/public/api/orders?pagination=0`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {...},
+ {...},
+ {...},
+ ...
+ {...}
+ ]
+}
+```
+
+![bagisto_orders_no_pag](../../assets/1.x/images/api/bagisto_orders_no_pag.jpg){:class="screenshot-dimension center"}
+
+:::
+
+## Get order by id
+
+To get the specific order details, you have to pass an `order_id` as a request payload in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/orders/{order_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | -------- | ---------- | ------ |
+ | order_id | Order's ID | Number |
+
+### Examples
+
+Let's fetch specific order,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/order/3`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 3,
+ "status": "pending",
+ "status_label": "Pending",
+ "channel_name": "Default",
+ "customer_email": "peterdoe@example.com",
+ "customer_first_name": "Peter",
+ "customer_last_name": "Doe",
+ "shipping_method": "flatrate_flatrate",
+ "shipping_title": "Flat Rate - Flat Rate",
+ "payment_title": "Cash On Delivery",
+ "total_qty_ordered": 2,
+ "grand_total": "80.0000",
+ "customer": {...},
+ "shipping_address": {...},
+ "billing_address": {...},
+ "items": [
+ {...},
+ {...}
+ ],
+ "invoices": [],
+ "shipments": [],
+ }
+ }
+}
+```
+
+![bagisto_orders_id](../../assets/1.x/images/api/bagisto_orders_id.jpg)
+
+:::
+
+## Get orders by customer's id
+
+To get all the orders of a specific customer, you have to pass a `customer_id` as a query parameter like `orders?customer_id={id}` in API URL. To use this API call customer authentication is required means that customers must be logged-in to the store.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/public/api/orders(?customer_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------- | -------------------------------------------- | ------ |
+ | customer_id | Cutomer's ID | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. To get all the results without pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/public/api/orders?customer_id=2&pagination=0`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 3,
+ "status": "pending",
+ "customer_email": "peterdoe@webkul.com",
+ "customer_first_name": "Peter",
+ "customer_last_name": "Doe",
+ "shipping_method": "flatrate_flatrate",
+ "shipping_title": "Flat Rate - Flat Rate",
+ "payment_title": "Cash On Delivery",
+ "total_qty_ordered": 2,
+ "grand_total": "80.0000",
+ "customer": {...},
+ "shipping_address": {...},
+ "billing_address": {...},
+ "items": [{...},{...},{...}],
+ },
+ {
+ "id": 2,
+ "status": "pending",
+ "customer_email": "peterdoe@webkul.com",
+ "customer_first_name": "Peter",
+ "customer_last_name": "Doe",
+ "shipping_method": "flatrate_flatrate",
+ "shipping_title": "Flat Rate - Flat Rate",
+ "payment_title": "Cash On Delivery",
+ "total_qty_ordered": 5,
+ "grand_total": "400.0000",
+ "customer": {...},
+ "shipping_address": {...},
+ "billing_address": {...},
+ "items": [{...},{...},{...}],
+ }
+ ]
+}
+```
+
+:::
+
+#### 2. Get all orders by customer's id with pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/orders?customer_id=2&limit=5&page=1`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/orders?customer_id=2&limit=1&page=1",
+ "last": "https://example.com/api/orders?customer_id=2&limit=1&page=1",
+ "prev": "https://example.com/api/orders?customer_id=2&limit=1&page=1",
+ "next": null
+ },
+ "meta": {
+ "current_page": 2,
+ "from": 2,
+ "last_page": 2,
+ "path": "https://example.com/api/orders",
+ "per_page": "1",
+ "to": 2,
+ "total": 2
+ }
+}
+```
+
+:::
diff --git a/docs/1.x/api/products.md b/docs/1.x/api/products.md
new file mode 100644
index 00000000..21cb91f2
--- /dev/null
+++ b/docs/1.x/api/products.md
@@ -0,0 +1,506 @@
+# Products
+
+In this section, we will use the product's API. We will start with the fetching of all products. Then we will move forward to query params and filterable query params. In last, we will check the additional and variant information.
+
+## Get all products
+
+This request will fetch all the products based on `limit` and `page`.
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `/api/products(?limit,page)`
+
+ ::: tip
+
+ If you didn't use the page(?page=x) filter, then it returns the data of the first page by default.
+
+ :::
+
+- Params
+
+ | Name | Info | Type |
+ | ----- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+
+::: tip
+
+If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get products for specific page
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `http(s)://example.com/api/products?page=1`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 3,
+ "type": "simple",
+ "name": "Lenovo IdeaPad Yoga 500 15 Hybrid (2-in-1) White",
+ "url_key": "lenovo-ideapad-yoga-500-15-hybrid-2-in-1-white",
+ "price": "600.0000",
+ "formated_price": "$600.00",
+ ...
+ "sku": "5626",
+ "images": [
+ {...}
+ ],
+ "base_image": {...},
+ "variants": [],
+ "in_stock": true,
+ "reviews": {...},
+ "is_saved": false,
+ "created_at": "2020-09-09 03:31:47",
+ "updated_at": "2020-09-09 03:31:47"
+ },
+ {...},
+ {...}
+ ],
+ "links": {...},
+ "meta": {...}
+}
+```
+
+:::
+
+#### 2. Get products for specific page with limit
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `http(s)://example.com/api/products?limit=2&page=1`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {...},
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/products?page=1&limit=2",
+ "last": "https://example.com/api/products?page=4&limit=2",
+ "prev": null,
+ "next": "https://example.com/api/products?page=2&limit=2"
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 4,
+ "path": "https://example.com/api/products",
+ "per_page": "2", // limit
+ "to": 2,
+ "total": 8
+ }
+}
+```
+
+:::
+
+## Get products with query parameters
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/products(?category_id,new,featured,name,sku,url_key,limit,page)`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------- | ---------------- | ------- |
+ | category_id | Category's ID | Number |
+ | new | New Product | Boolean |
+ | featured | Featured Product | Boolean |
+ | name | Name | String |
+ | sku | SKU | String |
+ | url_key | URL Key | String |
+ | limit | Limit | Number |
+ | page | Page | Number |
+
+### Examples
+
+#### 1. If you want to get the store's products those are having new condition then you can use `new=1` in the query parameter and if want to get the products without new condition then use `new=0`
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?new=1`
+
+#### 2. You can also use the `limit` and `page` query parameters with the `new` query parameter
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?new=1&limit=5&page=1`
+
+ `GET http(s)://example.com/api/products?new=0&limit=5&page=1`
+
+#### 3. If you want to get the store's products those are featured then you can use `featured=1` query parameter
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?featured=1`
+
+#### 4. You can also use the `limit` and `page` in query parameters with `featured` query parameter
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?featured=1&limit=5&page=1`
+
+ `GET http(s)://example.com/api/products?featured=0&limit=5&page=1`
+
+#### 5. Suppose you want to find out the data of your product in the Bagisto store, here you can use the `name` query parameter. You have to provide the product name to the `name` query parameter in the API URL
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?name='Leather Shoes'`
+
+#### 6. You can also get your product-related details with the help of the product's SKU. SKU will be unique for each product in the Bagisto store. For this, you have to use `sku` as a query parameter in the API URL
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?sku='1234'`
+
+#### 7. `url_key` is a unique field for every product in Bagisto Store. You can also find out product details by using `url_key`. For this, you have to pass `url_key` as a query parameter in the API URL
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?url_key='leather-shoes'`
+
+## Get products with filterable query parameters
+
+You can also filter your store products by using filterable attributes query parameters. These filters will only work with the `category_id` input query parameter. There are two system-defined filterable attributes in the Bagisto E-commerce framework i.e. `size` and `color`. Admin user can also create their own custom attribute and can make these custom attributes as filterable. By using these filterable attributes, customers can filter the category's products to get the desired result.
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products(?category_id,size,color,price)`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------- | ------------- | ------ |
+ | category_id | Category's ID | Number |
+ | size | Size | String |
+ | color | Color | String |
+ | price | Price | String |
+
+### Examples
+
+#### 1. You can filter Bagisto's product catalog with the help of `size` filter. `size` filter will work only on the category layout. You can pass the multiple attribute's values to the `size` filterable attributes as a query parameter in API url. Suppose you want to filter men's T-Shirt with medium and large size, then you can pass the id of both medium & large
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&size=6,7`
+
+#### 2. You can also use the limit and page in query parameters with category & size filterable parameters
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&size=6,7&limit=10&page=1`
+
+ ![Bagisto Product Size](../../assets/1.x/images/api/bagisto_prod_size.jpg)
+
+#### 3. You can also filter the Bagisto product catalog with the help of `color` filter. `color` filter will work only on the category layout. You can pass the multiple attribute's values to the color`s filterable attributes as a query parameter in API URL. Suppose you want to filter men's T-Shirt with white and red color, then you can pass the id of both white & red
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&color=1,2`
+
+#### 4. You can also use the limit and page in query parameters with category & color filterable parameters
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&color=1,2&limit=10&page=1`
+
+ ![Bagisto Product Color](../../assets/1.x/images/api/bagisto_prod_color.jpg)
+
+#### 5. In the case of a simple product, You can set a range of a minimum price and maximum price. Same as `size` and `color`, the `price` filter will also work on the category layout only. Suppose you want to filter products those are having price between price range from 50 to 100, then you have to pass value like `price=10,50` as the query parameter in API URL
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&price=50,100`
+
+#### 6. You can also use the `limit` and `page` in query parameters with `category` & `price` filterable parameters
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&price=50,100&limit=10&page=1`
+
+ ![Bagisto Product Price Simple](../../assets/1.x/images/api/bagisto_prod_price_simple.jpg)
+
+#### 7. In the case of a configurable product, the `price` filter will also work with the product's variants. Suppose you want to filter products with the 40$ min and 100$ max price range. And there is a configurable product named men's T-shirts having a price 30$ and there is any variant of the same product having 45$ price, then men's T-shirts product will show you in the filtered product's list
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products?category_id=2&price=30,100`
+
+ ![Bagisto Product Price Config](../../assets/1.x/images/api/bagisto_prod_price_config.jpg)
+
+::: tip
+
+The above-explained filter query parameters (i.e. size, color, price) can be used together.
+
+:::
+
+## Get product by id
+
+If you want the record of any specific product, then you have to provide the product id as an input parameter in the API URL.
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/products/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ------------ | ------ |
+ | product_id | Product's ID | Number |
+
+### Examples
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/products/1`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 1,
+ "type": "simple",
+ "name": "Adorable Cream Teddy Bear",
+ "url_key": "adorable-cream-teddy-bear",
+ "price": "10.0000",
+ "formated_price": "$10.00",
+ "short_description": "
Buy Adorable Cream Teddy Bear online at best price
",
+ "description": "
Buy Adorable Cream Teddy Bear online at best price
",
+ "sku": "80971254",
+ "images": [
+ {...}
+ ],
+ "base_image": {...},
+ "variants": [],
+ "in_stock": true,
+ "reviews": {...},
+ "is_saved": false,
+ "created_at": "2020-09-08T23:52:02.000000Z",
+ "updated_at": "2020-09-08T23:52:02.000000Z"
+ }
+}
+```
+
+:::
+
+## Get product's additional information
+
+Additional information relates to all the attributes and their values for which admin sets the `Yes` value for the `Visible on Product View Page on Front-end`. The product's additional information means those attributes which describe the product's specification.
+
+![Bagisto Attribute](../../assets/1.x/images/api/bagisto_attribute.jpg)
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/product-additional-information/1`
+
+::: details Response
+
+![Bagisto Additional Info](../../assets/1.x/images/api/bagisto_add_info.jpg)
+
+:::
+
+## Get product's variants information
+
+You can get all the configurable attributes of a product by using `product-configurable-config` resource in API calls. It will return all the variants of a product with their `label`, `options`, `regular_price` and `final_price` also.
+
+Admin can set the `Yes` value for the `Use To Create Configurable Product` field under the attribute panel to make that attribute as variant.
+
+![Bagisto Config](../../assets/1.x/images/api/bagisto_config.jpg)
+
+- Headers
+
+ | Key | Value |
+ | ------ | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET http(s)://example.com/api/product-configurable-config/1`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "attributes": [
+ {
+ "id": 24,
+ "code": "size",
+ "label": "Size",
+ "swatch_type": null,
+ "options": [
+ {
+ "id": 7,
+ "label": "M",
+ "swatch_value": null,
+ "products": [4]
+ }
+ ]
+ }
+ ],
+ "variant_prices": {
+ "4": {
+ "regular_price": {
+ "formated_price": "$45.00",
+ "price": 45
+ },
+ "final_price": {
+ "formated_price": "$45.00",
+ "price": 45
+ }
+ }
+ }
+ }
+}
+```
+
+![Bagisto Config Attributes](../../assets/1.x/images/api/bagisto_config_attr.jpg)
+
+:::
diff --git a/docs/1.x/api/reviews.md b/docs/1.x/api/reviews.md
new file mode 100644
index 00000000..04abae40
--- /dev/null
+++ b/docs/1.x/api/reviews.md
@@ -0,0 +1,495 @@
+# Reviews
+
+In this section, we will check all the reviews' API based on customers as well as products. Also we will see how to create a review.
+
+## Get all reviews
+
+You can get all the reviews of the Bagisto store. You can achieve this job by using `reviews` API call resource. There is no need of customer authentication.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/reviews(?page,limit,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get reviews for specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews?page=1`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 10,
+ "title": "Awesome Product & Service ",
+ "rating": "3.0",
+ "comment": "Awesome Product & Service ",
+ "name": "John Doe",
+ "status": "approved",
+ },
+ {
+ "id": 9,
+ "title": "Awesome Product Quality",
+ "rating": "4.0",
+ "comment": "Awesome Product Quality",
+ "name": "John Doe",
+ "status": "approved",
+ },
+ {...},
+ {...},
+ ],
+ "links": {
+ "first": "https://example.com/api/reviews?page=1",
+ "last": "https://example.com/api/reviews?page=2",
+ "prev": null,
+ "next": null
+ },
+ "meta": {...}
+ }
+ ~~~
+
+:::
+
+#### 2. Get all reviews without pagination
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews?pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 6,
+ "title": "Great product & Service!!!",
+ "rating": "4.0",
+ "comment": "Beautiful bangles. Better than I expected.",
+ "name": "John Doe",
+ "status": "approved",
+ },
+ {
+ "id": 5,
+ "title": "Very good product.. Recommend to all",
+ "rating": "5.0",
+ "comment": "I have ordered 2 sets. The product i received was good, i loved it.",
+ "name": "Peter Doe",
+ "status": "approved",
+ },
+ {
+ "id": 4,
+ "title": "Awesome Product & Service ",
+ "rating": "3.0",
+ "comment": "Awesome Product & Service ",
+ "name": "John Doe",
+ "status": "approved",
+ },
+ {...},
+ {...},
+ {...}
+ ]
+ }
+ ~~~
+
+:::
+
+## Get review by id
+
+To get the specific review detail, you have to pass a review id i.e. `id` as a request payload like `reviews/{id}` in API URL.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/reviews/{id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---- | ------------ | ------ |
+ | id | Review's ID. | Number |
+
+### Examples
+
+#### 1. Get specific review by id
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews/2`
+
+- Response
+
+ ~~~json
+ {
+ "data": {
+ "id": 2,
+ "title": "Awesome Product & Service ",
+ "rating": "3.0",
+ "comment": "Awesome Product & Service ",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...}
+ }
+ }
+ ~~~
+
+## Get reviews by customer's id
+
+This request will fetch all the reviews by customer's id.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/reviews(?customer_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------- | -------------------------------------------- | ------ |
+ | customer_id | Customer's ID. | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. Get data of the specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews?customer_id=1&page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET https://example.com/api/reviews?customer_id=1`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ {
+ "data": [
+ {
+ "id": 4,
+ "title": "Good Product",
+ "rating": "5.0",
+ "comment": "Nice...",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...},
+ },
+ {
+ "id": 3,
+ "title": "Value For Money",
+ "rating": "5.0",
+ "comment": "Very nice product. Made with good quality.",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...},
+ }
+ {
+ "id": 2,
+ "title": "Great product & Service!!!",
+ "rating": "4.0",
+ "comment": "Beautiful bangles. Better than I expected.",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...}
+ },
+ {
+ "id": 1,
+ "title": "Awesome Product & Service ",
+ "rating": "3.0",
+ "comment": "Awesome Product & Service ",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...}
+ },
+ ],
+ "links": {
+ "first": "https://example.com/api/reviews?customer_id=1&page=1",
+ "last": "https://example.com/api/reviews?customer_id=1&page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {...}
+ }
+ }
+ ~~~
+
+:::
+
+#### 2. Get all customer's reviews without pagination
+
+You can also get all customer's reviews of Bagisto Store in a single API call without using pagination. For this you have to pass `pagination=0` in the query parameter with the `reviews?customer_id={id}` resource in the API URL.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews?customer_id=1&pagination=0`
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 4,
+ "title": "Good Product",
+ "rating": "5.0",
+ "comment": "Nice...",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...},
+ },
+ {
+ "id": 3,
+ "title": "Value For Money",
+ "rating": "5.0",
+ "comment": "Very nice product. Made with good quality.",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...},
+ }
+ {
+ "id": 2,
+ "title": "Great product & Service!!!",
+ "rating": "4.0",
+ "comment": "Beautiful bangles. Better than I expected.",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...}
+ },
+ {
+ "id": 1,
+ "title": "Awesome Product & Service ",
+ "rating": "3.0",
+ "comment": "Awesome Product & Service ",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ "customer": {...}
+ }
+ ]
+ }
+ ~~~
+
+:::
+
+## Get review by product's id
+
+To get all the reviews of a specific product, you have to pass a `product_id` as a query parameter like `reviews?product_id={id}` in API URL. To use this API call customer authentication is not required.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET /api/reviews(?product_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | product_id | Product's ID. | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. Get data of the specific page
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `GET https://example.com/api/reviews?product_id=1&page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET https://example.com/api/reviews?product_id=1`
+
+ :::
+
+::: details Response
+
+ ~~~json
+ {
+ "data": [
+ {
+ "id": 4,
+ "title": "Great product & Service!!!",
+ "rating": "4.0",
+ "comment": "Beautiful bangles. Better than I expected.",
+ "name": "John Doe",
+ "status": "approved",
+ "product": {...},
+ },
+ {
+ "id": 3,
+ "title": "Very good product.. Recommend to all",
+ "rating": "5.0",
+ "comment": "I have ordered 2 sets. The product i received was good, i loved it..",
+ "name": "Peter Doe",
+ "status": "approved",
+ "product": {...},
+ }
+ ],
+ "links": {...},
+ "meta": {...}
+ }
+ ~~~
+
+:::
+
+## Create products's review
+
+To post a review of a specific product, you have to login as a customer.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST /api/reviews/{product_id}/create`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ------------------------------ | ------ |
+ | product_id | Product's ID. | Number |
+ | rating | Specify rating of the product. | Number |
+ | title | Title for review. | String |
+ | comment | Comments for review. | String |
+
+### Examples
+
+#### 1. Creating review for the product
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Request
+
+ `POST https://example.com/api/reviews/1/create`
+
+- Params
+
+ | Name | Value |
+ | ---------- | --------------------- |
+ | rating | 5 |
+ | title | Awesome Product |
+ | comment | Good quality product. |
+
+::: details Response
+
+ ~~~json
+ {
+ "message": "Your review submitted successfully.",
+ "data": {
+ "id": 6,
+ "title": "Awesome Product",
+ "rating": "5.0",
+ "comment": "Good quality product.",
+ "name": "John Doe",
+ "status": "pending",
+ "product": {...},
+ "customer": {...},
+ "created_at": "2020-09-28T14:27:27.000000Z",
+ "updated_at": "2020-09-28T14:27:27.000000Z"
+ }
+ }
+ ~~~
+
+:::
diff --git a/docs/1.x/api/shipments.md b/docs/1.x/api/shipments.md
new file mode 100644
index 00000000..4b46772b
--- /dev/null
+++ b/docs/1.x/api/shipments.md
@@ -0,0 +1,286 @@
+# Shipments
+
+In this section, we will check all the shipments' API.
+
+## Get shipments from all orders
+
+You can get all the shipments of the Bagisto store. To get the shipments of the store, the customer must be logged in to the Bagisto store. You can achieve this job by using the `shipments` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/shipments(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get all shipments with pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/shipments`
+
+ :::
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "total_qty": 2,
+ "total_weight": null,
+ "carrier_title": "DHL Shipping",
+ "track_number": "1234566",
+ "customer": {...},
+ "inventory_source": {
+ "id": 1,
+ "name": "Default",
+ "contact_name": "Detroit Warehouse",
+ "contact_email": "warehouse@example.com",
+ "contact_number": "1234567899",
+ "country": "US",
+ "state": "MI",
+ "city": "Detroit",
+ "street": "12th Street",
+ "postcode": "48127",
+ },
+ "items": [{...},{...}]
+ }
+ ],
+ "links": {...},
+ "meta": {...}
+}
+```
+
+![bagisto_shipments](../../assets/1.x/images/api/bagisto_shipments.jpg)
+
+:::
+
+#### 2. Get all shipments without pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments?pagination=0`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "total_qty": 2,
+ "total_weight": null,
+ "carrier_title": "DHL Shipping",
+ "track_number": "1234566",
+ "customer": {...},
+ "inventory_source": {
+ "id": 1,
+ "name": "Default",
+ "contact_name": "Detroit Warehouse",
+ "contact_email": "warehouse@example.com",
+ "contact_number": "1234567899",
+ "country": "US",
+ "state": "MI",
+ "city": "Detroit",
+ "street": "12th Street",
+ "postcode": "48127",
+ },
+ "items": [{...},{...}]
+ },
+ {...},
+ {...},
+ {...},
+ ...
+ {...}
+ ]
+}
+```
+
+:::
+
+## Get shipments by order's id
+
+To get the details of a specific order's shipment, you have to pass an `order_id` as a query parameter in API URL. By using this resource and query parameter, you will get only a single shipment detail in API response based on the provided `order_id`.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/shipments(?order_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | order_id | Order's ID | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. Get all shipments by order's id
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments?order_id=3&pagination=0`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 1,
+ "total_qty": 2,
+ "total_weight": null,
+ "carrier_code": null,
+ "carrier_title": "DHL Shipping",
+ "track_number": "1234566",
+ "customer": {...},
+ "inventory_source": {...},
+ "items": [
+ {...},
+ {...}
+ ]
+ }
+ ],
+}
+```
+
+:::
+
+#### 2. Get all shipments by order's id for specific page
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments?order_id=3&page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/shipments?order_id=3`
+
+ :::
+
+::: details Response
+
+![bagisto_ship_order_id](../../assets/1.x/images/api/bagisto_ship_order_id.jpg)
+
+:::
+
+## Get shipment by id
+
+To get the details of a specific shipment, you have to pass a `shipment_id` as a request payload in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments/{id}`
+
+### Examples
+
+#### 1. Let's fetch specific shipment
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/shipments/1`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 1,
+ "total_qty": 2,
+ "total_weight": null,
+ "carrier_code": null,
+ "carrier_title": "DHL Shipping",
+ "track_number": "1234566",
+ "email_sent": 0,
+ "customer": {...},
+ "inventory_source": {...},
+ "items": [
+ {...},
+ {...}
+ ]
+ }
+}
+```
+
+:::
diff --git a/docs/1.x/api/transactions.md b/docs/1.x/api/transactions.md
new file mode 100644
index 00000000..458066bd
--- /dev/null
+++ b/docs/1.x/api/transactions.md
@@ -0,0 +1,203 @@
+# Transactions
+
+In this section, we will see all the APIs which are related to transactions. In Bagisto, we save all the transactions done by the customers using the Paypal Smart Button option.
+
+::: warning
+
+These are all transactions that are saved in the database after the payment done by the customers using the Paypal Smart Button option.
+
+:::
+
+## Get all transactions
+
+You can get all the transaction data from the Bagisto store. To get the data from the store, the customer must be authenticated. You can achieve this job by using the `transactions` API call resource.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/transactions(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Records for specific page
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/transactions?page=1`
+
+ ::: tip
+
+ If you didn't use the page (?page=x) filter, then it returns the data of the first page by default.
+
+ `GET http(s)://example.com/api/transactions`
+
+ :::
+
+::: details Response
+
+~~~json
+{
+ "data": [
+ {
+ "id": 1,
+ "transaction_id": "47427618SF330010G",
+ "status": "COMPLETED",
+ "type": "CAPTURE",
+ "payment_method": "paypal_smart_button",
+ "data": "{\"0\": {\"items\": [{\"sku\": \"12\", \"name\": \"Soft Toy\", \"category\": \"PHYSICAL_GOODS\", \"quantity\": \"1\", \"unit_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}], \"payee\": {\"merchant_id\": \"85PGX7H6T2ZLW\", \"email_address\": \"prachiwebkul-facilitator@gmail.com\"}, \"amount\": {\"value\": \"150.00\", \"breakdown\": {\"shipping\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"tax_total\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"item_total\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}, \"currency_code\": \"USD\"}, \"payments\": {\"captures\": [{\"id\": \"2U5068420K488272L\", \"links\": [{\"rel\": \"self\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L\", \"method\": \"GET\"}, {\"rel\": \"refund\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L/refund\", \"method\": \"POST\"}, {\"rel\": \"up\", \"href\": \"https://api.sandbox.paypal.com/v2/checkout/orders/47427618SF330010G\", \"method\": \"GET\"}], \"amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}, \"status\": \"COMPLETED\", \"create_time\": \"2021-04-09T09:28:03Z\", \"update_time\": \"2021-04-09T09:28:03Z\", \"final_capture\": true, \"seller_protection\": {\"status\": \"ELIGIBLE\", \"dispute_categories\": [\"ITEM_NOT_RECEIVED\", \"UNAUTHORIZED_TRANSACTION\"]}, \"seller_receivable_breakdown\": {\"net_amount\": {\"value\": \"143.85\", \"currency_code\": \"USD\"}, \"paypal_fee\": {\"value\": \"6.15\", \"currency_code\": \"USD\"}, \"gross_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}}]}, \"shipping\": {\"name\": {\"full_name\": \"John Doe\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}}, \"reference_id\": \"default\", \"soft_descriptor\": \"PAYPAL *TESTFACILIT\"}, \"name\": {\"surname\": \"Doe\", \"given_name\": \"John\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}, \"payer_id\": \"8KC42JLS656PQ\", \"email_address\": \"sb-eyqoq4881652@personal.example.com\"}",
+ "updated_at": "2021-04-09T09:28:08.000000Z",
+ "created_at": "2021-04-09T09:28:08.000000Z"
+ }
+ ],
+ "links": {
+ "first": "https://example.com/api/transactions?page=1",
+ "last": "https://example.com/api/transactions?page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "links": [
+ {
+ "url": null,
+ "label": "« Previous",
+ "active": false
+ },
+ {
+ "url": "https://example.com/api/transactions?page=1",
+ "label": "1",
+ "active": true
+ },
+ {
+ "url": null,
+ "label": "Next »",
+ "active": false
+ }
+ ],
+ "path": "https://example.com/api/transactions",
+ "per_page": 10,
+ "to": 1,
+ "total": 1
+ }
+}
+~~~
+
+:::
+
+#### 2. Get all transactions without pagination
+
+You can also get all the transaction data at once from the Bagisto store without pagination. To get the data, the customer must be authenticated. For this, you have to pass `pagination=0` in the query parameter with the `transactions` resource in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/public/api/transactions?pagination=0`
+
+::: details Response
+
+~~~json
+{
+ "data": [
+ {
+ "id": 1,
+ "transaction_id": "47427618SF330010G",
+ "status": "COMPLETED",
+ "type": "CAPTURE",
+ "payment_method": "paypal_smart_button",
+ "data": "{\"0\": {\"items\": [{\"sku\": \"12\", \"name\": \"Soft Toy\", \"category\": \"PHYSICAL_GOODS\", \"quantity\": \"1\", \"unit_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}], \"payee\": {\"merchant_id\": \"85PGX7H6T2ZLW\", \"email_address\": \"prachiwebkul-facilitator@gmail.com\"}, \"amount\": {\"value\": \"150.00\", \"breakdown\": {\"shipping\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"tax_total\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"item_total\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}, \"currency_code\": \"USD\"}, \"payments\": {\"captures\": [{\"id\": \"2U5068420K488272L\", \"links\": [{\"rel\": \"self\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L\", \"method\": \"GET\"}, {\"rel\": \"refund\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L/refund\", \"method\": \"POST\"}, {\"rel\": \"up\", \"href\": \"https://api.sandbox.paypal.com/v2/checkout/orders/47427618SF330010G\", \"method\": \"GET\"}], \"amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}, \"status\": \"COMPLETED\", \"create_time\": \"2021-04-09T09:28:03Z\", \"update_time\": \"2021-04-09T09:28:03Z\", \"final_capture\": true, \"seller_protection\": {\"status\": \"ELIGIBLE\", \"dispute_categories\": [\"ITEM_NOT_RECEIVED\", \"UNAUTHORIZED_TRANSACTION\"]}, \"seller_receivable_breakdown\": {\"net_amount\": {\"value\": \"143.85\", \"currency_code\": \"USD\"}, \"paypal_fee\": {\"value\": \"6.15\", \"currency_code\": \"USD\"}, \"gross_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}}]}, \"shipping\": {\"name\": {\"full_name\": \"John Doe\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}}, \"reference_id\": \"default\", \"soft_descriptor\": \"PAYPAL *TESTFACILIT\"}, \"name\": {\"surname\": \"Doe\", \"given_name\": \"John\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}, \"payer_id\": \"8KC42JLS656PQ\", \"email_address\": \"sb-eyqoq4881652@personal.example.com\"}",
+ "updated_at": "2021-04-09T09:28:08.000000Z",
+ "created_at": "2021-04-09T09:28:08.000000Z"
+ }
+ ]
+}
+~~~
+
+:::
+
+## Get transaction by id
+
+To get the specific transaction details, you have to pass an `transaction_id` as a request payload in the API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/transactions/{transaction_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | -------------- | ---------------- | ------ |
+ | transaction_id | Transaction's ID | Number |
+
+### Examples
+
+Let's fetch specific transaction,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/transactions/1`
+
+::: details Response
+
+~~~json
+{
+ "id": 1,
+ "transaction_id": "47427618SF330010G",
+ "status": "COMPLETED",
+ "type": "CAPTURE",
+ "payment_method": "paypal_smart_button",
+ "data": "{\"0\": {\"items\": [{\"sku\": \"12\", \"name\": \"Soft Toy\", \"category\": \"PHYSICAL_GOODS\", \"quantity\": \"1\", \"unit_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}], \"payee\": {\"merchant_id\": \"85PGX7H6T2ZLW\", \"email_address\": \"prachiwebkul-facilitator@gmail.com\"}, \"amount\": {\"value\": \"150.00\", \"breakdown\": {\"shipping\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"tax_total\": {\"value\": \"0.00\", \"currency_code\": \"USD\"}, \"item_total\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}, \"currency_code\": \"USD\"}, \"payments\": {\"captures\": [{\"id\": \"2U5068420K488272L\", \"links\": [{\"rel\": \"self\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L\", \"method\": \"GET\"}, {\"rel\": \"refund\", \"href\": \"https://api.sandbox.paypal.com/v2/payments/captures/2U5068420K488272L/refund\", \"method\": \"POST\"}, {\"rel\": \"up\", \"href\": \"https://api.sandbox.paypal.com/v2/checkout/orders/47427618SF330010G\", \"method\": \"GET\"}], \"amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}, \"status\": \"COMPLETED\", \"create_time\": \"2021-04-09T09:28:03Z\", \"update_time\": \"2021-04-09T09:28:03Z\", \"final_capture\": true, \"seller_protection\": {\"status\": \"ELIGIBLE\", \"dispute_categories\": [\"ITEM_NOT_RECEIVED\", \"UNAUTHORIZED_TRANSACTION\"]}, \"seller_receivable_breakdown\": {\"net_amount\": {\"value\": \"143.85\", \"currency_code\": \"USD\"}, \"paypal_fee\": {\"value\": \"6.15\", \"currency_code\": \"USD\"}, \"gross_amount\": {\"value\": \"150.00\", \"currency_code\": \"USD\"}}}]}, \"shipping\": {\"name\": {\"full_name\": \"John Doe\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}}, \"reference_id\": \"default\", \"soft_descriptor\": \"PAYPAL *TESTFACILIT\"}, \"name\": {\"surname\": \"Doe\", \"given_name\": \"John\"}, \"address\": {\"postal_code\": \"110045\", \"admin_area_1\": \"DL\", \"admin_area_2\": \"New Delhi\", \"country_code\": \"IN\", \"address_line_1\": \"Dwarka\"}, \"payer_id\": \"8KC42JLS656PQ\", \"email_address\": \"sb-eyqoq4881652@personal.example.com\"}",
+ "updated_at": "2021-04-09T09:28:08.000000Z",
+ "created_at": "2021-04-09T09:28:08.000000Z"
+}
+~~~
+
+:::
diff --git a/docs/1.x/api/wishlists.md b/docs/1.x/api/wishlists.md
new file mode 100644
index 00000000..45e6e091
--- /dev/null
+++ b/docs/1.x/api/wishlists.md
@@ -0,0 +1,309 @@
+# Wishlists
+
+In this section, we will see how wishlists' API works.
+
+## Get all wishlists
+
+You can also get all the wishlists of store's customers. To get the wishlists, customer must be logged-in to the Bagisto store.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/wishlist(?limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | -------------------------------------------- | ------ |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+::: tip
+
+If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+### Examples
+
+#### 1. Get wishlists for specific page
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist?page=1`
+
+#### 2. Get wishlists for specific page with limit
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist?limit=2&page=1`
+
+::: details Response (Example 1 & 2)
+
+![bagisto_wishlist_page](../../assets/1.x/images/api/bagisto_wishlist_page.jpg)
+
+:::
+
+#### 3. Get all wishlists without pagination
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist?pagination=0`
+
+::: details Response
+
+```json
+{
+ "data": [
+ {
+ "id": 9,
+ "product": {
+ "id": 5,
+ "type": "simple",
+ "name": "Home Decor Bottles",
+ "url_key": "home-decor-bottles",
+ "price": 10,
+ "formated_price": "$10.00",
+ "short_description": "
Home Decor Bottles
",
+ "description": "
Home Decor Bottles
",
+ "sku": "bottles",
+ }
+ },
+ {
+ "id": 8,
+ "product": {...}
+ },
+ {
+ "id": 7,
+ "product": {...}
+ }
+ ]
+}
+```
+
+:::
+
+## Get wishlists by customer's id
+
+To get all wishlists of a specific customer, you have to pass a `customer_id` as a query parameter in API url.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET /api/wishlist(?customer_id,limit,page,pagination)`
+
+- Params
+
+ | Name | Info | Type |
+ | ----------- | -------------------------------------------- | ------ |
+ | customer_id | Customer's ID | Number |
+ | limit | Maximum number of records in each request | Number |
+ | page | Records for specific page based on the limit | Number |
+ | pagination | Will display all the records if set to `0` | Number |
+
+### Examples
+
+#### 1. If you want all the wishlists by `customer_id`
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist?customer_id=1&pagination=0`
+
+::: details Response:
+
+```json
+{
+ "data": [
+ {
+ "id": 7,
+ "product": {...},
+ },
+ {...},
+ {...},
+ {...},
+ ...
+ {...}
+ ]
+}
+```
+
+:::
+
+#### 2. If you want wishlists for specific page by `customer_id`
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist?customer_id=1&page=1`
+
+::: details Response:
+
+```json
+{
+ "data": [
+ {
+ "id": 7,
+ "product": {...},
+ },
+ {...},
+ {...},
+ {...},
+ ...
+ {...}
+ ],
+ "links": {
+ "first": "https://example.com/api/wishlist?customer_id=1&page=1",
+ "last": "https://example.com/api/wishlist?customer_id=1&page=1",
+ "prev": null,
+ "next": null
+ },
+ "meta": {
+ "current_page": 1,
+ "from": 1,
+ "last_page": 1,
+ "path": "https://example.com/api/wishlist",
+ "per_page": 10,
+ "to": 2,
+ "total": 9
+ }
+}
+```
+
+:::
+
+## Add product to wishlist
+
+To add a product to customer's wishlist, you have to pass a `product_id` as a request payload like `wishlist/add/{product_id}` in API URL.
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist/add/{product_id}`
+
+- Params
+
+ | Name | Info | Type |
+ | ---------- | ---------- | ------ |
+ | product_id | Product ID | Number |
+
+### Examples
+
+Let's add one product to wishlist,
+
+- Headers
+
+ | Key | Value | Info |
+ | ------------- | --------------------- | ------------------------------------ |
+ | Accept | application/json | |
+ | Authorization | Bearer `token-string` | Use only when you pass `?token=true` |
+
+- Request
+
+ `GET http(s)://example.com/api/wishlist/add/11`
+
+::: details Response
+
+```json
+{
+ "data": {
+ "id": 11,
+ "product": {
+ "id": 1,
+ "type": "simple",
+ "name": "Leather Shoes",
+ "url_key": "leather-shoes",
+ "price": 50,
+ "formated_price": "$50.00",
+ "short_description": "
",
+ "locale": "en",
+ "cmsPageId": "10"
+ }
+ ],
+ "channels": [],
+ "success": null
+ }
+ ]
+ }
+ }
+}
+~~~
+:::
+
+### 2. Get CMS Page By ID
+
+To get the specific CMS Page, you have to pass an `id` field with query request .By using this resource and request payload, you will get only a single object under the `data` object in response.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+### Examples
+
+Let's take an example,
+
+- Request Query
+ ~~~Query
+ query cmspage {
+ cmsPage(id:1) {
+ id
+ layout
+ createdAt
+ updatedAt
+ translations {
+ id
+ urlKey
+ metaDescription
+ metaTitle
+ pageTitle
+ metaKeywords
+ htmlContent
+ locale
+ cmsPageId
+ }
+ channels {
+ id
+ code
+ name
+ description
+ theme
+ homePageContent
+ footerContent
+ hostname
+ defaultLocaleId
+ baseCurrencyId
+ rootCategoryId
+ }
+ success
+ }
+ }
+ ~~~
+
+::: details Response
+ ~~~json
+ {
+ "data": {
+ "cmsPage": {
+ "id": "1",
+ "layout": null,
+ "createdAt": "2021-05-05 15:36:49",
+ "updatedAt": "2021-05-05 15:36:49",
+ "translations": [
+ {
+ "id": "1",
+ "urlKey": "about-us",
+ "metaDescription": "",
+ "metaTitle": "about us",
+ "pageTitle": "About Us",
+ "metaKeywords": "aboutus",
+ "htmlContent": "
About us page content
",
+ "locale": "en",
+ "cmsPageId": "1"
+ }
+ ],
+ "channels": [],
+ "success": null
+ }
+ }
+ }
+ ~~~
+
+:::
+
+### 3. Get Filtered CMS Page
+
+You can get the filter data from the CMS Pages by passing the input fileds in the request and that you want in the response.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+**Note**: You can pass all the related fileds that you want in response.
+
+### Examples
+
+Let's take an example,
+
+- Request Query
+
+~~~query
+ query cmspages {
+ cmsPages(input: {
+ id:1
+ }, page:1) {
+ paginatorInfo {
+ count
+ currentPage
+ lastPage
+ total
+ }
+ data {
+ id
+ layout
+ createdAt
+ updatedAt
+ translations {
+ id
+ urlKey
+ metaDescription
+ metaTitle
+ pageTitle
+ metaKeywords
+ htmlContent
+ locale
+ cmsPageId
+ }
+ channels {
+ id
+ code
+ name
+ description
+ theme
+ homePageContent
+ footerContent
+ hostname
+ defaultLocaleId
+ baseCurrencyId
+ rootCategoryId
+ }
+ success
+ }
+ }
+ }
+~~~
+
+::: details Response
+ ~~~json
+ {
+ "data": {
+ "cmsPages": {
+ "paginatorInfo": {
+ "count": 1,
+ "currentPage": 1,
+ "lastPage": 1,
+ "total": 1
+ },
+ "data": [
+ {
+ "id": "1",
+ "layout": null,
+ "createdAt": "2021-05-05 15:36:49",
+ "updatedAt": "2021-05-05 15:36:49",
+ "translations": [
+ {
+ "id": "1",
+ "urlKey": "about-us",
+ "metaDescription": "",
+ "metaTitle": "about us",
+ "pageTitle": "About Us",
+ "metaKeywords": "aboutus",
+ "htmlContent": "
About us page content
",
+ "locale": "en",
+ "cmsPageId": "1"
+ }
+ ],
+ "channels": [],
+ "success": null
+ }
+ ]
+ }
+ }
+ }
+ ~~~
+ :::
+
+
+### 4. Get CMS Translations
+
+You can get the CMS Page Translations from the Bagisto store. You can achieve this job by using the `CMS Page Translations` API call.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Single Request Endpoint
+
+ `POST http(s)://example.com/graphql`
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+**Note**: You can pass all the related fileds that you want in response.
+
+- Query
+ ~~~query
+ query cmsPageTranslations {
+ cmsPageTranslations(input: {
+ cmsPageId:1
+ id:1
+ }, page:1) {
+ paginatorInfo {
+ count
+ currentPage
+ lastPage
+ total
+ }
+ data{
+ id
+ urlKey
+ metaDescription
+ metaTitle
+ pageTitle
+ metaKeywords
+ htmlContent
+ locale
+ cmsPageId
+ }
+ }
+ }
+ ~~~
+
+::: details Response
+
+~~~json
+{
+ "data": {
+ "cmsPageTranslations": {
+ "paginatorInfo": {
+ "count": 1,
+ "currentPage": 1,
+ "lastPage": 1,
+ "total": 1
+ },
+ "data": [
+ {
+ "id": "1",
+ "urlKey": "about-us",
+ "metaDescription": "",
+ "metaTitle": "about us",
+ "pageTitle": "About Us",
+ "metaKeywords": "aboutus",
+ "htmlContent": "
About us page content
",
+ "locale": "en",
+ "cmsPageId": "1"
+ }
+ ]
+ }
+ }
+}
+~~~
+:::
+
+### 5. Get CMS Translations By ID
+
+To get the specific CMS Translations, you have to pass an `id` field with query request .By using this resource and request payload, you will get only a single object under the `data` object in response.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+### Examples
+
+Let's take an example,
+
+- Request Query
+ ~~~Query
+ query cmsPageTranslation {
+ cmsPageTranslation(id:1,input: {
+ cmsPageId:1
+ id:1
+ }) {
+ id
+ urlKey
+ metaDescription
+ metaTitle
+ pageTitle
+ metaKeywords
+ htmlContent
+ locale
+ cmsPageId
+ }
+ }
+ ~~~
+
+::: details Response
+ ~~~json
+ {
+ "data": {
+ "cmsPageTranslation": {
+ "id": "1",
+ "urlKey": "about-us",
+ "metaDescription": "",
+ "metaTitle": "about us",
+ "pageTitle": "About Us",
+ "metaKeywords": "aboutus",
+ "htmlContent": "
About us page content
",
+ "locale": "en",
+ "cmsPageId": "1"
+ }
+ }
+ }
+ ~~~
+
+:::
+
+### 6. Create a new CMS Page
+
+ To create a CMS Page, you have to perform mutation on CMS Page and paas the related fields in the request.
+ API call resource will create a new CMS Page, only if the admin has logged in.
+
+ - Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+ ### Examples
+
+ Let's take an example,
+
+- Request Mutation
+ ~~~Mutation
+ mutation{
+ createCmsPage(input:{
+ pageTitle: "test"
+ channels:1
+ htmlContent: "
\n ",
+ "hostname": "http://localhost/graphql/public",
+ "defaultLocaleId": 1,
+ "baseCurrencyId": 1,
+ "rootCategoryId": 1
+ }
+ ],
+ "success": null
+ }
+ }
+ }
+ ~~~
+:::
+
+### 7. Update CMS Page
+
+By using this API call you can update the CMS Page. To do this , you have to perform update mutation on CMS Page and paas the related fields in the request.
+API call will update a CMS Page, only if the admin has logged in.
+
+
+ - Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+ ### Examples
+
+ Let's take an example,
+
+- Request Mutation
+ ~~~Mutation
+ mutation{
+ updateCmsPage(id:12,input:{
+ pageTitle: "testUpdate"
+ channels:1
+ htmlContent: "
We love to craft softwares and solve the real world problems with the binaries. We are highly committed to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.
We love to craft softwares and solve the real world problems with the binaries. We are highly committed to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.
",
+ "locale": "en",
+ "channel": "default",
+ "headerContentCount": "5",
+ "createdAt": null,
+ "updatedAt": null
+ }
+ }
+ }
+ ~~~
+
+:::
+
+### 3. Update Meta Data
+
+By using this API call you can update the Meta Data. To do this , you have to perform update mutation on Meta Data and paas the related fields in the request.
+API call will update a Meta Data, only if the admin has logged in.
+
+
+ - Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+ ### Examples
+
+ Let's take an example,
+
+- Request Mutation
+ ~~~Mutation
+ mutation{
+ updateMetaData(id:1,input:{
+ homePageContent: "
We love to craft softwares and solve the real world problems with the binaries. We are highly committed to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.
We love to craft softwares and solve the real world problems with the binaries. We are highly committed to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.
\n ",
+ "hostname": "http://localhost/graphql/public",
+ "defaultLocaleId": 1,
+ "baseCurrencyId": 1,
+ "rootCategoryId": 1,
+ "homeSeo": "{\"meta_title\": \"Demo store\", \"meta_keywords\": \"Demo store meta keyword\", \"meta_description\": \"Demo store meta description\"}",
+ "defaultLocale": "{\"id\":1,\"code\":\"en\",\"name\":\"English\",\"created_at\":null,\"updated_at\":null,\"direction\":\"ltr\",\"locale_image\":null}",
+ "baseCurrency": "{\"id\":1,\"code\":\"USD\",\"name\":\"US Dollar\",\"created_at\":null,\"updated_at\":null,\"symbol\":\"$\"}",
+ "rootCategory": "{\"id\":1,\"position\":1,\"image\":null,\"status\":1,\"_lft\":1,\"_rgt\":16,\"parent_id\":null,\"created_at\":\"2021-05-05T10:06:44.000000Z\",\"updated_at\":\"2021-05-05T10:06:44.000000Z\",\"display_mode\":\"products_and_description\",\"category_icon_path\":null,\"additional\":null,\"name\":\"Root\",\"description\":\"Root\",\"slug\":\"root\",\"url_path\":\"\",\"meta_title\":\"\",\"meta_description\":\"\",\"meta_keywords\":\"\",\"translations\":[{\"id\":1,\"name\":\"Root\",\"slug\":\"root\",\"description\":\"Root\",\"meta_title\":\"\",\"meta_description\":\"\",\"meta_keywords\":\"\",\"category_id\":1,\"locale\":\"en\",\"locale_id\":null,\"url_path\":\"\"}]}",
+ "logoUrl": null,
+ "faviconUrl": null,
+ "success": null
+ }
+ }
+ }
+ }
+}
+~~~
+:::
+
+## Remove From Wishlist
+
+To remove a product from the wishlist, you have to pass an `id` field with query request .By using this resource and request payload, you will get only a single object under the `data` object in response.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+### Examples
+
+Let's take an example,
+
+- Request Query
+ ~~~Query
+ mutation removeFromWishlist {
+ removeFromWishlist(input: {
+ productId: 1
+ }) {
+ status
+ success
+ }
+ }
+ ~~~
+
+::: details Response
+ ~~~json
+ {
+ "data": {
+ "removeFromWishlist": {
+ "status": true,
+ "success": "Item Successfully Removed From Wishlist"
+ }
+ }
+ }
+ ~~~
+:
+
+## Remove All From Wishlist
+
+To remove all product from the wishlist, you have to pass related fields with query request .
+
+- Headers
+
+ | Key | Value |
+ | ------------- | --------------------- |
+ | Accept | application/json |
+ | Authorization | Bearer `token-string` |
+
+### Examples
+
+Let's take an example,
+
+- Request Query
+ ~~~Query
+ mutation removeAllWishlists {
+ removeAllWishlists {
+ status
+ success
+ }
+ }
+ ~~~
+
+::: details Response
+ ~~~json
+ {
+ "data": {
+ "removeAllWishlists": {
+ "status": true,
+ "success": "All The Items From Your Wishlist Have Been Removed"
+ }
+ }
+ }
+ ~~~
+:
+
+## Move To Cart From Wishlist
+
+You can move a product from wishlist to cart from the Bagisto store. You can achieve this job by using the `Move To Cart From Wishlist` API call.
+
+- Headers
+
+ | Key | Value |
+ | ------------- | ---------------- |
+ | Accept | application/json |
+
+- Single Request Endpoint
+
+ `POST http(s)://example.com/graphql`
+
+::: tip
+
+ If you are using pagination and want to know more info about responses then check the [explanation](./explanation) portion.
+
+:::
+
+- Query
+ ~~~query
+ mutation moveToCart {
+ moveToCart(id: 2) {
+ status
+ success
+ }
+ }
+ ~~~
+
+::: details Response
+
+~~~json
+{
+ "data": {
+ "moveToCart": {
+ "status": true,
+ "success": "Item successfully moved To cart"
+ }
+ }
+}
+~~~
+:::
+
diff --git a/docs/1.x/introduction/README.md b/docs/1.x/introduction/README.md
new file mode 100644
index 00000000..9e78c2d3
--- /dev/null
+++ b/docs/1.x/introduction/README.md
@@ -0,0 +1,18 @@
+# Introduction
+**Bagisto** is a E-Commerce framework built on top of the hottest opensource technologies such as [Laravel](https://laravel.com), a [PHP](https://php.net) framework and [Vue.js](https://vuejs.org/), a progressive Javascript framework.
+
+**Bagisto** is a viable option to reduce your time, cost and workforce for building online stores or migrating from a physical store to an online platform.
+
+It is suitable for all small or large E-Commerce business demands using a simple set-up procedure.
+Built on top of [Laravel](https://laravel.com) and equipped with an easy product information management.
+
+The framework is very flexible and easy to use even for non-tech users.
+**Bagisto** features an administration panel with a dashboard, sales data, a catalog for products and customer management.
+
+To learn more about **Bagisto's** features and try a demo, check out our website [https://bagisto.com](https://bagisto.com).
+Get quickly updated on the current version and recently released features, see [Bagisto roadmap](https://bagisto.com/roadmap/).
+You can get started with the source code by checking out the repo on GitHub at [bagisto/bagisto](https://github.com/bagisto/bagisto).
+
+
+
+
diff --git a/docs/1.x/introduction/docker.md b/docs/1.x/introduction/docker.md
new file mode 100644
index 00000000..b935b09c
--- /dev/null
+++ b/docs/1.x/introduction/docker.md
@@ -0,0 +1,206 @@
+# Docker
+
+[[toc]]
+
+## Introduction
+[Docker](https://www.docker.com/) is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. Docker can also be used for defining and running multi-container Docker applications using Docker-Compose tool.
+
+With the help of docker-compose, you can define containers to be build, their configuration, links, volumes, ports etc in a single file and it gets launched by a single command.
+You can also add multiple servers and services just by adding them to docker-compose configuration file. This configuration file is in [YAML](https://en.wikipedia.org/wiki/YAML) format.
+
+#### Application Data and Database Volume Persistance
+It is recommended to keep your application files and database data volume on the docker host and mount them on the running container, this to ensure that the application and database data persistance even in the case of containers' failure or termination, In this way even if you destroy containers, your data won't get lost unless you remove them forcefully.
+This compose configuration file mounts the application directory `app` and database volume `dbvolume` from host to running docker containers at the time of containers launch.
+
+## Installation & Setup
+
+### First steps
+Before you can launch Bagisto in a docker environment you need to install the latest version of Docker and Docker Compose.
+
+- [Docker](https://docs.docker.com/install/)
+- [Docker-compose](https://docs.docker.com/compose/install/)
+- [Composer](https://getcomposer.org) (optional)
+
+### Configure the docker container
+Once Docker and docker-compose have been installed, we need to create a **docker-compose.yml** file.
+The **docker-compose.yml** configuration file requires following inputs from the user:
+
+#### Webserver configuration
+In the `web_server` service block, assign your system working user uid to the `USER_UID` enviroment variable.
+Run the following command `id -u` on linux or Macos to get your user id
+```shell
+id -u
+```
+
+#### Database configuration
+In the `database_server` service block, assign mysql database name, mysql database user name, mysql database user password and mysql root password to `MYSQL_DATABASE`, `MYSQL_USER`, `MYSQL_PASSWORD` and `MYSQL_ROOT_PASSWORD` environment.
+
+
+#### Clone configuration from Github
+You can make use of our repository from Github by cloning this in your new directory
+```shell
+git clone https://github.com/bagisto/bagisto-docker.git .
+```
+#### Configure manually
+- Create a new folder for example **bagisto-docker** and create **docker-compose.yml** manually inside it.
+- Add the following content to **docker-compose.yml**
+```yml
+version: '3'
+
+services:
+
+ web_server:
+ image: webkul/apache-php:latest
+ container_name: apache2
+ restart: always
+ volumes:
+ - ./app:/var/www/html
+ working_dir: /var/www/html/
+ environment:
+ USER_UID: 'mention your system user ID here. ex: 1001, 1000, 33, etc'
+ networks:
+ - bagisto-network
+ ports:
+ - '80:80'
+ expose:
+ - '80'
+ depends_on:
+ - database_server
+ links:
+ - database_server
+
+ database_server:
+ image: mysql:5.7
+ container_name: mysql
+ restart: always
+ environment:
+ MYSQL_DATABASE: 'mention the name of the database to be created here. eg: mydatabase'
+ MYSQL_USER: 'mention database user here. eg: mydatabase_user'
+ MYSQL_PASSWORD: 'mention database user password here. ex: mystrongPassword'
+ MYSQL_ROOT_PASSWORD: 'mention mysql root password here. ex: mysqlstrongpass'
+ MYSQL_ROOT_HOST: '%'
+ networks:
+ - bagisto-network
+ ports:
+ - '3306:3306'
+ expose:
+ - '3306'
+ volumes:
+ - ./dbvolume:/var/lib/mysql
+
+volumes:
+ dbvolume:
+ app:
+
+networks:
+ bagisto-network:
+ ```
+
+#### Download the docker image
+The following command will download the docker images for apache-php version 7.3 and mysql version 5.7.
+```shell
+docker-compose pull
+```
+
+### Launching the docker container
+The following command will create a network, launch a webserver and database containers with names `apache2` and `mysql`.
+It will also create a new `app` and `dbvolume` directory inside your current directory and mount it to respective docker containers as mentioned in docker-compose.yml.
+It binds your `host port 80` with the apache2 container port 80 and `host port 3306` with mysql container port 3306. If you want to run containers on ports other than 80 and 3306, modify their values in **docker-compose.yml** file.
+
+```
+docker-compose up -d
+```
+
+### Monitor your container(s):
+Check your running docker containers with the following commands
+
+`docker ps` OR `docker-compose ps`
+```shell
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+62a10346b84a webkul/apache-php:latest "/usr/bin/supervisord" About an hour ago Up About an hour 0.0.0.0:80->80/tcp apache2
+90a0a2e0e46b mysql:5.7 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
+```
+
+## Configuring Bagisto
+Once our environment is ready we can start installing Bagisto. You can either install Bagisto from [Github](#install-without-composer) or with [composer](#install-with-composer)
+
+### Install without composer
+Download the [latest release](https://bagisto.com/en/download) inside `app/bagisto` directory.
+Open the `.env` file inside **app/bagisto** and set the following environment variables listed below:
+
+```editorconfig
+APP_URL=https://127.0.0.1
+DB_CONNECTION=mysql
+DB_HOST=mysql
+DB_PORT=3306
+DB_DATABASE=
+DB_USERNAME=
+DB_PASSWORD=
+```
+
+Run the following commands to install Bagisto.
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan migrate'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan db:seed'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan vendor:publish'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan storage:link'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer dump-autoload -d bagisto'"
+```
+
+Mention the database details same as docker-compose.yml and admin details.
+
+
+### Install with composer
+The following commands will be exexcuted within the docker container
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer create-project bagisto/bagisto'"
+```
+
+Open the .env file inside `app/bagisto` directory and set the following environment variables listed below:
+
+```editorconfig
+APP_URL=https://127.0.0.1
+DB_CONNECTION=mysql
+DB_HOST=mysql
+DB_PORT=3306
+DB_DATABASE=
+DB_USERNAME=
+DB_PASSWORD=
+```
+
+Run the following commands to install Bagisto.
+```shell
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan migrate'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan db:seed'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan vendor:publish'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'php bagisto/artisan storage:link'"
+docker exec -i apache2 bash -c "su - www-data -s /bin/bash -c 'composer dump-autoload -d bagisto'"
+```
+
+Bagisto has been installed and is ready. Browse your server IP address or domain name on the web browser.
+
+### Configure Apache
+The Apache documentroot is by default assigned to **/var/www/html/public_html**. while the **app** directory on host is mapped with the **html** directory inside the container.
+We need to create a symlink of `bagisto/public` in `app` directory to `/var/www/html/public_html`.
+
+Run the following command on Linux or MacOS
+```bash
+cd app; ln -snf bagisto/public public_html
+```
+
+Run the following command on Windows
+```command-line
+cd app
+mklink bagisto/public public_html
+```
+### Ready
+
+#### Login as a administrator:
+You can directly visit the admin interface [http://your_server_endpoint/admin](http://your_server_endpoint/admin/) and authenticate with the following credentials.
+
+| Email | Password |
+| --------- | ------- |
+| admin@example.com | admin123 |
+
+#### Login as a customer
+You can directly visit your store on [http://your_server_endpoint/](http://your_server_endpoint/).
diff --git a/docs/1.x/introduction/installation.md b/docs/1.x/introduction/installation.md
new file mode 100644
index 00000000..39f65503
--- /dev/null
+++ b/docs/1.x/introduction/installation.md
@@ -0,0 +1,72 @@
+# Installation
+
+## Use Our GUI Installer
+1. [Download Bagisto](https://bagisto.com/en/download/)
+2. Extract the contents of the zip file.
+3. Point your HTTP server to the public/ directory of the project and open it on your browser.For example:
+ - `https://example.com/`
+4. This will detect Bagisto and start the installer.
+
+## Install Bagisto Using _composer_
+
+```
+composer create-project bagisto/bagisto
+```
+
+- Start the installation script.
+```sh
+php artisan bagisto:install
+```
+
+### Features of above installation command
+::: warning
+It will check existence of the .env file, if it exists then please update the file manually with the below details.
+:::
+
+```
+- APP_TIMEZONE
+- APP_LOCALE
+- LOG_CHANNEL
+- APP_CURRENCY
+- DB_DATABASE
+- DB_USERNAME
+- DB_PASSWORD
+```
+
+::: warning
+If the .env file does not exists then it will ask to provide the details on command prompts.
+
+:::
+- To start the installation, provide the details of the following command prompts:
+```sh
+- Please select the default locale or press enter to continue [en]:
+- Please enter the default timezone [Asia/Kolkata]:
+- Please enter the default currency [USD]:
+- What is the database name to be used by Bagisto?:
+- What is your database username?:
+- What is your database password?:
+```
+
+# Start Using Bagisto
+
+### On a production server
+
+- Open your domain on the browser. For example:
+ - `https://example.com/`
+
+### On your local device
+
+```sh
+php artisan serve
+```
+
+### How to log in to your domain as an admin
+
+Go to `https://example.com/admin/`, in case `php artisan bagisto:install` is opted, use the following credentials.
+```
+email: admin@example.com
+password: admin123
+```
+
+### How to log in to your domain as a customer
+You can directly register on `https://example.com/customer/register` as a customer, and then log in to your domain.
diff --git a/docs/1.x/introduction/requirements.md b/docs/1.x/introduction/requirements.md
new file mode 100644
index 00000000..cb379927
--- /dev/null
+++ b/docs/1.x/introduction/requirements.md
@@ -0,0 +1,42 @@
+# Requirements
+
+Before installing Bagisto, make sure the server meets the following requirements:
+
+## Server configuration
+
+- **SERVER**: Apache 2 or NGINX
+- **RAM**: 4GB or higher
+- **Node**: 8.11.3 LTS or higher
+- **PHP**: 7.4 or higher
+- **Composer**: 1.6.5 or higher
+
+## PHP Extensions
+
+Make sure the following extensions are installed and enabled. You can check using the `phpinfo()` page or the `php -m` command.
+
+- php-intl extension
+
+- php-gd extension
+
+ ::: tip
+ You must install the `php-gd` extension properly otherwise, the image does not work properly in the project.
+ :::
+
+## PHP Configuration
+
+Open your php configuration file **php.ini** and change the following settings.
+
+ ~~~ini
+ memory_limit = 4G
+ max_execution_time = 360
+ date.timezone = Europe/Brussels <- Change this to your own timezone.
+ ~~~
+
+::: tip Restart your web server
+ Whenever you make changes to the PHP configuration file, you must restart Apache or NGINX.
+:::
+
+## Supported Database Servers
+
+- **MySQL**: 5.7.23 or higher
+- **MariaDB**: 10.2.7 or higher
diff --git a/docs/1.x/introduction/upgrade-to-latest-bagisto.md b/docs/1.x/introduction/upgrade-to-latest-bagisto.md
new file mode 100644
index 00000000..deca615e
--- /dev/null
+++ b/docs/1.x/introduction/upgrade-to-latest-bagisto.md
@@ -0,0 +1,138 @@
+# Upgrade to the latest version of Bagisto
+
+To upgrade your current version to the latest version of Bagisto, you need to follow some steps,
+
+- First, you need to download the latest version of Bagisto.
+
+- You can download Bagisto from the following links,
+
+ - [Download From Official Bagisto Site](https://bagisto.com/en/download/)
+ - [Download From Github](https://github.com/bagisto/bagisto)
+
+- After downloading the Bagisto zip file, you need to extract where you want to deploy it.
+- After extract the file, you need to go to the root folder of the extracted folder and run the below command in the terminal.
+
+ ~~~sh
+ composer create-project
+ ~~~
+
+- After the command has been executed, now go to your `.env` file, provide your old project database credentials for which you want to upgrade Bagisto, and run the following command,
+
+ ~~~sh
+ php artisan optimize
+
+ # -- OR
+
+ php artisan config:cache
+ ~~~
+
+- Now, your new changes have been cached and now your project is ready to run the migrate command,
+
+ ~~~sh
+ php artisan migrate
+ ~~~
+
+ ::: danger
+ Here we have not provided you the seeder command because the seeder command always resets all the settings, categories and etc. If some tables need default settings then we advise you to add manually.
+ :::
+
+- Now, its time to create a symlink so that public assets can be linked to storage,
+
+ ~~~sh
+ php artisan storage:link
+ ~~~
+
+- Copy all the content of the previous version's folder (e.g. `old-project/storage/app/public`) to the latest version's folder (e.g. `new-project/storage/app/public`).
+
+ ::: tip
+ If your existing project also depends on some local storage, or you have changed some paths, or you want previous logs also then make sure you add all those also.
+ :::
+
+- Once this is finished run the following command to publish your new files,
+
+ ~~~sh
+ php artisan vendor:publish --all
+ ~~~
+
+ ::: warning
+ Don't use the `--force` flag, this will reset all your views. Use only when you know what you are doing.
+ :::
+
+You are now at the latest version. Still, we want to mention that if you have done a lot of customizations then that portion of compatibility should be handled at your end.
+
+## Bagisto Changes
+
+### These are the changes from the version 1.3.3 to 1.4.0
+
+#### Added one composer dependency (High Severity)
+
+- Added `diglactic/laravel-breadcrumbs` for breadcrumbs in the frontend shop. Make sure to run the `composer install`, if you are upgrading the existing project.
+- Moved all the old APIs to a separate package i.e. `bagisto/legacy-api`. If you are getting exceptions then just go to `bootstrap/cache` and delete all the files and then run `composer install`. After the installation, run `php artisan optimize`.
+
+#### Changes from the datagrid (High Severity)
+
+- Implemented the ajaxified datagrid, see [#5756](https://github.com/bagisto/bagisto/pull/5756)
+
+#### Revamped admin theme (High Severity)
+
+- Added a new admin theme with features of multi-locale switcher, real time notification for admin upon order creation or updation and dark theme for admin panel.
+
+#### Changes in factories (Medium Severity)
+
+- Dropped laravel legacy factories dependencies and refactored all models to use Laravel 8 class factories. If you have used it in modules try to upgrade or just install the dependency when needed.
+
+#### Changes in routes (Medium Severity)
+
+- In admin, shop and velocity packages, this file `packages/Webkul//src/Http/routes.php` is moved to `packages/Webkul//src/Routes/web.php` this path. So if you are upgrading the existing project just make sure the provider registry is updated.
+
+### These are the changes from the version 1.3.1 to 1.3.2
+
+#### Changes from the web vital (Medium Severity)
+
+- For the velocity theme, the `velocity.js` file is divided into two files i.e. `velocity-core.js` and the `velocity.js` file. In `velocity-core.js`, all core dependencies like jQuery, bootstrap js, Vue js are added and in `velocity.js` all the components are present which is bootstrapped by the `velocity-core.js`.
+
+- All these components are minified now, `quantity-changer`, `mini-cart`, `slider-component`, and `searchbar-component`.
+
+- These components are added `hot-categories`, `popular-categories`, `sidebar-header`, `right-side-header` and `mobile-header`.
+
+- In `velocity.js`, this component `VueToast` has been removed. As no traces were found in the core. If you are using this then make sure you add it to your module dependencies.
+
+- This folder i.e. `packages/Webkul/Velocity/src/Resources/views/shop/UI` is completely removed. The files inside this folder contain the components which are already minified so not needed. Make sure if you included these files in your modules, use the direct component rather than including the file.
+
+- In this folder i.e. `packages/Webkul/Velocity/src/Resources/views/shop/layouts/particals` three files (`compare.blade.php`, `wishlist.blade.php` and `search-bar.blade.php`) are given. All these files are having individual components. For `compare.blade.php` and `wislist.blade.php`, you can use the `isText` prop to disable the text for mobile.
+
+- Reference PR: [#5020](https://github.com/bagisto/bagisto/pull/5020)
+
+#### Changes from security fixes (High Severity)
+
+- These routes i.e. `address.delete`, `customer.orders.cancel`, `customer.review.delete`, `customer.review.deleteall`, `shop.movetowishlist`, `customer.wishlist.add`, `customer.wishlist.remove` and `customer.wishlist.removeall` methods are changed from `GET` to `DELETE` and `POST` respectively. `GET` is only use for retrieving data.
+
+- Maybe if you forgot to change then surely this will impact your project. Make sure it should be updated and also run `php artisan optimize` command.
+
+- Reference PR: [#4996](https://github.com/bagisto/bagisto/pull/4996), [#4998](https://github.com/bagisto/bagisto/pull/4998) and [#5052](https://github.com/bagisto/bagisto/pull/5052)
+
+#### Downloadable product medias are moved to private disk (Medium Severity)
+
+- If someone facing broken downloadale links, this is because of the privatization of the paid links, in this case move your downloadable links folder to a private disk, and the broken link got fixed.
+
+- If still broken then take a reference from the below PR and adjust the storage data.
+
+- Reference PR: [#4966](https://github.com/bagisto/bagisto/pull/4966)
+
+#### Changes from invoice prefixes (Medium Severity)
+
+- Moved sequencer class from shop package to sales package, as orders and invoices are part of the sales. This will not impact as there is only one key and that one is in the repository.
+
+- Enhanced and scaled the `Sequencer` class.
+
+- As per the existing project perspective, `increment_id` by default is going null, so for displaying portion it will first check `increment_id` if not found then it will give the actual `id`.
+
+- In the core config, moved all the invoice settings to the new tab name `Invoice Settings` so make sure reset the value for the `Invoice Slip Design`.
+
+- Reference PR: [#4956](https://github.com/bagisto/bagisto/pull/4956)
+
+#### Changes from `.env` (Low Severity)
+
+- Just capitalized the `fixer_api_key` in `.env` to have consistency and `.env` standard.
+
+- If you have this key in your `.env` and you are using this just make sure you capitalize your key also.
diff --git a/docs/1.x/packages/README.md b/docs/1.x/packages/README.md
new file mode 100644
index 00000000..08bfc691
--- /dev/null
+++ b/docs/1.x/packages/README.md
@@ -0,0 +1,63 @@
+# Package development
+
+A package is a unit added to your application for enhancement which includes routes, controllers, views, and configuration specifically. Packages are created to manage your large applications into smaller units.
+
+In Bagisto, we have created plenty of packages at path `packages/Webkul/`. You can find a basic tree-structure of the package below:
+
+~~~directory-structure
+- ACME/HelloWorld/
+ - publishable/assets
+ - css/
+ - images/
+ - js/
+ - src/
+ - Config/
+ - acl.php
+ - admin-menu.php
+ - Console/
+ - Commands/
+ - Contracts/
+ - Database/
+ - Migrations/
+ - Seeders/
+ - Events/
+ - Http/
+ - Controllers/
+ - Admin/
+ - HelloWorldController.php
+ - Shop/
+ - HelloWorldController.php
+ - Middleware/
+ - Requests/
+ - admin-routes.php
+ - shop-routes.php
+ - Listeners/
+ - Mail/
+ - Models/
+ - Providers/
+ - HelloWorldServiceProvider.php
+ - ModuleServiceProvider.php
+ - Repositories/
+ - Resources/
+ - assets/
+ - images/
+ - js/
+ - app.js
+ - sass/
+ - admin.scss
+ - default.scss
+ - velocity.scss
+ - lang/
+ - views/
+ - admin/
+ - layouts/
+ - style.blade.php
+ - index.blade.php
+ - shop/
+ - default/
+ - index.blade.php
+ - velocity/
+ - index.blade.php
+ - package.json
+ - webpack.mix.js
+~~~
diff --git a/docs/1.x/packages/add-menu-in-admin.md b/docs/1.x/packages/add-menu-in-admin.md
new file mode 100644
index 00000000..a3f5b34d
--- /dev/null
+++ b/docs/1.x/packages/add-menu-in-admin.md
@@ -0,0 +1,70 @@
+# Add menu in admin
+
+- In your package's source directory i.e. `packages/ACME/HelloWorld/src`, create the `Config` folder and create a file named `admin-menu.php`.
+
+~~~php
+ 'helloworld',
+ 'name' => 'Hello World',
+ 'route' => 'helloworld.admin.index',
+ 'sort' => 1,
+ 'icon-class' => 'dashboard-icon',
+ ]
+];
+~~~
+
+- In this file, we provide the name of the menu, route & its icon.
+
+| Params | Description |
+| ---------- | --------------------------------------------------- |
+| key | Unique key for menu icon. |
+| name | Name of menu icon. |
+| route | Route name for your menu icon. |
+| sort | Sort number on which your menu icon should display. |
+| icon-class | Class for menu icon. |
+
+- For the route, just add the named route which specified above i.e. `helloworld.admin.index`,
+
+ ~~~php
+ Route::view('/admin/hello-world', 'helloworld::admin.index')->name('helloworld.admin.index');
+ ~~~
+
+- After that, we need to merge this `menu.php` folder with a core menu file. For this, we use the method `mergeConfigFrom()` in the register method of the service provider.
+
+ ~~~php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
+ );
+ }
+ }
+ ~~~
+
+- Run this command i.e. `php artisan optimize`.
+
+- Now, the menu will display in the admin panel. You can change the icon according to your needs.
+
+![Admin Menu Output](../../assets/1.x/images/package-development/admin-menu-output.png)
\ No newline at end of file
diff --git a/docs/1.x/packages/create-acl.md b/docs/1.x/packages/create-acl.md
new file mode 100644
index 00000000..34abd04f
--- /dev/null
+++ b/docs/1.x/packages/create-acl.md
@@ -0,0 +1,79 @@
+# Access control list
+
+In addition to providing authentication services out of the box, Bagisto also provides a functionality **ACL** (Access Control List).
+
+With this feature the administrator can allow/disallow other users to access parts of Bagisto.
+
+## Create a new ACL file
+
+Create a new file named `acl.php` in your package **Config** folder, for example, `packages/ACME/HelloWorld/src/Config` and add the following code.
+
+~~~php
+ 'helloworld',
+ 'name' => 'HelloWorld',
+ 'route' => 'helloworld.admin.index',
+ 'sort' => 2
+ ]
+];
+~~~
+
+If you check the above code we have created an array for an individual's menu with the parameters (key, name, route & sort).
+
+Just like that, we need to define the menu here which we want to include in our ACL.
+
+## Merge configuration
+
+After that, we need to merge the ACL config also just like we have done with menu items,
+
+ ~~~php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/acl.php', 'acl'
+ );
+ }
+ }
+ ~~~
+
+After setting up, just run this command `php artisan optimize` to cached the latest changes.
+
+Now check the latest ACL.
+
+![Admin ACL Output](../../assets/1.x/images/package-development/admin-acl-output.png)
+
+## Checking roles and permissions
+
+- If you check the `Admin` model in the namespace `Webkul\User\Models`, you will see the relationship binding with the `Role` model in the same namespace. From here you can grab all the permissions of the current user.
+
+- We have provided the `bouncer()` helper, which helps you to check the permissions. Let's check the current user has permission or not,
+
+ ~~~php
+ bouncer()->hasPermission($permission)
+ ~~~
diff --git a/docs/1.x/packages/create-custom-configuration.md b/docs/1.x/packages/create-custom-configuration.md
new file mode 100644
index 00000000..7ad5ccd9
--- /dev/null
+++ b/docs/1.x/packages/create-custom-configuration.md
@@ -0,0 +1,267 @@
+# Create custom configuration
+
+Creating a custom configuration ease the task for a developer or any non-developer person. Generally, in Bagisto, you can find it in admin panel **Configuration Menu**.
+
+## Steps to create custom configuration
+
+- To create a custom configuration for your application, you just need to create a `system.php` file in the `Config` folder of your package.
+
+- Inside the file, you can include the code below,
+
+ ~~~php
+ 'helloworld',
+ 'name' => 'Hello World',
+ 'sort' => 1
+ ], [
+ 'key' => 'helloworld.settings',
+ 'name' => 'Custom Settings',
+ 'sort' => 1,
+ ], [
+ 'key' => 'helloworld.settings.settings',
+ 'name' => 'Custom Groupings',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'status',
+ 'title' => 'Status',
+ 'type' => 'boolean',
+ 'channel_based' => true,
+ 'locale_based' => false
+ ]
+ ]
+ ]
+ ];
+ ~~~
+
+### Explanation for the keys
+
+- **key** : This key accept the unique value and nested with '.' (dot) operator.
+
+- **name** : This key accept the value as a placeholder for your configuration. Generally, in Bagisto, we consider writing it using translation.
+
+- **sort** : This key accept the sort position for the configuration menu.
+
+- **fields** : This key accept the array for the value of the custom configuration.
+
+- We need to merge these custom config also,
+
+ ~~~php
+ mergeConfigFrom(
+ dirname(__DIR__) . '/Config/admin-menu.php', 'menu.admin'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/acl.php', 'acl'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/system.php', 'core'
+ );
+ }
+ }
+ ~~~
+
+- Run this command i.e. `php artisan optimize`.
+
+- Now, check the configuration,
+
+ ![Admin ACL Output](../../assets/1.x/images/package-development/admin-custom-config-output.png)
+
+## Supported Field Types
+
+There are several field types supported by the Bagisto. Let us know all of them,
+
+- Text Type
+- Number Type
+- Boolean Type
+- Select Type
+- Textarea Type
+- Image Type
+
+Let's get started with the first one.
+
+### Text Type
+
+This field type will give you the input field of type text.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'text_type',
+ 'title' => 'admin::app.admin.system.text-type',
+ 'type' => 'text',
+ 'default_value' => '',
+ ],
+ ],
+ ],
+ ...
+];
+~~~
+
+### Number Type
+
+This field type will give you the input field of type number.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'number_type',
+ 'title' => 'admin::app.admin.system.number-type',
+ 'type' => 'number',
+ ],
+ ],
+ ],
+ ...
+];
+~~~
+
+### Boolean Type
+
+This field type will give you the enable/disable switch.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'boolean_type',
+ 'title' => 'admin::app.admin.system.boolean-type',
+ 'type' => 'boolean',
+ ],
+ ],
+ ],
+ ...
+];
+~~~
+
+### Select Type
+
+This field type will give you the select field with mentioned options.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'select_type',
+ 'title' => 'admin::app.admin.system.select-type',
+ 'type' => 'select',
+ 'options' => [
+ [
+ 'title' => 'option_1',
+ 'value' => 'value_1',
+ ], [
+ 'title' => 'option_2',
+ 'value' => 'vallue_2',
+ ],
+ ],
+ ],
+ ],
+ ],
+ ...
+];
+~~~
+
+### Textarea Type
+
+This field type will give you the textarea field mostly used for long text.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'textarea_type',
+ 'title' => 'admin::app.admin.system.textarea-type',
+ 'type' => 'textarea'
+ ],
+ ],
+ ],
+ ...
+];
+~~~
+
+### Image Type
+
+This field type will give you the file upload option for uploading the images.
+
+#### Example
+
+~~~php
+return [
+ ...
+ [
+ 'key' => 'general.general.custom-types',
+ 'name' => 'admin::app.admin.system.custom-types',
+ 'sort' => 1,
+ 'fields' => [
+ [
+ 'name' => 'image_type',
+ 'title' => 'admin::app.admin.system.image-type',
+ 'type' => 'image',
+ 'validation' => 'mimes:bmp,jpeg,jpg,png,webp',
+ ],
+ ],
+ ],
+ ...
+];
+~~~
diff --git a/docs/1.x/packages/create-migrations.md b/docs/1.x/packages/create-migrations.md
new file mode 100644
index 00000000..a688ee39
--- /dev/null
+++ b/docs/1.x/packages/create-migrations.md
@@ -0,0 +1,26 @@
+# Create migrations
+
+You can create migration in two ways,
+
+1. By using Bagisto Package Generator.
+2. By normal laravel command and then manually copy to the respective folder.
+
+## By using Bagisto Package Generator
+
+This command will create a new migration class in `packages/ACME/HelloWorld/src/Database/Migrations` directory.
+
+`php artisan package:make-migration CreateUsersTable ACME/HelloWorld`
+
+## By normal laravel command and then manually copy to the respective folder
+
+To create a migration, use the `make:migration` artisan command:
+
+`php artisan make:migration create_users_table`
+
+The new migration will be placed in your `database/migrations` directory. Each migration file name contains a timestamp which allows Laravel to determine the order of the migrations.
+
+The --table and --create options may also be used to indicate the name of the table and whether the migration will be creating a new table.
+
+You may also specify a --path option when creating the migration. The path should be relative to the root directory of your installation:
+
+`php artisan make:migration create_demo_table --path=packages/ACME/HelloWorld/src/Database/Migrations`
\ No newline at end of file
diff --git a/docs/1.x/packages/create-models.md b/docs/1.x/packages/create-models.md
new file mode 100644
index 00000000..eeccb32e
--- /dev/null
+++ b/docs/1.x/packages/create-models.md
@@ -0,0 +1,23 @@
+# Create models
+
+## Create model by using Bagisto Package Generator
+
+- This command will create a following files,
+ - New model class in `packages/ACME/HelloWorld/src/Models` directory.
+ - New model proxy class in `packages/ACME/HelloWorld/src/Models` directory.
+ - New model contract in `packages/ACME/HelloWorld/src/Contracts` directory.
+
+ `php artisan package:make-model User ACME/HelloWorld`
+
+## Create model by normal laravel commands
+
+- Models typically live in the `app` directory, but you are free to place them anywhere that can be auto-loaded according to your `composer.json` file. All Eloquent models extend `Illuminate\Database\Eloquent\Model` class.
+
+- The simple way to create a model is executing the command `make:model` artisan command,
+
+ `php artisan make:model User`
+
+- After creating model, to generate database migration, you may append `--migration or -m option` artisan command as stated below,
+
+ `php artisan make:model User --migration`
+ `php artisan make:model User -m`
\ No newline at end of file
diff --git a/docs/1.x/packages/create-package.md b/docs/1.x/packages/create-package.md
new file mode 100644
index 00000000..42d3ca36
--- /dev/null
+++ b/docs/1.x/packages/create-package.md
@@ -0,0 +1,832 @@
+# Create a new package
+
+There are two ways to create a package.
+
+1. By using Bagisto Package Generator (**Recommended**)
+2. By manually setting up all files (**Expert Level**)
+
+## 1. By using Bagisto Package Generator
+
+- You need to install [Bagisto Package Generator](https://github.com/bagisto/bagisto-package-generator).
+
+- If you have not installed this package then you need to go to the root folder of **Bagisto** and run the following command
+
+ ```php
+ composer require bagisto/bagisto-package-generator
+ ```
+
+- Now, to generate your package you need to use the following command,
+
+ - If the package directory does not exist,
+
+ ```php
+ php artisan package:make ACME/HelloWorld
+ ```
+
+ - If somehow the package directory is already present then you can use the force command as well. For that you just need to pass the '**--force**' command.
+
+ ```php
+ php artisan package:make ACME/HelloWorld --force
+ ```
+
+- Now check your `packages` directory, everything is setup for you.
+
+- After that, you need to register your service provider in `config/app.php`.
+
+ ```php
+ [
+ ...
+ ACME\HelloWorld\Providers\HelloWorldServiceProvider::class,
+ ...
+ ]
+ ...
+ ];
+ ```
+
+- Add you package namespace in `psr-4` key in `composer.json` file for auto loading which is located in Bagisto root directory.
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ ...
+ "ACME\\HelloWorld\\": "packages/ACME/HelloWorld/src"
+ ...
+ }
+ ...
+ }
+ ```
+
+- Run the below listed command:
+
+ ```php
+ composer dump-autoload
+ php artisan optimize
+ ```
+
+ ```php
+ php artisan vendor:publish --force
+
+ -> Press the number before "ACME\HelloWorld\Providers\HelloWorldServiceProvider" and then press enter to publish all assets and configurations.
+ ```
+
+::: details Check output in the browser
+
+![helloworld-admin-browser-output](../../assets/1.x/images/package-development/hello-world-package-output.png)
+
+:::
+
+- Now start creating something cool.
+
+## 2. By manually setting up all files
+
+By manually setting up package, we assume that you are familiar with packages directory structures and flow. If not then you can find a basic tree structure of package below,
+
+::: details Basic tree structure of the package
+
+```
+- ACME/HelloWorld/
+ - publishable/assets
+ - css/
+ - images/
+ - js/
+ - src/
+ - Config/
+ - acl.php
+ - admin-menu.php
+ - Console/
+ - Commands/
+ - Contracts/
+ - Database/
+ - Migrations/
+ - Seeders/
+ - Events/
+ - Http/
+ - Controllers/
+ - Admin/
+ - HelloWorldController.php
+ - Shop/
+ - HelloWorldController.php
+ - Middleware/
+ - Requests/
+ - admin-routes.php
+ - shop-routes.php
+ - Listeners/
+ - Mail/
+ - Models/
+ - Providers/
+ - HelloWorldServiceProvider.php
+ - ModuleServiceProvider.php
+ - Repositories/
+ - Resources/
+ - assets/
+ - images/
+ - js/
+ - app.js
+ - sass/
+ - admin.scss
+ - default.scss
+ - velocity.scss
+ - lang/
+ - views/
+ - admin/
+ - layouts/
+ - style.blade.php
+ - index.blade.php
+ - shop/
+ - default/
+ - index.blade.php
+ - velocity/
+ - index.blade.php
+ - package.json
+ - webpack.mix.js
+```
+
+:::
+
+Let's start with first step by creating the packages folder.
+
+### Step-1
+
+- In `packages` folder, create a folder with your company name and inside that create a folder with your package name. Let's say `ACME/HelloWorld`. So, your basic structure will look like this,
+
+ ```
+ - packages/
+ - ACME/HelloWorld/
+ ```
+
+### Step-2
+
+- In your package folder, create a folder named as `src`. This is the place where you need to put all your files related to your package. Now, your updated structure will look like this,
+
+ ```
+ - packages/
+ - ACME/HelloWorld/
+ - src/
+ ```
+
+### Step-3
+
+- In `src` folder, create a folder named as `Providers` and inside that folder, create a file named as `PackagenameServiceProvider.php`. Let's say `HelloWorldServiceProvider.php`.
+
+ ::: tip
+ If you want to do this with the **Bagisto Package Generator** then you need to type the following command, it will generate the service provider for you.
+
+ ```php
+ php artisan package:make-provider HelloWorldServiceProvider ACME/HelloWorld
+ ```
+
+ If somehow the file already exists then you can use `--force` to overwrite the file.
+ :::
+
+- Copy the below code and paste it in `HelloWorldServiceProvider.php`,
+
+ ```php
+ [
+ ...
+ ACME\HelloWorld\Providers\HelloWorldServiceProvider::class,
+ ...
+ ]
+ ...
+ ];
+ ```
+
+### Step-5
+
+- Add your package namespace in `psr-4` key in `composer.json` file for auto loading which is located in Bagisto root directory.
+
+ ```json
+ "autoload": {
+ ...
+ "psr-4": {
+ ...
+ "ACME\\HelloWorld\\": "packages/ACME/HelloWorld/src"
+ ...
+ }
+ ...
+ }
+ ```
+
+- Run `composer dump-autoload`.
+
+### Step-6
+
+- Now, you need to add routing & views in your package.
+
+ - **For routes**: Create a `Http` folder in `packages/ACME/HelloWorld/src` and create two files named as `admin-routes.php` and `shop-routes.php`. So the updated structure will look like below,
+
+ ::: details Updated directory structure
+
+ ```
+ - packages/
+ - ACME/HelloWorld/
+ - src/
+ ...
+ - Http/
+ - admin-routes.php
+ - shop-routes.php
+ ```
+
+ :::
+
+ - `admin-routes.php`: This file is for the admin routes. Add below codes to this file,
+
+ ```php
+ ['web', 'admin']], function () {
+ Route::prefix(config('app.admin_url'))->group(function () {
+
+ // all admin routes will place here
+ });
+ });
+ ```
+
+ - `shop-routes.php`: This file is for the shop routes. Add below codes to this file,
+
+ ```php
+ ['web', 'theme', 'locale', 'currency']], function () {
+
+ // all shop routes will be place here
+
+ });
+ ```
+
+ ::: tip
+
+ - If you don't want to do it manually, then you can use our **Bagisto Package Generator**. For that you need to use this command,
+
+ - For **admin-routes.php**,
+
+ ```php
+ php artisan package:make-admin-route ACME/HelloWorld
+ ```
+
+ - For **shop-routes.php**,
+
+ ```php
+ php artisan package:make-shop-route ACME/HelloWorld
+ ```
+
+ :::
+
+ - **For views**: Create `Resources` folder in `packages/ACME/HelloWorld/src` path. In `Resources` folder, create another folder named as `views`. Now, in the `views` folder, we need to create a two more folder i.e. `admin` and `shop`. So updated structure will look like this,
+
+ ::: details Updated directory structure
+
+ ```
+ - packages/
+ - ACME/HelloWorld/
+ - src/
+ ...
+ - Resources/
+ ...
+ - views/
+ - admin/
+ - shop/
+ ```
+
+ :::
+
+ - Inside each folder i.e. `admin` and `shop` create a file named as `index.blade.php`. Add some data to `index.blade.php`,
+
+ - `admin/index.blade.php`
+
+ ```html
+
Hello World Admin
+ ```
+
+ - `shop/index.blade.php`
+
+ ```html
+
Hello World Shop
+ ```
+
+- Now, we need to register our routes and views to service provider’s boot method i.e. `packages/ACME/HelloWorld/src/Providers/HelloWorldServiceProvider.php`
+
+ ```php
+ loadRoutesFrom(__DIR__ . '/../Http/admin-routes.php');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Http/shop-routes.php');
+
+ $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'helloworld');
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+
+ }
+ }
+ ```
+
+### Step-7
+
+- Now, we need to create a route and render a view on that route.
+
+- Go to `packages/ACME/HelloWorld/src/Http/shop-routes.php` file and create a route to render view.
+
+ ```php
+ ['web', 'theme', 'locale', 'currency']], function () {
+
+ // all shop routes will be place here
+ Route::view('/hello-world', 'helloworld::shop.index');
+
+ });
+ ```
+
+- Same for admin routes in file `packages/ACME/HelloWorld/src/Http/admin-routes.php`.
+
+ ```php
+ ['web', 'admin']], function () {
+
+ // all admin routes will place here
+ Route::view('/admin/hello-world', 'helloworld::admin.index');
+
+ });
+ ```
+
+- Now, check your route in your browser,
+
+ ::: details Admin Output
+
+ ![Admin Browser Output](../../assets/1.x/images/package-development/helloworld-admin-browser-output.png)
+
+ :::
+
+ ::: details Shop Output
+
+ ![Shop Browser Output](../../assets/1.x/images/package-development/helloworld-shop-browser-output.png)
+
+ :::
+
+### Step-8
+
+- Now, we are going to create a language file for our package. For this create a `lang` folder in the `packages/ACME/HelloWorld/src/Resources` path.
+
+- In `lang` folder, you can create a different folder for language translations like for English 'en', Hindi ‘hn’ etc. Moving forward, we will create a folder name `en` (say language code) and in that folder, create a file name as `app.php` to perform language translation.
+
+ ::: details Updated directory structure
+
+ ```
+ - packages/
+ - ACME/HelloWorld/
+ - src/
+ ...
+ - Resources/
+ ...
+ - lang/
+ - en/
+ - app.php
+ ```
+
+ :::
+
+- Now, we need to register the language file to the service provider.
+
+ ```php
+ loadRoutesFrom(__DIR__ . '/../Http/admin-routes.php');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Http/shop-routes.php');
+
+ $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'helloworld');
+
+ $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'helloworld');
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+
+ }
+ }
+ ```
+
+- Now we can write a translation in `app.php` like below,
+
+ ```php
+ [
+ 'name' => 'Prateek Srivastava'
+ ]
+ ];
+ ```
+
+- Add below code to your blade file.
+
+ ```html
+ {{ __('helloworld::app.hello-world.name') }}
+ ```
+
+ ::: details Admin Output
+
+ ![Translation Output](../../assets/1.x/images/package-development/hello-world-admin-translation-output.png)
+
+ :::
+
+ ::: details Shop Output
+
+ ![Translation Output](../../assets/1.x/images/package-development/hello-world-shop-translation-output.png)
+
+ :::
+
+### Step-9
+
+- Now we will add CSS, JS and images to our package.
+
+- In `Resources` folder creates a folder name `assets` & create `sass`, `js` and `images` folder.
+
+ - In **sass** folder, add file **_app.scss_**
+
+ - In **js** folder, add file **app.js**
+
+::: details Updated directory structure
+
+```php
+- packages/
+ - ACME/HelloWorld/
+ - src/
+ ...
+ - Resources/
+ - assets/
+ - sass/
+ - app.scss
+ - js/
+ - app.js
+ - images/
+```
+
+:::
+
+- To add assets, create `package.json` and `webpack.mix.js` file inside the root of your package i.e. `packages/ACME/HelloWorld`.
+
+- Copy below code to `package.json`,
+
+ ```json
+ {
+ "scripts": {
+ "dev": "npm run development",
+ "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "watch-poll": "npm run watch -- --watch-poll",
+ "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "prod": "npm run production",
+ "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
+ },
+
+ "devDependencies": {
+ "cross-env": "^7.0.2",
+ "laravel-mix": "^5.0.1",
+ "laravel-mix-merge-manifest": "^0.1.2"
+ }
+ }
+ ```
+
+- Copy below code to `webpack.mix.js`,
+
+ ```javascript
+ const mix = require("laravel-mix");
+
+ if (mix == "undefined") {
+ const { mix } = require("laravel-mix");
+ }
+
+ require("laravel-mix-merge-manifest");
+
+ if (mix.inProduction()) {
+ var publicPath = "publishable/assets";
+ } else {
+ var publicPath = "../../../public/vendor/webkul/helloworld/assets";
+ }
+
+ mix.setPublicPath(publicPath).mergeManifest();
+
+ mix.disableNotifications();
+
+ mix
+ .js([__dirname + "/src/Resources/assets/js/app.js"], "js/helloworld.js")
+ .copyDirectory(
+ __dirname + "/src/Resources/assets/images",
+ publicPath + "/images"
+ )
+ .sass(
+ __dirname + "/src/Resources/assets/sass/app.scss",
+ "css/helloworld.css"
+ )
+ .options({
+ processCssUrls: false,
+ });
+
+ if (mix.inProduction()) {
+ mix.version();
+ }
+ ```
+
+- After doing this go to the root of your package i.e. `packages/ACME/HelloWorld` and run `npm install` which will install all dependencies.
+
+- Now, `app.js` and `app.scss` is ready. Write all your css and js here.
+
+- When you done with your changes, then run `npm run prod` which will compiled all your css, js and images to the publishable folder. Then register your publishable in `HelloWorldServiceProvider`,
+
+ ::: tip
+
+ You can use `npm run watch` also, this will watch all your changes and put all your changes to the public path. When you done with all your changes then run `npm run prod` to compile all your changes and move to publishable folder.
+
+ :::
+
+ ```php
+ loadRoutesFrom(__DIR__ . '/../Http/admin-routes.php');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Http/shop-routes.php');
+
+ $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'helloworld');
+
+ $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'helloworld');
+
+ $this->publishes([
+ __DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/helloworld/assets'),
+ ], 'public');
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+
+ }
+ }
+ ```
+
+- After doing this we need to add an event listener so that admin layouts include our CSS. For this we need to add an Event Listener in service provider. But before adding event, let's create a `layouts` folder in `packages/ACME/Test/src/Resources/views/admin` and inside that create a file called `style.blade.php` & mention compiled CSS path inside this file.
+
+ ```html
+
+ ```
+
+- **For Event Listener:** Add facade 'Event' into your `HelloWorldServiceProvider.php` file,
+
+ ```php
+ loadRoutesFrom(__DIR__ . '/../Http/admin-routes.php');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Http/shop-routes.php');
+
+ $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'helloworld');
+
+ $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'helloworld');
+
+ $this->publishes([
+ __DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/helloworld/assets'),
+ ], 'public');
+
+ Event::listen('bagisto.admin.layout.head', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('helloworld::admin.layouts.style');
+ });
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+
+ }
+ }
+ ```
+
+- Till now, we configured our package HelloWorld and now we need to extend the default layout of our admin panel by using `@extends('admin::layouts.master')` in file `packages/ACME/HelloWorld/src/Resources/views/admin/index.blade.php`. Below is the simple template which you can copy to your `index.blade.php` file,
+
+ ```html
+ @extends('admin::layouts.master') @section('page_title') Package HelloWorld
+ @stop @section('content-wrapper')
+
+