View, search, filter, and manage all products in the system.
| Filter Field | Description |
|---|---|
| Product Name | Partial search by product name. |
| SKU | Search by product or variant SKU code. |
| Category | Filter products by category. Supports searching all subcategories. |
| Brand | Filter by product brand. |
| Status | Filter by status: Active, Inactive, Draft. |
| Created Date | Filter by product creation date range (from date – to date). |
| Column | Description |
|---|---|
| Image / Name | Thumbnail image and product name; click to edit. |
| SKU | SKU code of the default variant. |
| Price | Original price and promotional price (if any). Shows the lowest price when multiple variants exist. |
| Stock | Total remaining quantity in stock (sum of all variants). |
| Category | Primary category of the product. |
| Brand | Product brand (if any). |
| Status | Display status on the website. |
| Created Date | Product creation time. |
Tick-select multiple products, then choose an action from the dropdown to apply all at once:
| Action | Description |
|---|---|
| Change Status | Toggle Active/Inactive status for multiple products at once. |
| Delete | Move products to the trash (soft delete). |
| Restore | Restore products from the trash back to the list. |
| Export Excel | Export the selected products to an Excel file. See more at Export Products. |
Create a new product or edit an existing product's information.
| Field | Required | Description |
|---|---|---|
| Product Name | ✓ Required | The display name of the product on the website. |
| Page URL (Slug) | ✓ Required | The product page address on the website, automatically generated from the product name. Can be edited if needed. |
| Product Type | ✓ Required |
Physical
— goods delivered via shipping. Digital — digital products; customer receives an attached file after payment. |
| Short Description | Optional | Product summary, typically displayed on listing pages and search results. |
| Detailed Content | Optional | Full product description. Composed using a rich text editor. |
| Specifications | Optional | Key–value specification table (stored as JSON). Displayed in the Specifications tab on the product detail page. |
| Thumbnail Image | Optional | The main product image, displayed on listing and detail pages. |
| Image Gallery | Optional | Multiple images for the product detail page. |
| Category | ✓ Required | Primary category. Additional secondary categories can also be selected. |
| Brand | Optional | Product brand. Used for brand filtering on category pages and search. |
| Product Label | Optional | Assign one or more labels (Hot, New, Sale...) to display badges on the product image. |
| Status | ✓ Required | Active to display the product on the website. |
| Field | Required | Description |
|---|---|---|
| Original Price | ✓ Required | Listed selling price of the product (or variant). |
| Promotional Price | Optional | Discounted price. If filled in, the website will show the strikethrough price and discount percentage. |
| SKU | Optional | Variant identifier code, used for inventory lookup and import/export management. |
| Stock Quantity | Optional | Quantity in stock. Automatically decremented when an order is Completed. |
| Weight (grams) | Optional | Used for weight-based shipping fee calculation. Defaults to 300g if left blank. |
Products support variants (e.g., color, size). Each variant has its own price, SKU, stock, and warranty duration.
- Create Attributes (e.g., Color, Size) at Products › Attributes.
- Add Attribute Values (e.g., Red, Blue, S, M, L).
- In the product form, select attributes and the system automatically generates variants.
- Fill in price / SKU / stock / warranty duration for each variant individually.
| Variant Field | Description |
|---|---|
| Warranty Duration |
Number of warranty units (e.g.,
12 months,
2 years). Ignored if
Lifetime is selected.
|
| Warranty Type |
month
— Month year — Year lifetime — Lifetime warranty (no quantity needed) |
The Warranty Information tab in the product form contains a free-text editor field to describe the warranty policy displayed on the product detail page.
| Field | Required | Description |
|---|---|---|
| Warranty Information | Optional | HTML content composed via CKEditor. Detailed description of warranty conditions, scope, and process for the product — displayed in the Warranty tab on the product detail page. |
The Related Products tab includes two fields to suggest additional products to customers on the detail page.
| Field | Required | Description |
|---|---|---|
| Related Products | Optional | Select similar or alternative products. Displayed in the Related Products section at the bottom of the detail page. Stored as a comma-separated ID string. |
| Bundled Accessories | Optional | Select accessory products sold alongside (e.g., phone case, charging cable). Displayed in the Accessories section on the detail page. Stored as a comma-separated ID string. |
Filters help customers narrow down products by criteria such as RAM, color, size, etc. on category pages. The system loads automatically when the admin selects a Category in the form.
- Each category can be assigned its own Filter groups — configure at Products › Filters and assign to the category on the category edit page.
- When selecting a category in the product form, the Filters section loads via AJAX and displays checkboxes belonging to that category's filter groups.
- Admin checks the appropriate filter values for the product (e.g., RAM 8GB, Color Black).
-
Values are saved to the
product_filter_mapstable linking the product to filter values.
| Field | Description |
|---|---|
| SEO Title |
The
<title> tag for the
product page. Defaults to the product name
if left blank.
|
| SEO Description |
The
<meta
description>
— a brief summary displayed in Google
search results.
|
| OG Image | Image displayed when sharing the product link on social media (Open Graph image). |
Export the product list and variants to an Excel file based on the current filters. Useful for backup, reconciliation, or bulk editing and re-importing.
- Go to the Product List page.
- Apply the desired filters (name, category, status, product type, creation date range).
- Click the Export Excel button on the action bar.
-
The system generates a
products_{timestamp}.xlsxfile and returns it for download.
| Parameter | Description |
|---|---|
name
|
Filter product name by keyword (LIKE). |
category_id
|
Export only products belonging to the selected category. |
product_type
|
Filter by type: physical, digital. |
status
|
Filter by status. If left blank, exports all Active, Deactive, and Draft. |
created_at_start /
created_at_end
|
Product creation date range. |
The exported file has the same column structure as the Import template, so it can be reused for editing and re-importing.
- No — row number.
- Slug, Name — identifier and product name.
- Attribute — list of product attributes.
- Id, Variant name, Variant attribute — variant information.
- Content, Description — detailed description and short description.
- Brand, Category — brand and category.
- Sku, Price, Price origin, Quantity, Weight — sales and inventory information per variant.
- Avatar, Slide images — thumbnail and slide images.
- Seo title, Seo description — SEO data.
- Product type, Digital attachments — product type and attached files for digital products.
slug.
During export, the system loads all relationships to ensure the data file is complete:
-
productAttributes— list of product-level attributes. -
productVariants+variantAttributeValues+productAttribute+attributeValue— sufficient information to reconstruct variants. -
productVariants.productWarehouse— stock quantity. -
brand,category,seo— classification and metadata.
- The system temporarily raises the timeout to 3600s and memory to 300MB to handle large files.
- For very large lists (≥ 10,000 variants), it is recommended to export by category or by date range to reduce server load and output file size.
-
On low-resource environments, consider increasing
memory_limitinphp.iniif out-of-memory errors still occur.
products_exports. Without this permission,
the system will block access and redirect to the previous
page with a warning.
Bulk import products from an Excel/CSV file into the system. Supports importing with variants, thumbnail images, slide images, SEO data, and categories.
- Go to the Product List page, click the Import button above the table.
- Download the template file in the popup to learn the correct column structure.
-
Fill in data in the template file: each row is
a variant; variants sharing the same
slugare grouped into one product. -
Return to the popup, select a
.xlsx,.xlsor.csvfile. -
Check
Download images to server
(
save_image) if you want the system to automatically download images from URLs in the file topublic/uploads. -
Click Import. The system pushes data
into the queue (every 5 products per
ImportProductExceljob) and returns a notification with the number of products queued.
| Column | Required | Description |
|---|---|---|
| Slug | Required |
Unique identifier of the product.
Rows sharing the same
slug are grouped into
one product with multiple variants.
|
| Name | Required | Main product name. |
| Attribute | Optional | Product attributes (e.g. Color, Size). |
| Id | Optional | Variant ID if needed for update mapping. Leave empty when creating new. |
| Variant name | Optional | Variant name, e.g. Black T-shirt size M. |
| Variant attribute | Optional | Variant attribute values, in the form Color: Black, Size: M. |
| Content | Optional | Detailed description content (may contain HTML). |
| Brand | Optional | Brand name. If it doesn't exist, the system will create it automatically. |
| Category | Optional | Category name. Can be multi-level, separated according to the structure in the template file. |
| Sku | Optional | SKU code for the variant. Should be unique for easier inventory/price management. |
| Price | Optional | Sale price. Leave empty for a contact-for-price product. |
| Price origin | Optional | Original price (strikethrough price) to display promotional pricing. |
| Quantity | Optional | Initial stock quantity for the variant. |
| Warranty Duration | Optional | Warranty duration. |
| Warranty type | Optional | Warranty type: month, year, lifetime |
| Weight | Optional | Weight (grams) — used for shipping fee calculation. |
| Width | Optional | Width (cm) — used for shipping fee calculation. |
| Height | Optional | Height (cm) — used for shipping fee calculation. |
| Length | Optional | Length (cm) — used for shipping fee calculation. |
| Avatar | Optional |
Thumbnail image. Can be a URL or a relative
path within
uploads/.
|
| Slide images | Optional | List of slide images, separated by commas. |
| Seo title / description | Optional | SEO title and description. |
| Description | Optional | Short description displayed just below the product name. |
- The file is parsed using PhpSpreadsheet, reading according to standard columns in the template file.
-
Data is grouped by
slug; each group of 5 products is pushed into one jobDreamTeam\Ecommerce\Jobs\ImportProductExcel. - Jobs run asynchronously in the default queue, so a queue worker must be running for data to actually be created.
-
If Download images to server is enabled,
image URLs will be downloaded to
public/uploads; if disabled, the original URLs are kept. - Timeout/memory are temporarily increased (3600s, 300MB) to prevent failures when importing large files.
products_import. Without this permission
the request will be blocked at the submit step.
Organize products into groups, supporting multi-level parent-child structure.
| Field | Required | Description |
|---|---|---|
| Category name | ✓ Required | Display name on the website. |
| Page URL | ✓ Required | Category page address on the website. Auto-generated from the category name. |
| Parent category | Optional | Select to create a subcategory. Supports multiple levels. |
| Description | Optional | Short description for the category, displayed on the product listing page. |
| Thumbnail image | Optional | Thumbnail image representing the category. |
| Status | ✓ Required | Active to display the category on the website. |
Each category can be configured with its own filters displayed on the listing page. For example: the Shirts category can filter by Color, Size; the Shoes category filters by Size, Material.
Go to Products › Filters to create a filter, then assign it to a category in the category edit page.
Manage product brands, helping customers easily identify and filter by brand.
| Field | Required | Description |
|---|---|---|
| Brand name | ✓ Required | Display name on the website, helping customers identify products by brand. |
| Logo | Optional | Logo representing the brand. |
| Description | Optional | Short description about the brand. |
| Sort order | Optional | Display order in the brand list. |
| Status | ✓ Required | Active to display the brand on the website. |
Create labels displayed on products (New, Hot, Sale, Out of stock...) to attract buyers.
| Field | Required | Description |
|---|---|---|
| Label name | ✓ Required | Text displayed on the label (e.g.: New, Hot, -50%). |
| Background color | Optional | Background color of the label. |
| Text color | Optional | Text color displayed on the label. |
| Status | ✓ Required | Enable so the label can be assigned to products. |
After creating a label, go to the Add / Edit Product page and select the label in the Product Label section. A product can have multiple labels assigned at once.
Labels will be displayed in the top corner of the product image on the product listing page and product detail page.
Create time-limited promotional programs with special prices for individual product variants. A countdown timer is displayed directly on the website.
| Field | Required | Description |
|---|---|---|
| Flash Sale name | ✓ Required | Display name of the promotion (e.g.: Friday Flash Sale). |
| URL (Slug) | ✓ Required | URL of the Flash Sale page on the website. Auto-generated from the name. |
| Banner image | Optional | Representative image displayed on the Flash Sale page and shortcode. |
| End time | Optional | The time the Flash Sale automatically ends. Leave empty = runs until sold out. The countdown timer on the website is based on this field. |
| Status | ✓ Required | Active for the Flash Sale to take effect on the website. |
Each Flash Sale can contain multiple products (per variant). Configure individual prices and limited quantities for each variant:
| Field | Required | Description |
|---|---|---|
| Product / Variant | ✓ Required | Search and select a product or specific variant to join the Flash Sale. |
| Flash Sale price | ✓ Required | Special price during the Flash Sale period. Replaces the listed price while the promotion is running. |
| Limited quantity | Optional |
Total quantity available at the
Flash Sale price. Set 0 =
unlimited. When sold out
(quantity_used >=
quantity), the product automatically reverts to the
regular price.
|
-
The Flash Sale price is joined directly into
the product query via
scopeQueryVariant— no additional relation loading needed. -
Flash Sale data is cached for 30 days
(
cache_flash_sales). Cache is automatically cleared when the promotion is updated. - A variant can belong to multiple Flash Sales, but the system only uses the Flash Sale with the lowest price that still has stock and has not expired.
-
When an order is Completed,
quantity_usedof the Flash Sale increases accordingly.
View, process and track all customer orders. Supports manual order creation, payment confirmation, refunds and Export Excel.
| Filter field | Description |
|---|---|
| Order code | Search exactly or partially by order code. |
| Customer name | Search by name of the customer who placed the order. |
| Phone number | Search by customer phone number. |
| Order status | Filter by status: New, Received, Delivering, Completed, Cancel Requested, Cancelled. |
| Payment method | Filter by COD, bank transfer, payment gateway. |
| Payment status | Filter by Paid / Unpaid / Refunded. |
| Created date | Filter orders by date range (from date – to date). |
Status flow: New → Received → Delivering → Completed. Can be cancelled at the Received or Delivering step (if a tracking code exists).
| Status | Admin action | Meaning |
|---|---|---|
| New 1 | Receive | Order just placed, not yet processed. Admin clicks Receive to move to the next step. |
| Received 2 | Start delivery / Cancel | Preparing goods. Admin can click Start delivery or Cancel order (stock is restored). |
| Delivering 21 | Complete / Cancel delivery | Goods handed to the shipping carrier. Can cancel delivery if the carrier supports the API. |
| Cancel Requested 31 | Approve cancel / Reject | Customer sent a cancellation request. Admin can Approve cancel (restore stock) or Reject (keep order going). |
| Completed 4 | — | Customer successfully received the goods. Stock has been deducted. |
| Cancelled 3 | — | Order cancelled. Stock is automatically restored. |
Admin can create an order on behalf of a customer via the Add Order button. The system automatically creates a user account if the email doesn't exist.
| Field | Required | Description |
|---|---|---|
| Customer | Optional | Search for an existing customer or enter new information (name, phone, email). |
| Shipping address | ✓ Required | Province/City, District, Ward/Commune, detailed address. |
| Products | ✓ Required | Search and add product variants + quantity. The system checks stock in real time. |
| Payment method | ✓ Required | COD, bank transfer or payment gateway methods. |
| Coupon code | Optional | Select from the list or enter a coupon code. The system automatically calculates the discount and saves the history. |
| VAT information | Optional | Company name, VAT email, tax code, VAT address. |
| Note | Optional | Internal note about the order. |
Click on the order code to view details. Actions that can be performed here:
| Action | Description |
|---|---|
| Confirm payment | Changes payment status from Unpaid to Paid. Sends a notification email to the customer. |
| Refund | Refund part or all of the payment amount. Enter the amount + reason. Supports refund via payment gateway API if the gateway supports it. |
| Edit customer information | Edit the name, phone, email, shipping address of the order (does not affect the user account). |
| Change shipping method | Change the carrier/shipping method when the order is at Received status. |
| Admin note | Add an internal note (not visible to customers). Saved to order history. |
| View history | All status changes, notes, payment confirmations are recorded chronologically. |
Click the Export Excel button on
the order list to download a
.xlsx file. Data is exported according to the currently applied filter
(status, created date, customer...). Requires the
orders_export permission.
Manage return, exchange or warranty requests from customers after receiving their order.
| Filter field | Description |
|---|---|
| Contact name | Search by name of the customer who submitted the request. |
| Phone number | Search by contact phone number. |
| Status | Filter by: Pending, Processing, Completed, Rejected. |
| Created date | Filter by time range of request submission. |
| Status | Meaning |
|---|---|
| Pending 1 | New request from customer, not yet received by admin. |
| Processing 2 | Admin is reviewing and contacting the customer. |
| Completed 3 | Request has been resolved (exchange / refund / warranty completed). |
| Rejected 4 | Request was not approved (does not meet return/warranty conditions). |
| Field | Description |
|---|---|
| Related order | ID of the original order the customer wants to return/warranty. |
| Reason |
Reason the customer submitted the request: defective — Defective product wrong_item — Wrong item delivered damaged — Product damaged during shipping no_longer_needed — No longer needed other — Other reason |
| Support type |
Type of support the customer requests: refund — Refund replacement — Exchange warranty — Warranty |
| Attached images | Photos of the defective/damaged product sent by the customer. |
| Contact information | Customer name, phone, email for admin to contact for processing. |
| Processing history | Records all status changes and admin notes chronologically. |
Create and manage discount coupon codes. Supports percentage or fixed-amount discounts, with limited scope by customer, category, product or brand.
| Field | Required | Description |
|---|---|---|
| Coupon name | Optional | Internal name to distinguish the coupon (displayed in admin, not shown to customers). |
| Coupon code | ✓ Required |
The string customers enter at checkout (e.g.:
SALE50). Case-insensitive.
|
| Description | Optional | Description of application conditions, used to display on the cart/checkout interface. |
| Internal note | Optional | Note for the admin team, not visible to customers. |
| Image | Optional | Illustrative image for the coupon, used to display in banners or coupon shortcodes. |
| Discount type | ✓ Required |
Percentage
— discount by percentage of order value. Fixed amount — discount a fixed amount. |
| Discount value | ✓ Required | The percentage or amount to be discounted. |
| Maximum discount | Optional | Only applies when the type is Percentage — limits the maximum discount amount. |
| Minimum order value | Optional | The order must reach this minimum for the code to be applied. |
| Maximum usage times | Optional | Total number of times the coupon can be used across the system. Leave empty = unlimited. |
| Start date | Optional | The code is only valid from this date onward. |
| Expiry date | Optional | After this date the code will automatically become invalid. |
| Status | ✓ Required | Active for the code to be valid. |
Each coupon can limit its applicable scope. Choose one of 5 types:
| Type | Description |
|---|---|
| All 0 | Apply to all orders, with no scope restriction. |
| Specific customers 1 | Only applies to designated customer accounts. Suitable for personalized promotions. |
| Category 2 | Only discounts when the cart contains products belonging to the selected category. |
| Product 3 | Only discounts when the cart contains the specifically designated products. |
| Brand 4 | Only discounts when the cart contains products belonging to the selected brand. |
In the coupon list, the
Used column shows the number of times
the coupon has been successfully applied. Each
application is recorded in the
coupon_useds table along with order info, user, and price before/after discount.
Manage consolidated stock inventory by product and variant, with Excel import/export support.
The warehouse page displays all products and variants with their current stock quantity. You can edit the quantity directly in the table without going into each individual product.
| Column | Description |
|---|---|
| Product name | Product name and thumbnail image. |
| SKU | Product / variant identifier code. |
| Variant | Variant attribute name (color, size...) if available. |
| Stock | Current quantity. Can be edited directly. |
Supports bulk stock updates via Excel file:
- Click Export Excel to download a template file with the current product list.
- Edit the Quantity column in the file.
- Click Import Excel, select the edited file, and the system will update the stock.
Detailed documentation of all options in the Advanced Settings of Ecommerce.
ec_advanced. After changing a value,
the system automatically clears the cache. If you still
don't see the change, go to Admin → Clear cache.
| Option | Value | Description |
|---|---|---|
| Enable cart | Yes / No | Enable the shopping cart and checkout flow. Disabling will hide the "Add to cart" button and the cart page — suitable for catalog/quote-only websites. |
| Enable wishlist | Yes / No | Allow customers to save products to their wishlist, viewable in their account. |
| Enable product comparison | Yes / No | Display a Compare button on product cards. Customers can select multiple products to compare attributes. |
| Enable "Buy Now" button | Yes / No | Show an additional Buy Now button next to the Add to Cart button. Clicking it opens the quick-buy flow bypassing the cart page. |
| Allow product reviews | Yes / No | Enable the star rating + review system for products. |
| Option | Value | Description |
|---|---|---|
| Show product schema | Yes / No | Enable to inject schema.org Product (JSON-LD) into the detail page, helping Google understand the product and display rich snippets. |
| Option | Value | Description |
|---|---|---|
| Show address at checkout | Yes / No | Enable to require entering province/district/ward during checkout. Recommended for physical goods; disable for digital products. |
| Require email | Yes / No | Require customers to enter their email when ordering. Disable if email is not needed (phone number only). |
| Require phone number | Yes / No | Require phone number when ordering. Recommended to enable. |
| Show Captcha at checkout | Yes / No |
Enable captcha to prevent order spam.
Requires the
form-custom plugin and
reCAPTCHA configured.
|
| Allow guest checkout | Yes / No | Allow guests to order without an account. Disabling will require registration/login before checkout. |
| Option | Value | Description |
|---|---|---|
| Show Country | Enable / Disable | Show country dropdown in checkout form. Useful when selling internationally. |
| Show Company | Enable / Disable | Show the company name field (B2B). Customers can fill it in if they need a company invoice. |
| Show Room/Apartment Number | Enable / Disable | Show the apartment/room number field. Suitable for condominiums or office buildings. |
| Option | Value | Description |
|---|---|---|
| Terms agreement | Automatic / Manual |
Automatic: the system pre-checks the agreement checkbox. Manual: customers must manually tick the agreement box before they can checkout. |
| Option | Value | Description |
|---|---|---|
| Shop page | Static Page | Select the page representing the product listing. Used to build the shop URL and as the breadcrumb root. |
Select the corresponding static Pages to link in the footer/checkout. Leave blank if not applicable.
| Link | Description |
|---|---|
| Payment security policy | Page about security during online payment. |
| Payment policy | Accepted payment methods and regulations. |
| Complaint resolution policy | Process for receiving and handling customer complaints. |
| Warranty policy | Warranty conditions and duration for products. |
| Return & refund policy | Regulations on returns and refunds for customers. |
| Shipping policy | Shipping fees, delivery time, shipping partners. |
| Consumer dispute resolution mechanism | In accordance with consumer protection regulations. |
View, search, filter and manage all published posts.
The list page displays all posts in a table format, including: post title, author, category, published date, SEO score and status.
| Filter field | Description |
|---|---|
| Post title | Search by post title (partial match). |
| Slug | Search by the post's SEO-friendly URL. |
| Category | Filter posts by a specific category. |
| Created date | Filter by post date range (from date → to date). |
| Status | Filter by Active / Inactive / Trash. |
| Action | Description |
|---|---|
| Edit | Click the post title or pencil icon to go to the edit page. |
| Duplicate | Copy all post content to a new draft for editing. |
| Delete / Restore | Move the post to trash. Can be restored or permanently deleted from the Trash tab. |
| Bulk status change | Select multiple posts → choose action → Apply. |
| Export Excel | Export the post list to an .xlsx file (requires posts_exports permission). |
Create and publish a new post on the system.
| Field | Required | Description |
|---|---|---|
| Title | ✓ Required |
The post title, displayed
on the website interface and the
<title> tag.
|
| Slug (URL) | ✓ Required | SEO-friendly URL. Auto-generated from the title; can be edited manually. |
| Short description | Optional | Post excerpt, commonly used for listing pages and the meta description tag. |
| Content | ✓ Required | Full post content. Edited with a WYSIWYG editor. |
| Thumbnail | Optional | Thumbnail image displayed in listings and as the OG image when sharing on social media. |
| Category | Optional | Select one or more categories for the post. |
| Author | Optional | Select the author from the admin user list. Defaults to the logged-in user. |
| Language | Optional | Select the post language if the system runs in multi-language mode. |
| Featured | Optional | Mark the post as featured (highlighted) to prioritize its display. |
| Status | ✓ Required | Active = visible, Inactive = hidden from website. |
| Field | Description |
|---|---|
| SEO Title | A separate SEO title, different from the post title (if you want to optimize for a different keyword). |
| SEO Description | Meta description displayed in Google search results. Recommended: 150–160 characters. |
| SEO Keywords | SEO keywords for the post (has little impact on current rankings). |
-
Go to Posts → Add Post.
-
Enter the Title. The Slug will be auto-generated; edit if needed.
-
Write the Content in the editor. Upload images directly into the editor or via the Media Library.
-
Select a Category and upload a Thumbnail.
-
Fill in SEO Title and SEO Description in the SEO tab.
-
Set the status to Active and click Save.
Organize posts by topic or subject area.
| Field | Required | Description |
|---|---|---|
| Category name | ✓ Required | The display name of the category on the website. |
| Slug | ✓ Required |
Category URL. Auto-generated from the
name, e.g.:
tin-tuc.
|
| Parent category | Optional | Select a parent category to create a subcategory structure. |
| Description | Optional | Short description for the category, typically displayed on the category listing page. |
| Thumbnail | Optional | Thumbnail image representing the category. |
| Status | ✓ Required | Active to display the category on the website. |
Configure the display and behavior of the post module:
sidebar, comments, SEO schema, "read more" button and
default news page. Configuration is saved with
setting_name = 'post_setting'.
| Option | Default | Description |
|---|---|---|
| Show Sidebar | Yes |
Enable/disable sidebar widget on
the post detail page and category pages. Helper:
BlogHelper::isSidebarEnabled().
|
| Allow comments | Yes |
Enable/disable comments on
all posts. When disabled, the comment form
is completely hidden even if the Comment module is active. Helper:
BlogHelper::isCommentEnabled().
|
| Show Default Schema | Yes |
Automatically inject JSON-LD Schema.org
(Article /
NewsArticle) into the
<head> of the
post detail page to optimize SEO
and rich results. Helper:
BlogHelper::isSchemaEnnabled().
|
| "Read more" button | No |
Display a content truncation button — long posts are
cut after X characters with a "Read more" button to expand. Helper:
BlogHelper::isViewMoreEnnabled().
|
| Select news page | — |
Link to the Page that will display
the post list. The system uses this ID to build
the breadcrumb and hierarchical URL.
Helper:
BlogHelper::blogPageId().
|
The number of posts displayed on the list and category pages is configured at Settings → Reading Settings, field "Posts per page".
The Post module injects this field into the Reading
Settings page via the hook
BASE_FILTER_ADD_PAGINATION_CONFIG
with key post_paginate, default value 10. In code, retrieve it with:
$readingConfig['post_paginate'] ??
10.
View, search, filter and manage all static pages on the system.
The list page displays all static pages in a table format, including: page name, URL (slug), order, SEO score and status.
| Filter field | Description |
|---|---|
| Page name | Search by static page title (partial match). |
| Slug | Search by the page's SEO-friendly URL. |
| Created date | Filter by page creation date range (from date → to date). |
| Status | Filter by Active / Inactive / Trash. |
| Action | Description |
|---|---|
| Edit | Open the static page content edit form. |
| Delete | Move the page to trash. Can be restored or permanently deleted afterward. |
| View on site | Open the static page on the website in a new tab. |
Create a new static page or edit an existing page's content.
| Field | Required | Description |
|---|---|---|
| Title | ✓ Required |
Page name, displayed in menus,
breadcrumbs and the
<title> tag.
|
| Slug (URL) | ✓ Required |
SEO-friendly URL. Auto-generated from the title;
can be edited manually. Example:
gioi-thieu.
|
| Content | Optional | Full page content. Edited with a WYSIWYG editor. |
| Thumbnail | Optional | Thumbnail image displayed when sharing the page on social media (OG image). |
| Language | Optional | Select the page language if the system runs in multi-language mode. |
| Status | ✓ Required | Active — visible on website; Inactive — hidden from website. |
| SEO field | Description |
|---|---|
| SEO Title | Title displayed in Google search results. Recommended: under 60 characters. |
| Meta Description | Short description for Google. Affects click-through rate. Recommended: under 160 characters. |
| Meta Keywords | Keywords related to the page content (little effect on modern SEO). |
-
Go to Static Pages → Add New Page.
-
Enter the Title — a slug will be automatically generated.
-
Write the Content with the editor.
-
Switch to the SEO tab to fill in the SEO Title and Meta Description.
-
Select a Status and click Save.
The Warranty module allows you to manage the full lifecycle of serial codes: from creating batches, printing QR codes, to activation and customer lookup, with automatic counterfeit detection.
- Workspace Setup — Create workspaces to separate warranties by brand / product line. Each workspace has its own prefix embedded in every serial code.
-
Product Linking — Products
and variants are managed in the Ecommerce module.
Each variant has
warranty_durationandwarranty_time_typefields defining the default warranty period. - Create Warranty Batch — Admin creates a batch, selects the product/variant, quantity and period. The system queue generates serials + QR codes in the background.
- Export QR / Serials — After the batch is complete, export a PDF of QR codes or an Excel file of serials for printing labels / distribution.
- Customer Activation — The customer scans the QR or enters the code on the activation page, fills in their name / phone / email, confirms, and receives their expiry date.
- Warranty Lookup — Customers can look up warranty status at any time using a serial code or phone number.
- Counterfeit Detection — The system automatically records cases such as: non-existent codes, blocked codes, activation by a different person, and classifies risk level (HIGH / MEDIUM / LOW).
The activation page is configured at Settings › Activation Page. The process consists of 3 steps:
| Step | Description |
|---|---|
| 1. Enter code |
The customer enters the serial code (e.g.:
STA067331766) or
scans the QR. The system verifies immediately.
|
| 2. Enter information | If the code is valid and not yet activated: the customer fills in their name, phone number and email. |
| 3. Confirm | A modal displays: serial, product name, SKU, activation date, warranty period. The customer clicks confirm to complete. |
warranty_duration and
warranty_time_type of the product variant.
| Scenario | Risk level | System action |
|---|---|---|
| Code does not exist in DB | HIGH |
Display counterfeit warning,
guide customer to contact hotline/email.
Log
counterfeit_reports
with reason
serial_not_exist.
|
| Code has been deactivated | HIGH |
Refuse activation. Log reason
blocked_serial.
|
| Code already activated by another person | HIGH |
Display the previous activation date and expiry date. Log reason
already_activated.
|
| Code already activated by this customer | — | Show friendly message "You have already activated this code before" — no warning is created. |
| Multiple activations in a short period | MEDIUM |
Log reason
multiple_attempts
along with IP and User-Agent.
|
The lookup page is configured at Settings › Lookup Page. Customers can search by:
- Serial code — Enter the full serial code.
- Phone number — Enter the phone number used during activation.
Results display: serial code, status (Activated), product, warranty period, activation date, expiry date, registered customer information.
| Table | Model | Description |
|---|---|---|
workspaces
|
Workspace | Warranty organization unit. Has its own prefix embedded in the serial. |
qr_batches
|
SerialNumberBatch | Warranty batch. Linked to product + variant. Generates serials via queue. |
serials
|
SerialNumber | Each individual serial/QR code. Linked to batch + workspace + product_variant. |
warranties
|
Warranty | Activated warranties. Stores customer information, activation date, expiry date. |
counterfeit_reports
|
CounterfeitReport | Counterfeit warnings. Stores IP, User-Agent, detection reason, risk level. |
Create and manage serial/QR code batches. Each batch is linked to a specific product variant and generates codes in the background via the queue system.
| Filter field | Description |
|---|---|
| Batch name | Search by warranty batch name. |
| Product name | Search by the product/variant name linked to the batch. |
| Batch status |
Processing (0)
— codes being generated Completed (1) — all codes generated Failed (3) — error during generation |
| Created date | Filter by batch creation date range. |
Click "Create New Batch" to open the popup. Fill in the following fields:
| Field | Required | Description |
|---|---|---|
| Batch name | ✓ Required | Identifying name for the batch (e.g.: Batch January 2025). Maximum 191 characters. |
| Product | ✓ Required | Select the product from the Ecommerce module. |
| Variant | ✓ Required | Select the specific product variant. Each batch is linked to exactly one variant. |
| Quantity (qty) | ✓ Required | Number of serial codes to generate. Minimum 1, maximum 10,000 per batch. |
| Warranty period | ✓ Required |
Number of warranty time units (e.g.:
12).
|
| Period type | ✓ Required |
month
— Month(s) year — Year(s) lifetime — Lifetime |
- Click "Download Excel Template" — the template file is auto-populated with the existing workspace + product list.
-
Fill in the 3 required columns:
Batch Name,Quantity,Warranty Period. Keep theWorkspace IDandProduct IDalready present. - Click "Import" and upload the completed file.
- The system validates each row, creates batches for valid rows, and reports errors for invalid rows.
| Action | Description |
|---|---|
| Export Excel (batch list) |
Export the currently filtered
batch list to a
.xlsx file.
Includes: batch name, product,
workspace, quantity, validity,
status, creator, created date.
Permission:
qr_batches_exports.
|
| Export Serial Excel (by batch) |
Export all serial codes of a
batch to a
.xlsx file. Each
row is an activation URL
(?code=SERIAL).
Permission:
serials_exports.
|
| Export QR PDF (by batch) |
Generate a PDF file containing
QR codes for all serials in the
batch. Runs in the background
via Job
ExportQrCodeJob.
When complete, the system sends
an email with the PDF link to
the current admin. Permission:
serials_exports.
|
| Download Generated PDF | If the PDF already exists, click "View PDF" to open it directly without regenerating. |
| Status | Meaning |
|---|---|
| Processing 0 | Queue is running, serial generation jobs not yet complete. |
| Completed 1 | All serials have been generated, batch is ready for export. |
| Being Processed 2 | Batch job is running but has not reported completion. |
| Failed 3 | Job failed. Check system logs for the cause. |
warranties table.
A list of all serial codes generated from batches. Each code is linked to a QR code and tracks the activation status for each customer.
| Filter field | Description |
|---|---|
| Batch name | Filter serials belonging to a specific batch (search by batch name). |
| Serial code | Partial search by serial string (LIKE). |
| Activation status |
Not activated (0)
— code is still available Activated (1) — customer has registered warranty |
batch_id filter is
automatically filled — the list only
shows serials belonging to that batch.
| Column | Description |
|---|---|
| Batch name | The Warranty Batch this serial belongs to. |
| Serial code |
Unique code string, e.g.
STA067331766.
Includes a QR link for printing
or sharing.
|
| Product name | Name of the product variant linked to the batch. |
| Warranty period | Number of months/years of warranty saved when the batch was created. |
| Created date | The time the serial was generated. |
| Activation date | The time the customer completed activation. Empty if not yet activated. |
| Expiry date | Calculated from activation date + warranty period. Empty if not yet activated. |
Click "Export Excel" to export all serials based on the current filter. If viewing serials of a specific batch, the exported file will only contain serials from that batch.
-
Each row is a complete activation URL:
SERIAL. - The file can be used for input into a QR printer or shared with distribution partners.
-
Required permission:
serials_exports.
Admin can change the serial status to
Inactive
(status = 0) to deactivate it. A
deactivated serial will not allow customer
activation and will be recorded as
blocked_serial in counterfeit
reports if someone attempts to activate it.
A list of all warranties successfully activated by customers. Each record stores customer information, serial, product, and remaining warranty period.
| Filter field | Description |
|---|---|
| Customer name | Search by the registered customer's full name. |
| Search by the email address used during activation. | |
| Phone number | Search by contact phone number. |
| Activation date | Filter by the time period the customer completed activation. |
| Column | Description |
|---|---|
| Customer information | Full name, phone number, and registered email. |
| Warranty information | Serial code, warranty period, activation date, and expiry date. |
| Product | Name of the product variant for which warranty was activated. |
| Activation date | The time the customer confirmed successful activation. |
Click the detail view icon to open the full page of a warranty. Information displayed includes:
| Information | Description |
|---|---|
| Serial code | The activated serial, along with batch and workspace information. |
| Product / Variant | Name and SKU of the product variant. |
| Customer information | Full name, phone number, email. This data is only visible to admins with the appropriate permissions. |
| Activation date | The exact time the customer clicked confirm. |
| Expiry date |
Auto-calculated:
activation date + warranty
period.
|
| Remaining | Number of days remaining until expiry. Negative if already expired. |
The system automatically records all suspicious behavior when customers attempt to activate warranty codes. Each event is classified by risk level and stored with IP address and device information for admin investigation.
| Filter field | Description |
|---|---|
| Serial code | Find reports by related serial code. |
| IP address | Search by IP of the activation attempt. |
| Risk level |
HIGH
— Very dangerous (fake code, locked code, duplicate activation) MEDIUM — Suspicious (multiple attempts, warning detected) LOW — Low risk (may be user error) |
| Detection reason | Filter by specific violation type (see table below). |
| Processing status |
Unresolved (0)
— not yet marked by admin Resolved (1) — admin has reviewed and closed the report |
| Reason | Risk level | When it occurs |
|---|---|---|
serial_not_exist
|
HIGH | Customer entered a code not in the database — clear sign of counterfeit product. |
blocked_serial
|
HIGH | Code has been deactivated by admin but someone still attempted to activate it. |
already_activated
|
HIGH | Code was already activated by someone else — suspected re-circulated product. |
multiple_attempts
|
MEDIUM | The same code was attempted for activation multiple times in a short period. |
too_soon_activation
|
MEDIUM | Activated too soon after the serial was created — suspected product not yet in end user's hands. |
warning_detected
|
MEDIUM | System detected a general suspicious pattern. |
suspicious_batch
|
MEDIUM | The Warranty Batch has an unusually high number of warnings. |
product_deleted
|
MEDIUM | Serial belongs to a product that has been deleted from the system. |
batch_deleted
|
MEDIUM | Serial belongs to a Warranty Batch that has been deleted. |
workspace_deleted
|
MEDIUM | Serial belongs to a workspace that has been deleted or deactivated. |
| Field | Description |
|---|---|
| Serial code | The code that was attempted to be activated. |
| Risk level | HIGH / MEDIUM / LOW — automatically classified based on reason. |
| Detection reason | The type of violation assigned by the system (see table above). |
| IP address | IP of the device that performed the suspicious action. |
| Customer-entered data |
Full name / phone number / email
entered by the customer during
the attempt (if any). Stored as
JSON in
attempt_data.
|
| Processing status | Unresolved / Resolved. Admin can toggle the status directly from the list via AJAX. |
| Detection time | Exact timestamp of the event. |
From the list, admin clicks the toggle
button
Resolved / Unresolved on
each report. The action calls AJAX to
POST
/counterfeit_reports/toggle-resolved
and updates immediately without page reload.
The report detail page displays full information: serial, batch, workspace, customer-entered data, and history linked to the actual warranty (if the code was previously activated legitimately).
Configuration specific to the warranty module: serial prefix, QR code background image, and the activation / lookup page. reCAPTCHA settings are managed centrally at System Settings → reCAPTCHA.
| Field | Type | Description |
|---|---|---|
| Prefix | text |
A character string prepended to
each serial code when generated.
Example: prefix
STA → serial
STA067331766.Only affects newly created batches; existing serials are not changed. |
| QR code background image | image |
Image used as background for QR
codes when exporting a PDF file.
If not set, the system uses the
default image
background-qr-code.png.
|
| Activation page | select | Select a CMS page to serve as the warranty activation page for customers. This page needs to embed the warranty activation shortcode. |
| Lookup page | select | Select a CMS page to serve as the warranty lookup page for customers. This page needs to embed the warranty lookup shortcode. |
Configure reCAPTCHA for the warranty lookup page. Settings located at:
When reCAPTCHA is enabled, the warranty activation and lookup forms will require reCAPTCHA verification before submission.
Warranty settings are saved as JSON in the
settings table with
setting_name = 'warranty_config'. Click "Save Settings" to
apply changes.
Configure header, footer, and custom 404 page information. This page has 3 configuration tabs.
| Field | Required | Description |
|---|---|---|
| Header phone number | Optional | Hotline displayed on the top header bar. |
| Quick Search — Products | Optional | List of suggested products appearing in the quick search box in the header. |
| Quick Search — Articles | Optional | List of suggested articles in the quick search box. |
| Popular keywords | Optional | List of keywords + links displayed below the header search box. Each item includes: Keyword name and Link. |
| Field | Required | Description |
|---|---|---|
| Footer form | Optional | Select a registration form (from the Custom Forms feature) to display in the footer. |
| Company name | Optional | Business name displayed in the footer. |
| Company address | Optional | Headquarters address displayed in the footer. |
| Company phone number | Optional | Hotline displayed in the footer. |
| Company email | Optional | Contact email displayed in the footer. |
| DMCA Link / Image | Optional | Copyright protection badge: enter the DMCA badge link and image. |
| Copyright | Optional | Copyright line displayed at the bottom of the footer. Can be plain text or HTML format. |
| Field | Required | Description |
|---|---|---|
| 404 Title | Optional | Large title displayed on the 404 error page. |
| 404 Description | Optional | Short explanatory paragraph below the 404 title. |
| Redirect suggestion list | Optional | Suggested navigation items when the user visits a non-existent link. Each item includes: Title, Description, Button name, and Link. |
An overview of all configuration pages within the
Theme menu group (parent:
group_interface).
| Configuration item | Main function |
|---|---|
| Font, size, color & logo configuration | Set overall style: typography, primary color, header/footer display configuration by layout, logo and style for desktop/mobile. |
| Menu | Manage website navigation menu structure, arrange order, assign links, and configure menu display. |
| CSS | Enter custom CSS to override the theme interface per specific needs without editing the theme source directly. |
| Sidebar widgets | Manage widgets in the sidebar/footer area: add, arrange, and configure content blocks to display. |
Add custom CSS or JavaScript to the website without editing the theme files directly.
Write custom CSS in the editor area. The CSS will be automatically applied to the entire website.
- Change the interface without editing theme files.
- Change fonts, colors, spacing per project requirements.
- Show/hide specific elements.
Inject custom JavaScript. The JS will be automatically added to the end of the page.
- Add tracking code (Google Analytics, Facebook Pixel...).
- Integrate livechat, chatbot.
- Other custom scripts.
Configure basic website information: company name, email, phone number, address, description, and copyright. This information is used across many modules: email, footer, shortcode.
| Field | Type | Description |
|---|---|---|
| Company name | text | Brand / company name displayed on the website and in emails. |
| text | Website's representative email. Used in system email templates. | |
| Phone number | text | Primary contact phone number. |
| Hotline | text | Customer support Hotline number. |
| Address | text | Office / store address. |
| Description | textarea | Short description of the website / business. |
| Copyright | textarea | Copyright content displayed in the footer. |
setting_name = 'overview'. Can be
read in code using
getSiteName(),
getSiteDescription() or
getOption('overview').
Set up the SMTP server for the system to send notification emails, order confirmations, warranty activations... Includes a test email feature to verify the configuration.
| Field | Type | Description |
|---|---|---|
| Protocol | select |
Currently supports
SMTP.
|
| SMTP Host | text |
SMTP server address. Example:
smtp.gmail.com,
smtp.sendgrid.net.
|
| SMTP Port | text |
Connection Port. Usually
587 (TLS) or
465 (SSL).
|
| Encryption | select |
TLS or
SSL.
|
| Username | text | SMTP username (usually the email address). |
| Password | password | SMTP password or App Password (for Gmail, 2FA must be enabled and an App Password created). |
| Charset | text |
Character set. Default
utf-8.
|
| From Address | text | Sender email address displayed in the recipient's inbox. |
| From Name | text |
Sender display name. Example:
Dream Team.
|
| Reply-To | text | Email to receive replies when the user clicks Reply. Leave blank to use From Address. |
After saving the configuration, enter an email address in the "Send test email" field and click the test button. The system sends a sample email to that address immediately.
- If you receive the email → SMTP configuration is correct.
- If not received → check host, port, encryption, and App Password again.
Customize HTML content for each type of system email (order confirmation, warranty...) at:
myaccount.google.com → Security → App
passwords
to create one.
Inject Google Analytics, Facebook Pixel, Google Tag
Manager scripts or any code snippet into the
<head> or
<body> of all pages. Includes an
option to delay script loading to improve page
speed.
| Field | Description |
|---|---|
| HTML Head (No Script) |
Inject at the end of
<head> as
<noscript> —
used for GTM noscript tags or
pixels that don't need JS.
|
| HTML Head |
Inject at the end of
<head> —
used for Google Analytics, GTM
scripts, verification meta tags.
|
| HTML Body (Footer) |
Inject before
</body> —
used for chat widgets, pixels,
scripts initialized after DOM.
|
This feature delays the execution of injected scripts until the user interacts with the page (scroll, click, mouse move). This helps improve Core Web Vitals and PageSpeed scores.
| Option | Description |
|---|---|
| Enable delay | Toggle to enable/disable the delay feature. When disabled, scripts run as soon as the page loads. |
| Delay time (seconds) |
If the user does not interact,
scripts will still run after
exactly this many seconds.
Default is 10
seconds.
|
<script async
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX">
snippet into HTML Head. To
install GTM: paste the script into
HTML Head and the noscript
into
HTML Head (No Script).
Configure the homepage, pagination, asset version and no-index options for the entire website.
| Field | Type | Description |
|---|---|---|
| Homepage | select |
Select a CMS page to use as the
homepage. The selected page will
be mapped to the URL /.
|
| Items per page (pagination) | number |
Number of items displayed per page on
listing pages (posts, products...).
Modules can register their own
pagination config via the filter
BASE_FILTER_ADD_PAGINATION_CONFIG.
|
| Asset Version | number |
Asset version (CSS/JS). Increment
this number to force browsers to
reload the latest asset files (cache
busting). Defaults to the value from
cms_assets.version.
|
| No-index | checkbox |
Enable to add
<meta name="robots"
content="noindex">
to all pages — typically used in
staging/dev environments to
prevent Google from indexing.
|
Configure Google reCAPTCHA v2 for use across the entire system — protects warranty activation forms, lookups, contact forms and customer forms from spam and bots.
| Field | Type | Description |
|---|---|---|
| Enable reCAPTCHA | toggle | Enable/disable reCAPTCHA across the entire system. When enabled, two additional key fields will appear below. |
| Site Key | text | Public key embedded into the frontend page to display the reCAPTCHA widget. |
| Secret Key | text | Secret key used server-side to verify the response from Google. Never expose this on the frontend. |
- Go to google.com/recaptcha/admin/create.
- Enter a name for the site, select the type reCAPTCHA v2 → "I'm not a robot".
- Add your website's domain to the allowed list.
- Click Submit — Google will provide the Site Key and Secret Key.
- Copy both keys into the settings form and save.
Once enabled and configured, reCAPTCHA is automatically applied at the following points:
- Warranty activation form — customer serial activation page.
- Warranty lookup form — warranty information lookup page.
- Ecommerce checkout — order form on the checkout page (when Ecommerce has captcha option enabled).
isRecaptchaEnabled() and get the key
with getRecaptchaConfig('key') /
getRecaptchaConfig('secret').
Configure floating contact buttons on the website: Zalo, Facebook, Phone, WhatsApp, Messenger... Admin sets up links, descriptions and display types.
Each channel is an independent list of accounts (you can add multiple phone numbers, multiple Zalo accounts...). Each item includes:
| Channel | Example link |
|---|---|
https://facebook.com/yourid
|
|
| Zalo |
https://zalo.me/0912345678
|
| Phone | tel:0912345678 |
https://wa.me/84912345678
|
|
| Viber |
viber://chat?number=+84912345678
|
| Messenger |
https://m.me/yourpage
|
https://instagram.com/yourprofile
|
Each item also has a Description field (displayed as tooltip) and Google Conversion Tag (to track clicks via Google Ads).
| Option | Description |
|---|---|
| Show button | Enable/disable the entire CTA area on the website. |
| Display type |
Icon
— show icon only Icon + Text — show icon with label Combined Icon — grouped into a single button, click to expand the list |
| Position | Left or Right of the screen. |
| Support title | Label displayed above the button group (when display type is Combined Icon). Example: "Contact us". |
Enable two-step authentication using Google Authenticator for all admin accounts. When enabled, each login requires the admin to enter an OTP code from the Google Authenticator app on their device.
| Field | Description |
|---|---|
| Enable 2FA | Toggle to enable/disable the two-step authentication requirement for all admins. Applies to all accounts simultaneously. |
- Enable the "Enable 2FA" toggle on this page and save.
- Each admin goes to Account Information → scans the QR code using the Google Authenticator app (iOS / Android).
- Enter the 6-digit OTP code from the app to confirm the link.
- From the next login, the system requires entering the OTP after the correct username and password have been entered.
2fa middleware. When 2FA is enabled and
the admin has not verified the OTP in the current session,
they will be redirected to the OTP entry page before
accessing the admin panel.
Configure the URL structure for posts, post categories, single pages, products and product categories across the website. Changes will update all links in the database.
Choose from one of the predefined URL structures or fully customize it:
| Type | Example URL |
|---|---|
| Day and post name |
/2023/04/04/post-name
|
| Month and post name |
/2023/04/post-name
|
| Post ID string | /blog/123 |
| Post name | /post-name |
| Category & post name |
/category/post-name
— enable
Link structure
to create hierarchical URLs based on
the category tree
|
| Custom |
Enter your own structure with dynamic tags:{year}
{monthnum}
{day}
{hour}
{minute}
{second}
{post_id}
{postname}
{category}
{author}{postname} must be at
the end.
|
Enter a prefix string for post categories. Example:
enter news → category URL becomes
/news/category-name. Leave blank →
/category-name.
-
Show as .html —
adds the
.htmlsuffix to category URLs. - Link structure — creates hierarchical URLs following the parent → child category tree.
Enter a prefix for single pages. Example: enter
page → page URL becomes
/page/{pagename}. Leave blank →
/{pagename}.
The {pagename} tag must be at
the end.
This section is injected by the Ecommerce module
via the hook INIT_LINK_CUSTOM — it only
appears when the Ecommerce module is activated.
| Item | Description |
|---|---|
| Product category prefix |
Enter a prefix for product
categories. Example:
products →
/products/category-name. Supports
.html and
link structure
hierarchical URLs.
|
| Product URL structure |
Enter your own structure with tags:
{productname},
{productcategory}.Example: /{productname}.html
or
/products/{productcategory}/{productname}.html.The {productname}
tag must be at the end.When using {productcategory} —
enable
Product link
structure
to create hierarchical URLs based on
the category.
|
replaceMenuLink() to update all
links in menus and the database. For sites with
a lot of content, this operation may take a
few seconds to a few minutes. Do not close the page while
saving is in progress.
Manage the content of the ads.txt file —
the authorized seller verification file per IAB standards.
Required when running Google AdSense, Google Ad Manager
or other advertising networks.
Paste the content of the ads.txt file
into the textarea. Each line is a seller declaration,
following the standard:
google.com, pub-XXXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0 advertising.com, 12345, RESELLER
The content is saved to the physical file at
public/ads.txt. Leave blank to delete
the file.
/ads.txt. Ad
networks will automatically crawl this URL to
verify. Check after saving by opening that URL
in a browser.
Configure conversion tracking codes (Google Ads Conversion, Facebook Pixel...) for key Ecommerce events: add to cart, initiate checkout, payment successful.
The Tracking page has no hardcoded content — all
tabs and forms are injected by other modules
via the filter hook
FILTER_LIST_DATA_GOOGLE_CONVERSION. Each module registers its own group of tabs.
If no module has registered yet, the page displays the message: "This feature is only available for e-commerce or service platforms!"
The Ecommerce module injects 3 tabs into the
Tracking page via
renderGoogleConversionSetting():
| Tab / Event | When triggered |
|---|---|
| Add to cart | When a customer clicks the Add to cart or Buy now button on the product page. |
| Initiate checkout | When the customer visits the checkout page / starts filling in payment information. |
| Payment successful | When an order is placed successfully — the code runs on the thank-you page. |
Each tab has the following fields:
| Field | Description |
|---|---|
| Activate | Enable/disable this tracking event. |
| Page load code | Script that runs when the event page loads. Paste code from Google Ads, GTM event or Pixel. |
| Conversion code (on click) | Script that runs when the button is clicked. Supports dynamic parameters. |
| Dynamic parameters |
The system replaces parameters
in the code before rendering:{price_total} —
Total order value{currency} — Currency
unit{transaction_id} —
Order ID
|
gtag('event', 'conversion', {...})
and paste it into the
Conversion code field of the corresponding event.
Use the {price_total} parameter for
the conversion value.
Automatically generate and insert a Table of Contents (TOC) into post, single page and product content based on heading tags (H2, H3...) found in the content.
| Field | Type | Description |
|---|---|---|
| Enable / Disable TOC | toggle | Enable to activate the feature. When disabled, the TOC will not appear anywhere on the website. |
| Display position | select |
Before first heading
— insert TOC just before the first H2/H3 After first heading — insert after the first heading Before content — insert at the top of all content After content — insert at the bottom of content |
| Display modules | checkbox |
Select which modules will apply
TOC: Posts — post detail page (Post) Single Pages — Page Products — product detail page (Ecommerce) Multiple modules can be selected at once. |
When TOC is enabled, the system analyzes the HTML of
the content field (CKEditor), finds all
<h2>,
<h3>,
<h4>... tags, assigns
id attributes to each heading, then generates
a TOC HTML block and inserts it at the selected position.
The TOC is only generated if the content has 2 or more headings. If there is only 1 heading, TOC will not be displayed.
setting_name = 'cms_toc'. The post
and product modules automatically read this config to
decide whether to show TOC or not — no need to add
shortcodes or code to templates.
Manage supported currencies, configure price display formatting and options for auto-detecting currency based on visitor location.
| Field | Description |
|---|---|
| Default currency symbol |
String displayed before/after the price.
Example: ₫,
đ,
VND.
|
| Auto-detect currency | Enable to have the system automatically switch to the appropriate currency based on the visitor's IP geolocation. Requires multiple currencies to be configured. |
| Space between price and symbol |
Enable to add a space between the price
number and the currency symbol. Example:
100,000 đ instead of
100,000đ.
|
| Thousands separator |
, (comma),
. (period), or space.
Example:
1,000,000 or
1.000.000.
|
| Decimal separator |
. (period) or
, (comma). Example:
99.99 or
99,99.
|
The lower section of the page allows adding/editing/deleting currencies. Each currency includes:
| Field | Description |
|---|---|
| Name |
Currency name. Example:
Vietnamese Dong.
|
| Code |
ISO 4217 code. Example:
VND,
USD.
|
| Symbol |
Display symbol. Example:
₫, $.
|
| Exchange rate |
Exchange rate relative to the default currency.
The default currency is set to
1.
|
| Default | Mark as the default currency displayed to visitors. Only one currency can be set as default. |
Manage supported languages on the website, configure the default language, enable multilingual mode and set the system timezone.
The Language tab (default) allows adding, editing, deleting and enabling/disabling languages. Each language includes:
| Field | Description |
|---|---|
| Select language | Dropdown to select from a standard language list. When selected, the system auto-fills Name, Locale, Code and Text direction. |
| Name |
Display name of the language. Example:
Vietnamese,
English.
|
| Locale |
Locale code used for translation directories.
Example: vi,
en_US.
|
| Language code |
ISO code (2 characters). Example:
vi,
en. Used in query
strings when switching language.
|
| Text direction | LTR (left to right — default) or RTL (right to left — Arabic, Hebrew). |
| Country flag | Flag icon displayed in the language switcher on the frontend. |
| Sort order | Display order in the list. Lower numbers appear first. |
lang/{locale}/
by copying from lang/en/.
Configuration saved with
setting_name = 'siteLanguage'.
Contains 4 fields:
| Field | Type | Description |
|---|---|---|
| Default language | select |
Default display language for website
visitors. Must be selected from the
list of Active languages.
Default: vi.
|
| Admin panel language | select |
Language displayed in the admin
interface (admin panel).
Separate from the frontend language.
Default: vi.
|
| Enable multilingual | toggle | Enable to allow visitors to choose their language. When enabled, the Language Switcher appears on the frontend. When disabled, the website uses only the default language. |
| Timezone | select |
Timezone used for the entire system —
post publish times, orders, logs... Default:
Asia/Ho_Chi_Minh
(UTC+7).
|
When multilingual is enabled, visitors can
switch languages via the query string
?lang={code}. The system uses
LanguageNegotiator to determine the
current language by priority order: query
string → cookie → Accept-Language header →
default language.
Configure social login (Google OAuth) and policy links
displayed in the registration form. All settings are saved
to the settings table with
setting_name = 'setting_auth_social'.
Allows users to log in quickly using their Google account instead of creating a separate password. You need to create an OAuth application at Google Cloud Console to obtain the credentials to fill in here.
| Field | Required | Description |
|---|---|---|
Google Client ID
auth_social_google_client_id
|
No |
Application identifier issued by Google.
Format:
123456789-xxxx.apps.googleusercontent.com. Obtain from
Google Cloud Console → APIs
& Services →
Credentials.
|
Google Client Secret
auth_social_google_client_secret
|
No | Secret password corresponding to the Client ID. Do not expose or commit to code. |
https://yoursite.com/auth/google/callback
to the
Authorized redirect URIs field.
When users register an account, the form displays the sentence: "By checking and proceeding to register, you agree with us regarding..." along with links to policy pages. Each field below allows selecting a single page already created in the Page module — the system will automatically use that page's URL to create the link.
| Field | Required | Description |
|---|---|---|
Privacy policy page
policy_page_id
|
No | Page describing how the website collects and uses users' personal information. Displays as "privacy policy" link in the registration form. |
General policy page
policy_general_page_id
|
No | Page outlining general policies when using the service (rules, return policy, etc.). |
Terms of service page
term_page_id
|
No | Page presenting the terms and conditions users must accept when registering an account. |
Complaint handling mechanism page
complaint_handling_mechanism_page_id
|
No | Page guiding users on how to submit complaints about personal data handling (often required by e-commerce legal regulations). |
Support page
support_page_id
|
No | Contact or customer support page. Displays as "support" link at the end of the terms confirmation sentence. |
hasLocale = false) — no need to reconfigure per locale.
Store and track all contact requests from website users — including regular contact forms and newsletter subscriptions. Admins can view content and mark processing status.
| Filter field | Description |
|---|---|
| Search by sender's email address. | |
| Subject | Search by contact subject / title. |
| Status |
New (0)
— unread, displayed prominently Contacted (1) — opened and viewed or manually marked |
| Type |
contact
— contact request from the contact form newsletter — email newsletter subscription |
| Time | Filter by date range submitted. |
| Column | Description |
|---|---|
| Sender's email address. | |
| Full name | Sender's name (if provided). |
| Phone number | Sender's phone number (if provided). |
| Subject | Contact subject / title. |
| Status | Can be changed quickly directly in the table (quick edit) without opening the detail view. |
| Time | Date and time the request was sent. |
Click the View icon to open the detail page. At that point:
- If the contact is in the New status, the system automatically changes it to Contacted.
- Displays the full message content, contact information, and the URL of the form submission page.
Records all admin actions across the system: create, update, delete, login. Allows searching and restoring permanently deleted data.
| Filter Field | Description |
|---|---|
| Admin | Filter by the admin performing the action. |
| Module Type | Filter by the affected table/module (posts, products, orders...). |
| Record Name | Search by the specific name of the affected item (LIKE). |
| Action | Filter by the type of action (see table below). |
| Time | Filter by the time range. |
| Action | Description |
|---|---|
create
|
Admin creates a new record. |
update
|
Admin updates the content of a record. |
quick_update
|
Quick update from the list table (change status, quick edit). |
quick_delete
|
Move the record to the trash. |
quick_restore
|
Restore the record from the trash. |
delete_forever
|
Permanently delete from the trash. This type of log allows rollback of data. |
login
|
Admin logs into the system. |
| Column | Description |
|---|---|
| Admin | The account name that performed the action. |
| IP | The IP address of the device at the time of the action. |
| Action | The type of operation (create / update / delete_forever...). |
| Module | The affected table/module (posts, products, orders...). |
| Time | The exact time the action was performed. |
When an admin permanently deletes a record, the system saves all old data (including slug, language, SEO, related comments) into the log with the action delete_forever.
To restore, open the log detail page and click "Rollback":
- The system recreates the record in the original table with the old data.
-
Restores with
slug,language_metas,meta_seoandcommentsif any. - Removes the log from the list (to avoid duplicate rollbacks).
- Redirects to the edit page of the restored record.
delete_forever.
Logs of other actions (create,
update...) are for reference only and do not support
rollback.
Use the "Delete Logs" button on
the list page (visible if you have the
system_logs_delete permission) to delete the
filtered logs. This action cannot be undone — the rollback data of the deleted logs
will also be lost.
View all payment transactions from ecommerce orders. Supports filtering by transaction ID, method, and status.
| Filter Field | Description |
|---|---|
| Transaction ID |
Search by
charge_id — transaction ID from the payment gateway.
|
| Payment Method | Filter by gateway: COD, Bank Transfer, VNPay, PayPal, Stripe... The list is automatically extended when additional payment packages are installed. |
| Status |
Pending — new transaction, not yet confirmed Success — payment completed Failed — transaction rejected / error Refunded — refunded to customer |
| Column | Description |
|---|---|
| Transaction ID | Transaction ID from the payment gateway. Click to view details. |
| Payer Information | Name and information of the customer associated with the order. |
| Amount | Transaction value, displayed with currency unit. |
| Payment Method | Payment gateway used. |
| Status | Badge color indicating the current status. Can be updated manually on the detail page. |
| Time | Transaction creation time. |
View full information of a payment transaction, manually update the status, and view refund information from the payment gateway.
The detail page consists of two parts:
basic information (from the
payments table) and
extended information (injected
from the corresponding payment package via the filter
PAYMENT_FILTER_PAYMENT_INFO_DETAIL).
| Field | Description |
|---|---|
| Transaction ID (charge_id) | Original transaction ID from the gateway. Used to look up on the payment gateway dashboard. |
| Amount | Payment amount. |
| Method | Payment method used. |
| Status | Dropdown allows manual update. The Pending status is hidden if the transaction is already processed. |
| Payment Gateway Information | Extensions inject details for each gateway — for example, VNPay shows bank code, response code; PayPal shows payer email, PayPal transaction ID. |
| Refund |
If the gateway supports it (VNPay), there is a button to view refund information. Clicking it opens a popup where you can view detailed information of each refund attempt, including time and amount. The data is taken from the field metadata.refunds[].
|
Package payment con (VNPay, PayPal,
Stripe...) inject detailed content into
this page via the filter
PAYMENT_FILTER_PAYMENT_INFO_DETAIL. Each package returns its own HTML from its view, for example Vnpay::detail or
DreamTeamPayPal::detail. If
the package is not installed, this section is empty.
Enable/disable and configure each payment gateway. Includes built-in methods (COD, Bank Transfer) and extensions injected via hooks.
This page displays a table of all payment methods. Each method has a status badge (Enabled/Disabled) and a Settings button to access its configuration page. If it is the default method, a "Default" badge will be displayed.
| Payment Method | Description |
|---|---|
| COD |
Cash on Delivery. Pre-installed in
PaymentMethodEnum::COD, no API key required. Setting
key:
payment_cod_status.
|
| Bank Transfer |
Displays bank account information for customers to manually transfer funds. Setting key:
payment_bank_transfer_status.
|
| VNPay |
Vietnamese domestic payment gateway. Injected via hook
PAYMENT_METHODS_SETTINGS_PAGE
from package
payment-vnpay. Supports refunds.
|
| PayPal |
International payment gateway. Injected
from package
payment-paypal. Automatically converts to USD if the currency is not supported.
|
| Stripe |
International payment gateway. Injected
from package
payment-stripe.
|
Each payment method has its own configuration page. The form content is injected via the filter
PAYMENT_METHODS_SETTINGS_RENDER_PAGE. Common fields include:
| Field | Applicable to |
|---|---|
| Set as Default |
All. Setting key:
default_payment_method. Once enabled, the payment method name will be saved to this key.
|
| Display Name / Description | COD, Bank Transfer, VNPay, PayPal, Stripe — hiển thị trên trang checkout. |
| Client ID / Client Secret |
PayPal:
payment_paypal_client_id,
payment_paypal_client_secret.VNPay: payment_vnpay_client_id
(TmnCode),
payment_vnpay_client_secret
(HashSecret).
|
| Secret Key / Publishable Key |
Stripe:
payment_stripe_secret,
payment_stripe_publishable.
|
| Bank Account Information | Bank Transfer: bank name, account number, account holder, QR code for transfer. |
Extension gateways (VNPay, PayPal, Stripe) register into the payment system through 3 main hooks:
| Hook | Purpose |
|---|---|
PAYMENT_METHODS_SETTINGS_PAGE
|
Add a row to the payment methods list table. |
PAYMENT_METHODS_SETTINGS_RENDER_PAGE
|
Render configuration form when accessing the settings page of that payment method. |
PAYMENT_FILTER_AFTER_POST_CHECKOUT
|
Handle payment logic (create redirect link, call gateway API) when a customer places an order. |
PAYMENT_FILTER_PAYMENT_INFO_DETAIL
|
Inject HTML transaction details into the payment detail page in the admin panel. |
HookServiceProvider and register the
above filters. No need to modify the core
payment package. The system will
automatically detect and display the new gateway
in the list.
Create and manage admin accounts. Each account can be assigned roles, detailed permissions, avatars, and author information.
| Field | Description |
|---|---|
| Name | Search by username (slug). |
| Search by email. | |
| Role | Filter by created role groups. |
| Creation Date | Account creation date range. |
| Status | Active / Inactive / Draft. |
Two-column form: the left side is account information, the right side is permissions.
| Field | Required | Description |
|---|---|---|
| Username | Yes | Username used for login. Automatically converted to slug. Maximum 191 characters. |
| Yes | Login email, must be unique. | |
| Password / Confirm | Yes | Password is hashed using bcrypt. Supports random password generation button. |
| Avatar | No | Avatar image. Displayed in the post list and author page on the frontend. |
| Display Name | No | Display name on the frontend (different from username). |
| Position | No | Displayed under the author's name on the post page. |
| Author Bio | No | Short description (up to 200 characters). Displayed in the author box under the post. |
| Social links | No |
Website, Facebook, Twitter,
Pinterest, Instagram, YouTube —
stored as JSON in the
social column.
|
| Full Author Bio | No | CKEditor content for the full author page. |
| Role | No |
Select either a predefined role with specific permissions, such as
Super Admin
(full access) or a custom role. When selecting Super Admin,
is_supper_admin = 1, there is no need to select detailed permissions.
|
| Custom Permissions | No |
Override role permissions. Stored as JSON in the
capabilities column.
|
Create and manage role groups. Each role defines a set of permissions allowed to perform in the admin panel.
The system has 2 levels of permissions:
| Type | Description |
|---|---|
| Super Admin |
Account with
is_supper_admin = 1. Full access, not checked
for permissions. Can be selected directly
when creating/editing an admin user.
|
| Custom Role |
Role group created on this page.
Stores the list of permissions in JSON format
in the permissions column.
When an account is assigned a role, it will only have access to the allowed functions.
|
| Field | Required | Description |
|---|---|---|
| Role Name | Yes |
Display name. For example:
Editor,
Accountant.
|
| Permission List | Yes |
Permission checklist by module
(posts, orders, products, settings, etc.).
Each module typically includes the following permissions:
view,
add,
edit,
delete,
deleteForever.
|
| Status | Required | Roles with Inactive status will not appear in the role selection dropdown when creating a new admin user. |
Review, edit, reply to, and delete customer comments. Comments can come from multiple modules: posts, products, static pages, etc.
| Field | Description |
|---|---|
| Name | Search by commenter name. |
| Content | Full-text search within comment content. |
| Comment Date | Comment creation date range. |
| Display Status | Visible — comment is publicly displayed on the frontend. Hidden — comment is hidden. |
| Processing Status | Processed (admin has replied/approved). Unprocessed — requires attention. |
| Action | Description |
|---|---|
| Edit Comment | Admin can modify customer comment content. For product comments, attached images can also be edited. |
| Quick Reply |
Admin replies directly from the list.
The reply is created as a child comment
(parent_id) with
admin_id assigned.
Status is automatically set to
Visible.
|
| Hide Comment | Change status to Hidden — the comment will not appear on the frontend but is not deleted. |
| Permanently Delete |
Completely remove from the database.
When a parent comment is deleted, all
child comments
(parent_id)
are deleted as well.
The action is recorded in the System Log.
|
The type column identifies which module
the comment belongs to. Examples:
posts,
products,
pages.
Hidden filters
type and
type_id
allow filtering comments by a specific
post/product when opened from the content detail page.
BlogHelper::isCommentEnabled()).
When disabled, the comment form is completely hidden
even though the Comment module remains active.
Manage 3-level geographical data: Country → Province/City → District → Ward. This data is used in Ecommerce shipping address forms.
| Level | Route | Description |
|---|---|---|
| Country |
admin.countries.*
|
Highest level. Examples: Vietnam, USA. Each province/city belongs to a country. |
| Province/City |
admin.provinces.*
|
Provincial/city level. Can be filtered by country. Deleting a province automatically deletes all child wards. |
| Ward | admin.wards.* |
Lowest level, belonging to a province/city. |
The module supports importing geographic data from
Excel files via
BulkImportController.
Used when importing complete province/district/ward
data for a new country.
| Action | Description |
|---|---|
| Import Excel |
Upload an
.xlsx file with the structure:
location name, code, parent ID.
The system automatically creates all records.
|
| Export Excel | Export all province/ward data to an Excel file. Used for backup or migration to another environment. |
code from its name (uppercase slug).
This code is used for lookup or synchronization with external systems.
Multi-language support is available — each location name can be translated by locale.
Manage URL redirects (301/302). When changing URL structures, add redirects to prevent SEO traffic loss and avoid 404 errors on old links.
| Field | Required | Description |
|---|---|---|
| Source URL (old) | Yes |
Old path to redirect.
Example:
/news/old-article.
Enter a relative path (without domain).
|
| Target URL (new) | Yes | New destination path. Can be a relative path or a full URL. |
| Redirect Type | Yes |
301 — Permanent Redirect
(Moved Permanently).
Google transfers PageRank to the new URL.
Use when the URL has permanently changed.
302 — Temporary Redirect (Found). Google keeps PageRank on the old URL. Use when the original URL will be restored later. |
| Status | Yes | Only Active redirects are applied on the website. |
When you need to add a large number of redirects (for example after migrating an old website), use the import feature:
| Action | Description |
|---|---|
| Import Excel |
Upload a
.xlsx or
.xls file.
Column structure:
Source URL,
Target URL,
Type (301/302).
Requires
sync_links_import
permission.
|
| Export Excel |
Export the current redirect list
(based on applied filters)
to
sync-links-{timestamp}.xlsx.
Requires
sync_links_export
permission.
|