Getting Started

Sellino POS — Point of Sale & Inventory System
Version: 1.0.0 (Stable)
Tech Stack: Laravel 12 · PHP 8.3 · MySQL 8.0+
License: Envato Market – Regular / Extended

Developed By: BugBuild Labs

Welcome to Sellino POS

Sellino POS is a complete point of sale, inventory and accounting system for real shops — supershop, grocery, pharmacy, fashion, hardware, restaurant and any counter-based retail business, running one outlet or a whole chain. From a single Laravel codebase you get the counter POS, the full back office, and a companion Flutter POS app.

This package ships two products that share one Laravel backend and database:

  • Web Panel (Admin & POS) — this documentation. The Laravel control center: the POS terminal itself plus catalog, inventory, branches, cash, accounting, HR and reports.
  • POS App — a Flutter counter app for Android and iOS (covered in the POS App tab).

This edition runs with SITE_MODE=pos-inventory. There is no customer storefront and no vendor marketplace — the panel shows only what a shop actually uses, and what separates one outlet from another is the branch, not a vendor.

Key Features:

  • Fast POS sales with multi-payment (cash, bank, mobile money or mixed)
  • Counters, cash registers, cash pickup and petty expenses
  • Multi-branch — branch-bound warehouses, counters and staff, with branch-wise Profit & Loss
  • Products with category, brand, unit, tax, attributes & variations
  • Purchase orders, supplier dues and multi-warehouse stock with racks and lots
  • Stock adjustment, damage, transfer and supplier returns; FIFO or average costing
  • Sale edit & cancel, customer returns, replacements & refunds — stock and accounts corrected automatically
  • Built-in double-entry accounting (Chart of Accounts, journals, banks, reconciliation)
  • Coupons, flash sales, campaigns and membership points at the counter
  • HR & Payroll with loans, advances and payroll journals
  • Role-based access control, activity logs and multi-language (RTL/LTR)
  • Push notifications (Firebase), local or S3-compatible media storage
  • Barcode labels, thermal receipt printing and counter scanner support
Admin dashboard
Admin dashboard

Server Requirements

Make sure your hosting meets these before installing the web backend. The built-in installer checks every item automatically on its first screen.

RequirementMinimum
PHP8.3 or higher
Laravel12.x (bundled with the source)
MySQL8.0 or higher
Web serverApache or Nginx
Build toolsComposer, Node.js & NPM
SSL certificateRecommended for production (HTTPS)

Required PHP extensions

All of these must be enabled — most shared hosts have them on by default:

BCMath   Ctype   cURL   Fileinfo   GD   JSON   Mbstring
OpenSSL  PDO     Tokenizer  XML   Zip  MySQLi   allow_url_fopen

Not sure your server qualifies? Open https://yourdomain.com/install — the installer's first step shows a live green/red check of every requirement and extension above, so you know exactly what to fix.

Database Setup (via cPanel)

Create a MySQL database before running the installer.

Step 1 – Login to cPanel:
Open your hosting cPanel (usually https://yourdomain.com/cpanel).

Step 2 – MySQL® Database Wizard:
Search and open MySQL® Database Wizard.

Step 3 – Create Database:
Enter a database name and click Next Step.

Step 4 – Create User:
Add a username and a strong password, then Create User. Save these securely.

Step 5 – Add User to Database:
Grant All Privileges and finish.

✅ Keep these three ready for the installer:

CredentialWhere you enter it
Database NameInstaller → Database Details (or DB_DATABASE in .env)
Database UsernameInstaller → Database Details (or DB_USERNAME)
PasswordInstaller → Database Details (or DB_PASSWORD)

Host: on most cPanel/shared hosting the database host is localhost. Use that in the installer unless your provider says otherwise.

Package Contents & Source Code

Download Main_Files.zip from your CodeCanyon downloads and extract it locally. Inside you will find the full source for both products, each in its own folder:

FolderWhat it is
WebSourceCode The Laravel backend — the admin panel, the POS terminal and the REST API the app runs on. This is what you install on your server (see Upload & Environment).
PosAppSourceCode The Flutter POS app source (counter app for Android & iOS). Configure it against your server's API — see the POS App guide.

Both connect to one Laravel backend and database — install WebSourceCode first, then point the app at its API URL.

Also in the package: this documentation, and the standard CodeCanyon licence & changelog. The .env file is not included — you create it during setup (it holds your private database and mail credentials).

WebSourceCodeLaravel · admin + POS + API
PosAppSourceCodeFlutter · counter app

Upload Files & Environment

Step 1 – Upload Application:
Extract Main_Files.zip, open the WebSourceCode folder and zip its contents. Upload that to public_html (or your domain root) and extract it on the server. Point your web root at the public/ folder.

Step 2 – Install dependencies (only if installing manually via SSH — skip on shared hosting where vendor files are already included):

composer install
npm install && npm run build   # optional — only if you edit resources/js or resources/css

Step 3 – Create the environment file — copy .env.example to .env:

cp .env.example .env

Step 4 – Set core values in .env. What each one actually changes:

Identity & mode — set these first

VariableWhat it does if you get it wrong
APP_NAMEShown in the panel title bar and outgoing mail. Cosmetic.
APP_URLCritical. Every generated link, image URL and payment callback is built from it. A wrong value breaks images in the apps and returns customers to the wrong host after payment. Must include the scheme, no trailing slash — https://shop.example.com.
APP_ENVproduction on a live server, local while developing. Laravel hides detailed errors and enables caching optimisations in production.
APP_DEBUGMust be false in production. Left true, any visitor who triggers an error sees your file paths, environment variables and database credentials on the error page.
APP_KEYThe encryption key for sessions and encrypted columns. Leave it empty and run php artisan key:generate — never reuse someone else's. Changing it later invalidates existing sessions and any encrypted data.
SITE_MODESelects the edition this install runs as — pos-inventory for this item. It decides which panels and routes exist at all (no storefront, no seller panel in POS mode).
APP_INSTALLEDSet to true by the web installer when it finishes. Flipping it back to false re-opens the installer — only do that on a fresh database.
APP_DEMOLeave false. It enables the public demo's passwordless quick-login buttons for the accounts listed in APP_DEMO_EMAILS — intended only for a throwaway demo site, never a real shop.

Database

VariableNotes
DB_HOST, DB_PORTUsually 127.0.0.1 and 3306. Shared hosts sometimes require localhost instead.
DB_DATABASE
DB_USERNAME
DB_PASSWORD
The database you created in cPanel. On cPanel these are usually prefixed with your account name (myacct_sellino). A wrong value stops the installer at its database step with a connection error.

Mail — OTP and notifications depend on this

Mail is not configured in .env — set SMTP host, port, username, password, encryption and the from-address in Admin → Settings → Mail after installing (values are stored in the database). If mail is not working, email OTP, password reset and order mail all silently fail — configure it before going live, and use the panel's Test mail button. Where the host blocks SMTP ports, use the Gmail API transport instead (see Settings → Mail).

Performance & infrastructure — safe defaults ship in .env.example

VariableImpact
QUEUE_CONNECTIONdatabase queues mail, push and exports to a background worker — needs the queue worker running or those jobs never execute. sync runs them inline instead: no worker needed, but the user waits for every email.
CACHE_STORE, SESSION_DRIVERdatabase or file works everywhere. redis is faster but needs a Redis server.
SESSION_LIFETIMEMinutes before an idle panel user is logged out. Default 120.
FILESYSTEM_DISKpublic keeps uploads on the server; s3 sends them to your bucket using the AWS_* values below — see Storage.
LOG_LEVELerror in production keeps storage/logs small; debug while troubleshooting.
BCRYPT_ROUNDSPassword hashing cost. Higher is safer but slower on weak shared hosting. Default 12 is fine.

API, apps & real-time

VariableImpact
APP_API_KEYFallback for the X-App-Key the apps send. The value saved in Settings → API Security wins over this. Empty = the check is off (fail-open). See Security.
JWT_SECRETSigns the app's login tokens. Generate your own (php artisan jwt:secret). Changing it logs out every app user immediately.
JWT_TTL, JWT_REFRESH_TTLAccess-token and refresh-token lifetimes in minutes. Shorter is safer; the app refreshes automatically.
REVERB_*Websocket credentials for chat and live updates — only used if you run the Reverb daemon. See Real-time & Chat.
FIREBASE_PROJECT_ID
FIREBASE_CREDENTIALS
Push notifications. Optional — leave unset and everything else still works. See Common Setup.
AWS_*Only read when FILESYSTEM_DISK=s3. Works with any S3-compatible provider (Wasabi, DigitalOcean Spaces, R2).

The .env file is secret. It holds your database password, app key, JWT secret and gateway keys. Never commit it to source control, never share it, and keep it outside public/ — which it already is by default.

Step 5 – Generate the app key:

php artisan key:generate

⚠ Important: Never skip php artisan key:generate — without a valid APP_KEY, sessions and encrypted data will break. (The web installer does this for you automatically.)

Step 6 – File permissions

The web server must be able to write to these paths — the installer's Permissions step checks each one:

PathWhy it must be writable
storage/Logs, cache, compiled views and uploaded media
bootstrap/cache/Framework config & route cache
.envThe installer writes your app key, DB and JWT config here

Set them from SSH:

chmod -R 775 storage bootstrap/cache
chmod 664 .env

# If the web server runs as another user (e.g. www-data), also give it ownership:
chown -R www-data:www-data storage bootstrap/cache .env

On cPanel (no SSH): use File Manager → right-click → Change Permissions and set 775 on storage and bootstrap/cache, and 664 on .env.

Installation

You can install with the web wizard (recommended for shared hosting) or the command line.

Web installer:

  1. Visit your domain in a browser — the installer opens automatically.
  2. It checks PHP version, extensions and folder permissions.
  3. Fill in the Database Details and create the Administrator Account (fields below).
  4. Click Install Now to run migrations & seed default data.

What you enter in the wizard

FieldWhat to put
Database Details
Database Hostlocalhost on most shared/cPanel hosting (change only if your provider says otherwise)
Database UserThe MySQL username you created (see Database Setup)
Database PasswordThat user's password
Database NameThe database you created
Administrator Account (your first admin login)
First Name / Last NameThe admin's name
Email AddressAdmin login email — you sign in with this
PasswordA strong admin password

The web installer also generates the app key and the JWT secret automatically — nothing extra to do. When it finishes, sign in with the admin email & password you just set.

Command line (alternative)

On a VPS with SSH you can install without the wizard:

php artisan migrate --seed
php artisan jwt:secret     # API & mobile apps use JWT for login

The default seed creates the standard roles/permissions and demo settings; create your admin user with your own seeder or the app's user management after login.

Real-time chat: the live chat feature uses Laravel Reverb. On a local/VPS setup run php artisan reverb:start to enable websockets — see Real-time Chat.

Manual Database Migration (if the installer fails)

The web installer runs the migrations and seeders for you. If it times out, dies half-way, or your host blocks long-running requests, do the same work by hand over SSH — the result is identical.

1. Start from a clean database

Migrations are not re-runnable over a half-built schema. If the installer created some tables before failing, drop and recreate the database (or run php artisan migrate:fresh, which drops every table first).

2. Confirm .env is correct

php artisan config:clear
php artisan migrate:status     # proves the DB credentials work before you change anything

A connection error here means DB_DATABASE, DB_USERNAME, DB_PASSWORD or DB_HOST is wrong — fix that first, nothing else will work.

3. Run the migrations and seed the defaults

php artisan key:generate          # only if APP_KEY is still empty
php artisan migrate --force       # --force is required when APP_ENV=production
php artisan db:seed --force       # currencies, countries, languages, settings,
                                  # permissions, roles and the default admin user
php artisan storage:link          # public symlink for uploaded media

4. Mark the install complete

Set APP_INSTALLED=true in .env — otherwise visiting the site re-opens the installer. Then warm the caches:

php artisan optimize:clear
php artisan optimize

You can now log in at your admin URL with the seeded administrator account and change its password from Profile & Password.

Common failures

SymptomCause & fix
SQLSTATE[42000] … max key lengthMySQL older than 8.0 (or MariaDB without innodb_large_prefix). Upgrade to MySQL 8.0+ as the requirements state.
Base table or view already existsA partial install left tables behind. Drop the database and start from step 1, or use php artisan migrate:fresh --force.
Installer page times outShared-host execution limit. Use these CLI steps instead — they have no time limit.
Access denied for userThe DB user has no rights on that database. In cPanel, add the user to the database with All Privileges.
Blank page after installCached config from the failed attempt. Run php artisan optimize:clear, and check storage/logs/laravel.log.

Upgrading an existing install? Run only php artisan migrate --force — never migrate:fresh or the plain db:seed, both of which will destroy or overwrite live data. Take a database backup first.

Queue Worker & Scheduler

Background jobs (emails, push notifications, media variants, backups) run through Laravel's queue, and timed jobs through the scheduler. Both are optional at first — but recommended in production.

  • Queue driver.env ships with QUEUE_CONNECTION=sync (jobs run inline, no worker needed). For production set QUEUE_CONNECTION=database and run a worker.
  • Run the workerphp artisan queue:work. Keep it alive with Supervisor/systemd (same pattern as Reverb), or on shared hosting use php artisan queue:work:daemon.
  • Scheduler — add one cron entry: * * * * * cd /path-to-app && php artisan schedule:run >> /dev/null 2>&1.
  • Timed commandspush-campaigns:dispatch-due (scheduled push campaigns), backup:database / backup:files (see Backups), currency:update-rates (nightly FX refresh when daily auto-update is on — see Currency Rates).

After changing QUEUE_CONNECTION or deploying new code, restart the worker: php artisan queue:restart.

Login & Security

The admin login link ends with a randomized security slug (set in config('site.admin_login_path')) so the admin panel is not at a guessable URL.

Login URLs (replace example.com with your own domain):

  • Admin: example.com/admin-7eP9kM4QX2pUoEic/login (slug from config('site.admin_login_path'))
  • Customer: example.com/login

Log in:

  1. Open the admin login link, enter your email and password, click Login.
  2. If two-step verification is on, enter the code emailed to you.

Forgot password: click Forgot password?, enter your email, type the emailed code, then set a new password.

Note: Never share your password. Change it from Profile & Password if anyone else may know it.

Admin login
Admin login
Forgot password
Forgot password

Dashboard

The first screen after login — a quick overview of your business.

  • Summary cards: today's sales, orders, customers and revenue.
  • Charts: sales and revenue trends at a glance.
  • Left menu: opens every module, grouped exactly like this guide.
  • Top-right menu: your profile, change password and logout.
Dashboard overview
Dashboard overview

Dashboard Styles (Admin Panel Look)

The admin panel itself ships with four looks. Open the style switcher from the top navbar — each entry shows a screenshot thumbnail of that style, so you pick by looking, not by guessing from a name.

StyleWhat it looks like
DefaultThe original panel look — no extra stylesheet is loaded.
NewRefreshed cards, softer surfaces and updated stat tiles.
GlassGlassmorphism — translucent, blurred panels.
SidebarRedesigned sidebar-led layout.
  • Per user, not per store — the choice is saved in your session and a one-year cookie, so it survives logout and follows that browser. Another admin can run a different style at the same time.
  • Nothing else changes — only CSS. Data, permissions and every screen stay identical.
  • This is the admin panel look. The customer-facing website and the apps are styled from Web Theme / App Theme.

Developers: styles are listed in config/dashboard_themes.php. A new style = one entry there (label + stylesheet + preview image) — the switcher, the page and the validation all read that one list.

Navbar → Style switcher4 styles with thumbnails
Dashboard style
Dashboard style

Categories, Brands, Units & Tax

Supporting lists you set up once and reuse on every product. Open the screen, click Create, fill the fields, and Save.

  • Categories & Subcategories (Products → Category) — organize products (e.g. Grocery → Rice) and let customers browse. Create the main category first, then pick a parent for subcategories. Each category takes two images: a banner/thumbnail and a small icon — the icon is what the POS category strips and the app's category grid show, so set it on every top-level category.
  • Brands (Products → Brand) — manufacturers you sell, with a logo.
  • Units (Products → Unit) — units of measure (pcs, kg, litre, box).
  • Tax Rates (Products → Tax Rates) — VAT/GST percentages applied at sale.
Categories
Categories
Brands, units & tax
Brands, units & tax

Products & Attributes

Attributes (Products → Attributes / Attribute Values) are options like Size or Color with values (S/M/L, Red/Blue), used for products sold in variations.

The Products menu is split by source:

  • In-House Products — owned by your own shop.
  • All Products — combined list.
  • Deleted Products — recycle bin to review/restore.

Add a product: Products → In-House → Create; fill name, category, brand, unit, price and photos; add a description; enable variations & set their prices; set stock (or manage in Product Stocks); Publish. Use the status switch to show/hide it in the shop.

Product list
Product list
Create product
Create product
Attributes
Attributes
Edit product
Edit product

Barcodes & Labels

Every variant carries its own SKU and barcode. Leave the barcode blank and the system generates one, or type the code already printed on the supplier's packaging so the shelf item scans as-is.

  • Barcodes (Products → Barcodes) — pick products, choose a label size and print a sheet on a normal or label printer.
  • At the counter — a USB or Bluetooth scanner types the code and presses Enter; the line lands in the cart. It works the same in the web POS and the POS app.
  • Racks — a scanned item can be pinned to a warehouse rack so staff know where to pick it from.
Barcode label printing
Barcode label printing

Product Stocks & Purchase Orders

Product Stocks (Purchase & Stock → Product Stocks) shows how many units you have. Add stock with a stock entry (product, quantity, cost price); the system reduces it automatically as orders sell. Open a product for its full stock history.

Purchase Orders (Purchase & Stock → Purchase Order) record goods you buy from suppliers. A PO adds stock and creates a payable (what you owe). Choose the supplier, add products with quantity & cost, record any payment made, and Save — stock and supplier dues update automatically.

Product stock
Product stock
Purchase order
Purchase order

Adjustment · Damage · Transfer · Returns

  • Stock Adjustment — manually correct counts (e.g. after a physical count).
  • Damage — write off broken/expired goods so they leave sellable stock.
  • Stock Transfer — move stock between warehouses/locations.
  • Customer Returns — goods a customer sends back; records the refund and returns items to stock.
  • Supplier Returns — goods you send back to a supplier; reduces stock and your supplier due.

Each works the same way: open the screen → Create → pick the product(s)/original order, set quantity & reason → Save.

Stock adjustment
Stock adjustment
Customer & supplier returns
Customer & supplier returns

Warehouses & Suppliers

Warehouses & Racks (Warehouse) — where stock physically lives. Warehouses are buildings/stores; racks are shelves inside them.

Suppliers — the companies you buy from. Each supplier keeps a due/payment ledger linked to purchase orders and supplier returns. Create a supplier with an opening balance, then open it to see purchases, returns and outstanding due.

Warehouses & racks
Warehouses & racks
Suppliers
Suppliers

Inventory Costing (FIFO / Weighted Average)

Every sale needs a cost to produce a true profit figure. Sellino tracks purchase cost in stock layers and picks the cost per sale using the method you choose in Settings → POS.

  • FIFO (default) — the oldest purchase cost is consumed first.
  • Weighted Average — a running average cost across all remaining stock.
  • The chosen cost is snapshotted on the sale line, so a later purchase at a different price never rewrites past profit.
  • Feeds COGS, gross profit and the Profit & Loss statement in Accounting, plus stock-valuation reports.
  • The method is set once for the shop and applies to every branch, so cost of goods is comparable across outlets.

Pick it before you start trading. Changing the method re-values existing stock — the panel warns you before saving.

Stock valuation
Stock valuation
Settings → POScosting method

Sales

Sale List — every sale rung up at any counter, filterable by status, date, branch and payment state. Each row shows the invoice number, customer, total, what was paid and what is still due.

Sale Details & History — open a sale for its items, customer, payments and the branch and warehouse it belongs to. Footprints record who changed what and when.

Draft sales — a cart parked at the till stays a draft until it is paid. Recall it from the terminal to finish the sale, or cancel it; stock is only committed when the sale completes.

Dues & part payment — take part of the money now and the rest later. The balance shows on the customer's profile and in the due report until it is settled.

Counter invoices — print a thermal receipt at the till or share a PDF; the receipt logo and footer come from POS settings.

Sale list
Sale list & details
Sales report
Sales report

Sale Edit & Cancel

A sale that is still a draft — parked at the till, not yet paid — can be changed freely: add items, change quantity, remove a line, apply or drop a discount. Nothing is committed until payment completes, so stock and accounts stay untouched.

After payment

  • Cancel — one click with an optional note. Stock goes back to the warehouse it came from and the journals are reversed, so the books show the sale never happened. The record stays for the audit trail; deleting is not the way to undo a sale.
  • Return part of it — for "one item back, the rest stays", use a customer return instead of a cancel. That refunds only what came back and re-values the stock at its original cost.
  • Fix a payment — take the remaining due, or record the refund of an overpayment, from the sale itself.

What happens to the money

ChangeEffect
Total goes upThe extra becomes amount due from the customer — collect it now or leave it on their account.
Total goes downThe difference is refunded from the register, or left as a credit on the customer's account.
Sale cancelledMoney already taken is refunded, stock returns and every related journal is reversed.

Who may edit or cancel is a permission, so a cashier can sell all day without being able to rewrite yesterday's takings.

Sale editdraft or paid sale
Cancelstock + journals reversed

Returns, Replacements & Refunds

A customer brings something back: open the sale and raise a return (money back) or a replacement (swap for another item). Both walk through the same steps — request, inspect, then settle.

  • Inspect — mark what actually came back and its condition. Good stock goes back on the shelf at its original cost; damaged stock is written off to the damage account instead of quietly inflating your inventory.
  • Refund methodscash from the register, bank/MFS transfer with a reference, or leave it as store credit against the customer.
  • Replacement — hand over the new item, and any price difference is collected or refunded on the spot.
  • Accounting — the sale's revenue, cost of goods and any membership points are reversed in proportion to what came back, so the books follow the goods.

Returning only part of a sale? Use a return rather than cancelling the whole sale — see Sale Edit & Cancel.

Customer returns
Customer returns

POS — Counters, Registers & Cash

The POS screen is where the shop actually earns. A sale takes seconds: scan or search, take the money, print the receipt — and behind it stock moves, the drawer balances and the books post themselves.

Before the first sale

  • Counters (POS Management → Counters) — one per till. A counter belongs to a branch and has its own cash account in the Chart of Accounts.
  • Cash Registers — open a shift with the float you put in the drawer; close it at shift end with the counted cash. Any difference is recorded with a reason, so a short drawer is a fact, not an argument.
  • Cash Pickup — a manager taking cash from the drawer to the safe or bank records it here, and the expected drawer balance drops accordingly.
  • Petty Expenses — small spending out of the drawer (tea, transport, a rickshaw fare) is booked as an expense against that register.

Selling

Open the POS screen, confirm the branch shown in the bar, pick the warehouse if you keep more than one, then scan or search products. Set quantity, give a line or bill discount, apply a coupon or redeem membership points, choose the customer (or leave it as walk-in), and take payment as cash, bank, mobile money or a mix. Change is calculated for you; the receipt prints to a thermal printer or shares as a PDF.

A cart you cannot finish now can be parked as a draft and recalled later from the sale list — useful when a customer goes back for one more item.

POS Settings

  • Inventory Costing MethodFIFO (oldest purchase cost first) or Weighted Average. This drives cost of goods and profit. Changing it re-values existing stock, so the page asks you to confirm.
  • Default Customer & Warehouse — what the POS screen pre-selects.
  • Max discount, receipt logo & footer — cap what a cashier may give away, and brand the printed receipt.

The same till is in your pocket: the POS App runs the identical flow on Android and iOS, against the same counters and registers.

POS terminal
POS terminal
Counters
Counters
Cash registers
Cash registers
Cash pickup
Cash pickup

Branches (Multi-Outlet)

A branch is one physical outlet. It groups its own warehouses, its own counters and the staff who work there — so one install runs a single shop or a whole chain without the outlets stepping on each other.

Setting up

  • Branches (Warehouse → Branches) — add a branch with a name, short code, address and phone.
  • Assign each warehouse and each counter to its branch on their own edit screens.
  • Assign staff to one or more branches on the user's edit screen, and mark one as their home branch.

How much a staff member may see

Each user carries a branch visibility setting, so a cashier does not read the whole chain's numbers:

SettingWhat they see
All branchesEverything — the default, and what an owner or accountant wants.
AssignedOnly the branches they are assigned to.
Own branchOnly the branch they are currently working in.
SelfOnly the records they created themselves.

At the till

The POS screen shows an active branch bar. Where a user may work in more than one branch it becomes a switcher; picking another branch reloads the product grid, the warehouse list and the register check, because all three belong to the branch. The POS App carries the same switcher.

Branch-wise money

Every sale, journal, counter and register records the branch it happened in, so Profit & Loss, Income Statement, Trial Balance and Balance Sheet can be filtered per branch — you can compare outlets, not just guess. Stock reports take a branch filter too, and stock transfers move goods between branches with request, approve and receive steps.

Upgrading an existing install? After php artisan migrate, run php artisan branches:backfill once. It creates a default "Main Branch" per owner and attaches existing warehouses, counters and past sales to it. Without it, branch-aware screens have nothing to point at.

BranchesWarehouse → Branches
Branch switcheron the POS screen

Customers

Customers — everyone you have sold to. Add one at the counter in a few seconds (name and phone is enough), or open a profile for their full purchase history, outstanding dues and membership points.

Walk-in customer — sales that need no name go to the built-in walk-in account, so the day's takings still balance without cluttering your customer list.

Dues — a customer who pays part now and the rest later carries a balance you can see per customer and settle from the sale, with the journal posted automatically.

Suppliers live under Warehouses & Suppliers — they are who you buy from, customers are who you sell to.

Customers
Customers

Coupons, Campaigns & Membership

  • Coupons (Promo → Coupons) — discount codes the cashier applies at the till (fixed amount or percentage, with usage limits and a date range).
  • Flash Sales (Promo → Flash Sales) — time-limited price drops; the POS picks up the sale price automatically while it runs.
  • Campaigns (Promo → Campaign) — themed groups of products and offers (Eid sale, winter clearance) with a date range.
  • Membership (Membership Settings / Members) — the in-store points program used at the POS: earn rate, redeem value, minimum redeemable points and the purchase amount that auto-enrols a customer. See Membership Points for how it behaves at the counter.

Tip: Always set an end date so a promo does not run forever by accident.

Coupons & flash sales
Coupons & flash sales
Membership
Membership

Membership Points at the Counter

Membership is the in-store loyalty program: a customer joins a tier, earns points on what they buy, and spends those points as a discount on a later sale — all at the till.

  • Tiers (Membership → Settings) — set the earn rate, the minimum purchase that qualifies, and how much a point is worth when redeemed.
  • Members — join a customer at the counter; their point ledger shows every earn and redeem with the sale that caused it.
  • Redeem at the till — the cashier applies points to the open sale, in full or partially, and the discount is split across the lines so returns refund correctly.
  • Accounting — issued points are carried as a liability and released when they are spent, so profit is never overstated.

Points are earned and spent in the shop. There is no online wallet or affiliate program in this edition — those belong to the eCommerce product.

Membership tiers
Membership

Accounting

Sellino POS includes a real double-entry accounting system. Sales, purchases, returns, expenses, cash movements and payroll post journal entries automatically against your Chart of Accounts (COA) — you do not book anything twice.

  • Accounts & Banks — set up your COA, cash-in-hand, bank and mobile-money (MFS) accounts. Each counter gets its own cash account, which is why a drawer can be reconciled at all.
  • Expenses, Transfers & Owner Money — record expenses, move money between accounts, and handle owner draw or investment.
  • Journals, Transactions & Reconciliation — every journal entry, the transaction ledger, and bank reconciliation against an imported statement.
  • Financial statementsTrial Balance, Income Statement (Profit & Loss) and Balance Sheet, built straight from the general ledger for any date range — and filterable per branch.
  • Cost of goods sold — posted from the inventory costing layer, so gross profit is real cost, not an estimate.
  • Stock adjustments post journals — an IN adjustment books an inventory gain, an OUT adjustment a loss, both valued at cost.
  • Membership points are a liability — points you issue are carried until they are spent, so profit is not overstated by a discount you still owe.

Reference: see docs/wiki/ in the source for the journal mapping of each module, including returns and payroll.

Accounts & banks
Accounts & banks
Journals & reconciliation
Journals & reconciliation
Chart of accounts
Chart of accounts

HR & Payroll

Manage your staff from the same panel (HumanResource module).

  • Employees & Structure — staff records, departments and designations.
  • Attendance & Leave — daily attendance and leave requests/approvals.
  • Payroll — monthly payroll generation, posted to accounting automatically. Loans and advances given to staff are tracked and recovered from payroll automatically, each with its own journal.
  • Employee Loans — create a loan (status Pending, terms still editable), then Approve & Disburse from a cash/bank account to make it Active. Repayment happens automatically as a monthly installment inside payroll, or manually as an off-payroll cash repayment; when fully repaid it becomes Paid. Every step posts its journal to Accounting (employee-loan receivable account).
  • Salary Advances — a one-shot advance disbursed from cash/bank and recovered in full from the salary of the month you choose; the payroll run deducts it and marks it Deducted. Journaled the same way on its own receivable account.

Good to know: only disbursed (Active) loans and advances are picked up by payroll — a pending request never touches anyone's salary. Cancelling an active, un-recovered loan/advance reverses its journal cleanly.

Employees
Employees
Attendance & leave
Attendance & leave
Payroll runs
Payroll runs

Reports

Decision-ready reports across the business, most exportable.

  • Sales Reports — sales summary, by product, by category, by customer, profit and more.
  • Inventory Reports — stock value, low-stock, movement, expiry and damage.
  • Accounting & Cash Reports — trial balance, profit & loss, balance sheet, cash flow, day book and account ledgers.
Sales reports
Sales reports
Inventory reports
Inventory reports
Accounting reports
Accounting reports

Media Library & Picker

All uploaded images and videos live in one Media Library. Every image field in the panel — products, sliders, widgets, blogs, brands, categories — opens the same media picker, so you upload once and reuse everywhere.

  • Browse & search — grid view with type filter and search over file name, title and alt text.
  • Upload — single or multiple files, drag-and-drop. An identical file (same checksum) reuses the existing entry instead of storing a second copy.
  • Edit details — rename, set title and alt text (good for SEO and accessibility).
  • Usage — every file shows a used in N place(s) count, and you can list exactly where it is attached.
  • Safe delete — a file still in use cannot be deleted; remove it from those places first.
  • Automatic sizes — each upload is resized into named presets (thumbnail / medium / large) so lists and the app serve the right size.
  • Staff see the shop's one media library; who may upload or delete is a permission.

Videos have their own size cap — set it in settings (media_video_max_mb, default 100 MB).

Media Librarygrid · search · filter
Usagewhere a file is used

Website Pages (Privacy, Terms & Custom Pages)

Static content lives under Website → Pages — each page has a title, a slug and rich-text content, and is served on the site at its own URL.

  • Legal pages ship readyPrivacy Policy, Terms & Conditions and Return & Refund Policy come with placeholder text. Review and rewrite them before launch — store review teams read them.
  • The apps read the same pages — the POS app's sign-in screen links Privacy and Terms straight from here (unauthenticated, as app stores require), so one edit updates web and app together.
  • Custom pages — add any number of extra pages (About, Delivery info…); each is served at its slug automatically.
  • Widgets & Page Builder — the website's building blocks under Website → Widgets and Website → Page Builder, for installs that run a customer-facing site.
  • Page create/edit/delete are individual permissions, like every other module.
Website → Pagesprivacy · terms · custom
App legal linkssame pages, one edit

Administration

  • Users & Roles — role-based access control. Create roles with Read/Create/Update/Delete permissions per module, then assign staff to roles.
  • Languages — add languages (with LTR/RTL), set the default, and translate phrases per module. Four packs ship ready: English, Bengali, Arabic and Hebrew (the last two RTL). The same translations feed the admin panel and the POS app through the API — translate once, everywhere updates. English is the fallback and cannot be deleted.
  • Activity & Login Logs — audit trail of admin actions and login history.
Users & roles
Users & roles
Languages
Languages
Activity logs
Activity logs

Settings

  • General — store name, contact, currency, timezone, date/time format, pagination and branding (logo/favicon).
  • Appearance & Colors — primary/secondary colors, fonts and button shapes.
  • Mail — standard SMTP, or the Gmail API transport (client ID, client secret, refresh token, from-name/address) when your host blocks SMTP ports 25/465/587 — common on cloud VPS providers. A Test mail button confirms either one.
  • SMS / Push — SMS gateway, and push notifications used by the mobile apps.
  • Media & Themes — see Media Library and Web / App Theme.
  • SecurityreCAPTCHA & API key; OTP channels & social login; backups.
  • Payment Gateways — enable and key your gateways: SSLCommerz, bKash, Nagad, EPS for local payments and Stripe / PayPal for international cards — see Stripe, PayPal & Currency Rates. Use live keys over HTTPS.
  • SEO, Menus, Login — meta/SEO defaults, navigation menus, and the admin login slug.
  • Storage — keep uploads on local disk or point them at an S3-compatible bucket (see below).
  • Preference Settings — feature switches for the modules you use.

Payment keys: test keys only process test transactions. Switch to live keys on an HTTPS domain before going live.

General settings
General settings
Payment / MFS providers
Payment / MFS providers

Web Theme / App Theme

Two theme pages style what your customers see — separate from the admin panel's own look (that is Dashboard Styles):

  • Settings → Web Theme — colors and styling for the customer-facing website, on installs that run one.
  • Settings → App Theme — how the mobile apps look, delivered live through the settings API: change a color here and the apps restyle on their next launch, no rebuild, no store update.

The App Theme page controls:

  • Brand colors — primary/secondary body, text colors and the accent.
  • Corner radii — per component: cards, buttons, inputs, chips, sheets, images, badges.
  • Screen styles — pick a variant per screen (home, cart, product details, checkout, account) and per section (deals slider, category list, brand list, promo strip), with on/off toggles.
  • Preset styles — start from a preset (e.g. classic / modern) and override its tokens.
Settings → App Themecolors · radii · screen styles
Live restyleno rebuild needed

Stripe, PayPal & Currency Rates

Local gateways (SSLCommerz, bKash, Nagad, EPS) charge in your store currency. Stripe and PayPal serve international cards — and card networks cannot charge BDT, so the system converts for you:

  • The bill amount is converted from the store currency to the gateway currency (default USD, configurable) using your FX rates, and the customer's card is charged that amount.
  • The charged amount and the exchange rate used are stored on the payment, so accounting always knows both sides of the conversion.
  • Keys live in Settings → Payment Gateways — one on/off switch and key pair per gateway. Test keys only process test transactions; go live with live keys over HTTPS.

Currency Rates (Settings → Currency Rates)

  • Per-currency exchange rates with your store currency as base — edit them by hand, or hit Fetch rates to pull live rates.
  • Daily auto-update — a toggle that lets the scheduler run currency:update-rates nightly, keeping rates fresh without anyone touching the page.
Stripe & PayPalinternational cards, auto FX
Currency Ratesmanual · fetch · nightly

Security (2FA, reCAPTCHA, API Key)

  • Two-step verification — when enabled, admin login asks for a one-time code emailed to the user after the password step.
  • Google reCAPTCHA (Settings → reCAPTCHA) — on/off switch plus site key and secret key. Protects the login form from bots. Get free keys from Google reCAPTCHA admin.
  • Admin login slug — the admin panel URL is randomized, see Login & Security.

App API Key (Settings → API Security)

A shared key your own clients send as the X-App-Key header on every API request. Requests without it are rejected with 401, so random scripts hitting your API are turned away. The page shows a Protection active / disabled badge, lets you show / copy the key, tells you when it was last generated, and has a built-in How it works panel.

  • Empty = off (fail-open) — with no key configured nothing is enforced, so an install that never opens this page keeps working.
  • The blade website is exempt — browser requests from your own domain skip the check (a browser cannot hold a secret header); they are covered by session & CORS. Only non-browser callers need the key.
  • Source — the key set here wins; APP_API_KEY in .env is the fallback. A badge tells you which one is active (Managed here / From .env).

Where the key goes

ClientWhere you paste it
POS Applib/core/env/prod_env.dart (and dev_env.dart for the dev key) → rebuild

Regenerating breaks every installed app. The key is compiled into the POS app at build time — the moment you generate a new one, every app already on a phone gets 401 Unauthorized and stays broken until a new version carrying the new key is published to the stores and the user updates. Only regenerate if the key has leaked, or before your first release. The panel makes you tick a confirmation box first.

Scope: this is a casual outer filter, not strong security — a key shipped inside a mobile app can be extracted. Rate limiting is the real protection; the key removes low-effort noise and gives you a rotation kill-switch.

Settings → API Securityapp API key + regenerate
Settings → reCAPTCHAsite & secret key

OTP & Social Login

OTP channels (Settings → Preference)

  • Email OTP and Mobile OTP have separate on/off switches — run either, both, or neither. Codes are 4 digits.
  • Used for customer signup / login verification and for verifying a changed email or phone number.
  • Mobile OTP needs an SMS gateway configured in Settings → SMS; email OTP needs working mail.
  • One identifier field — login, signup, OTP and password reset all take a single box where the customer types either an email or a phone number. A phone is stored in one canonical international form, so 01811843300, 8801811843300 and +8801811843300 are the same person — no duplicate accounts, and no OTP sent to a number the customer cannot verify. Numbers typed without a country code are completed with your store's country.
  • Other switches on the same page: Order-placed email, Recently viewed, order-code and member-ID prefixes, and the barcode label defaults.

Social login (Settings → Social Login)

  • Google and Facebook sign-in, each with its own on/off switch, client ID and client secret.
  • Both off → only email/phone login is offered. Accounts created socially merge with an existing account on the same email.
Settings → Preferenceemail / mobile OTP toggles
Settings → Social LoginGoogle & Facebook keys

Real-time & Chat (Reverb)

Live features — customer ↔ staff chat and live panel updates — ride on Laravel Reverb, a websocket server that ships with the item. It is fully optional: with the daemon off, everything else keeps working.

Settings → Realtime

  • App id / key / secret — the credentials clients connect with; defaults come from .env (REVERB_*), and values saved here win.
  • Host, port & scheme — what browsers and apps connect to (production: https/wss on 443 behind your reverse proxy).
  • Server host & port — what the daemon itself binds to on the box.

Running the daemon

  • Start it with php artisan reverb:start and keep it alive with Supervisor / systemd — the same pattern as the queue worker.
  • The POS app does not use the websocket (it polls the API), so no app-side Reverb setting exists.
Chatcustomer ↔ staff, live
Settings → RealtimeReverb key · host · port

Push Notifications (Firebase)

Sellino POS sends push notifications to the POS app through Firebase Cloud Messaging (FCM) — for low stock, stock transfer requests, return requests and announcements to your staff. This is the server half, configured in Settings → Push.

  • Create a free Firebase project and download its service-account JSON.
  • On the Push page, tick Enable push notifications, upload the JSON (the Project ID auto-fills), and hit Test connection to confirm.
  • Devices register automatically when a user signs in to an app, so notifications reach the right person on all their devices.
  • Push campaigns — compose a promotional push, target an audience and send it now or schedule it; due campaigns are fanned out by the scheduler.
  • Leave push disabled and everything else keeps working — it is fully optional.

Full procedure: the mobile apps also need their own Firebase config files, and iOS needs an APNs Auth Key. Because those steps are shared by the backend and both apps, they are documented once in Common Setup → Push Notifications (Firebase).

Note: Firebase is a Google service. A project is free to create, but any usage beyond its free tier is billed by Google and is not included in this item.

Settings → Pushenable + upload JSON
App notificationstock / transfer alerts

Storage (Local or S3-Compatible)

By default all uploaded media (product images, banners, attachments) is stored on your server's local disk — nothing to configure. When you outgrow that, switch to any S3-compatible bucket (AWS S3, DigitalOcean Spaces, Wasabi, MinIO, etc.) from Settings → Storage.

  • Enter your bucket credentials on the Storage page and choose it as the active disk.
  • Storage is per-file aware — files already saved locally keep serving from local, while new uploads go to the bucket, so switching over is safe and non-destructive.
  • Great for scaling media off the app server and putting files behind a CDN.

Tip: Local disk is perfect to launch with. Move to a bucket only when your media volume or traffic calls for it.

Settings → Storagelocal / S3 bucket

Backups (Database & Files)

Two separate backup pages, both uploading to your own Google Drive: Settings → Database Backup and Settings → File Backup.

  • Database Backup — dumps the MySQL database. Fields: enable switch, mysqldump path (leave default unless your host puts it elsewhere), and the Google Drive credentials.
  • File Backup — archives the public/ directory (uploaded media). Adds a chunk size (MB) field so large archives upload in resumable parts.
  • Google Drive credentials — client ID, client secret, refresh token and target folder ID, from your own Google Cloud project. Drive storage cost is yours and not included.
  • Run themphp artisan backup:database and php artisan backup:files. Automate with the scheduler cron entry.

Always take a fresh database and file backup before updating to a new version.

Settings → Database Backupmysqldump → Google Drive
Settings → File Backuppublic/ → Google Drive

Troubleshooting

Most post-install issues come from server configuration, permissions or the .env file. Work through these before contacting support.

1. Blank page or HTTP 500 after install

  • Open storage/logs/laravel.log — it names the exact error.
  • Confirm APP_KEY is set; if empty, run php artisan key:generate.
  • Make sure the web root points to the public/ folder, not the project root.

2. "Permission denied" / cannot write to storage

  • chmod -R 775 storage bootstrap/cache; on cPanel set the folder owner to your hosting user.

3. Database connection error

  • Verify DB_HOST (usually localhost), DB_DATABASE, DB_USERNAME, DB_PASSWORD.
  • Confirm the user is attached to the database with full privileges.

4. Changes in .env not taking effect

  • After editing .env, run php artisan optimize:clear to reload config and routes.

5. Changes not showing / old data cached

  • Clear caches: php artisan optimize:clear.

6. POS says "no open register" and refuses to sell

  • A sale needs a counter in the active branch and an open cash register on it. Create the counter, then open a register with its starting float.
  • If the counter belongs to another branch, switch branch on the POS bar — a till is only usable in its own branch.

7. Emails / OTP not sending

  • Complete Settings → Mail with valid SMTP host, port, encryption, username and password, then send a test. Many hosts block port 25 — use 465 (SSL) or 587 (TLS).

8. Branch screens are empty after an upgrade

  • Run php artisan branches:backfill once. It creates a "Main Branch" and attaches your existing warehouses, counters and past sales to it.
  • The branch switcher hides itself when the operator may work in only one branch — that is expected, not a bug.

9. The POS app cannot reach the server

  • Check lib/core/env/prod_env.dart — the base URL and the app key must both match your server (Settings → API Security). A wrong key returns 401 before any screen loads.
  • On a device, localhost is the phone itself — use the server's real address.

FAQ

Q: What's included in the purchase?
The Laravel web backend (admin panel + POS terminal + API), the Flutter POS App source, the database, and this documentation.

Q: What are the server requirements?
PHP 8.3+, Laravel 12.x, MySQL 8.0+, Composer, Node.js & NPM, with the standard PHP extensions enabled.

Q: Does it have an online store?
No — this is the POS edition. It is a shop system for counter selling, stock and accounts. If you also need a customer-facing webshop and a vendor marketplace, that is our separate eCommerce item.

Q: Can I run more than one shop from one install?
Yes. Create a branch per outlet, give each its own warehouses and counters, and assign staff to them. Reports and Profit & Loss can be read per branch or for the whole chain.

Q: Does the POS app need the web panel?
It needs the same server: the app talks to the API (/api/v10/staff/*) that runs alongside the panel. Both work on the same data, so a sale made on the phone shows on the panel immediately.

Q: Does the app work offline?
No. A sale is created on the server so stock and cash stay correct across every till at once, which needs a connection. Plan for a stable network at the counter.

Q: Can I change logo, colors and texts?
Yes — branding, theme and every phrase are managed from the admin panel, no rebuild required. The receipt logo and footer are set under POS settings.

Q: Does it support multiple languages?
Yes, with LTR/RTL support. Add languages and translate phrases under Administration → Languages.

Q: How does the customer pay?
At the counter: cash, bank, mobile money (MFS) or any mix of them on one bill, with change calculated for you. Online card gateways are not part of this edition — nobody checks out on a website here.

Q: What hardware do I need?
Nothing mandatory. A thermal ESC/POS receipt printer, a USB or Bluetooth barcode scanner and a cash drawer are all supported and are what most shops use. Hardware cost is not included.

Q: How do I update to a new version?
Back up your database and .env, replace the source files (keep .env and storage/), then run php artisan migrate and php artisan optimize:clear.

Q: I still need help — what should I do?
Check Troubleshooting and storage/logs/laravel.log first, then contact us via our profile with the exact error message.

Third-Party Services & Costs

This item is a software product only. Third-party services and their costs are not included in the item price — including web hosting and domain, payment gateway accounts (e.g. SSLCommerz, bKash), SMS gateway, push-notification services (Firebase / FCM), optional cloud storage (S3-compatible buckets), the Anthropic (Claude) API or any OpenAI-compatible AI provider used for AI auto-reply, Google services (reCAPTCHA keys, Google Drive for backups, Google social login), any external vision API used for search-by-image, Meta services (WhatsApp Cloud API, Facebook Messenger, Facebook Pixel), and Apple/Google developer accounts for publishing the mobile apps. You arrange and pay for these separately, and generate your own application key and credentials during setup.

Changelog

Version 1.0.0
  • Initial release of Sellino POS — the point-of-sale edition of the Sellino platform (SITE_MODE=pos-inventory).
  • POS terminal — search or scan, cart, line and bill discounts, coupons, membership redemption, multi-payment (cash, bank, MFS or mixed) with change, draft sales and thermal or PDF receipts.
  • Counters, cash registers, cash pickup and petty expenses — open a shift with a float, close it against counted cash with a variance reason.
  • Multi-branch — branches group warehouses, counters and staff; per-user branch visibility (all / assigned / own / self), a branch switcher at the till, and branch-wise Profit & Loss, Income Statement, Trial Balance and Balance Sheet.
  • Catalog — products with category, brand, unit, tax, attributes and variations, plus barcode generation and label printing.
  • Purchase & stock — purchase orders, suppliers and dues, multi-warehouse stock with racks, lots and layers, and full movement history.
  • Stock operations — adjustment, damage, inter-warehouse and inter-branch transfer with request/approve/receive, and supplier returns.
  • Inventory costing — FIFO or weighted average, with cost of goods posted on every sale.
  • Returns, replacements and refunds — cash, bank or store credit, with stock and journals corrected in proportion.
  • Double-entry accounting — Chart of Accounts, journals, banks and MFS accounts, deposits, fund transfers, owner money, expenses and bank reconciliation.
  • Coupons, flash sales, campaigns and membership points at the counter, carried as a liability until redeemed.
  • HR & Payroll — employees, departments, attendance, salary generation, loans and advances, all journaled.
  • Reports — daily sales, sales summary, product and customer sales, cash register, cash pickup, stock, stock valuation, low stock, expiry, purchase summary, supplier dues, expenses and the full accounting set.
  • Administration — users, roles and granular permissions, activity and login logs, multi-language with RTL/LTR.
  • POS App (Flutter) — Android and iOS counter app: terminal, sales, cash, customers and loyalty, stock and reports, with the same branch switcher, thermal printing and barcode scanning.
  • Push notifications (Firebase) and local or S3-compatible media storage.