CWPOS Documentation

Complete reference for CWPOS v1.0.0 — a self-hosted, browser-based point-of-sale system built for Caribbean retail, food service and hospitality.

1. Overview

CWPOS is a full point-of-sale system that runs entirely in a web browser. There is no app to install and no hardware lock-in — open it on a laptop, tablet or phone and start selling. All data is stored as flat JSON files; no database server is required.

Version1.0.0
PHP7.4 or higher
DatabaseNone — flat-file JSON
LicenseSingle-domain, one-time purchase (CWPOS-XXXX-XXXX-XXXX-XXXX)
HostingAny standard cPanel shared hosting with HTTPS

2. System Requirements

  • PHP 7.4+ with json, curl, session and openssl extensions
  • HTTPS — required for secure sessions and payment integrations
  • Writable data/ directory — CWPOS stores all data here
  • mod_rewrite (Apache) or equivalent URL rewriting (LiteSpeed, Nginx)
  • Browser — any modern browser; Chrome, Firefox, Safari, Edge
LiteSpeed users: URL rewriting works automatically. If you see 404 errors on all pages, check that AllowOverride All is set in your server config or contact your host to enable .htaccess processing.

3. Installation

  1. Purchase CWPOS at cwfms.com and download the ZIP from your account.
  2. Unzip and upload all files to your web server — either the document root or a subdirectory (e.g. /pos/).
  3. Make the data/ directory writable: chmod 755 data/
  4. Navigate to your CWPOS URL in a browser. The install wizard will start automatically.
  5. Enter your business name, currency, admin email, password, and your license key.
  6. Click Install CWPOS. You'll be logged in immediately.
Subdirectory installs: If you install into /pos/, your URL will be https://yourdomain.com/pos/. CWPOS detects the base path automatically — no configuration needed.
Security: The data/ directory is protected by a .htaccess deny rule automatically created at install. Verify this file exists after installation.

4. First-Time Setup

After the install wizard completes, work through these steps before your first sale:

Add products

Go to Products → New Product. At minimum set a name and price. Enable Track stock level if you want stock deductions and low-stock alerts. Products appear on the terminal immediately once marked active.

Configure categories

CWPOS seeds 8 default categories (Food, Beverages, Grocery, Bakery, Retail, Electronics, Services, General) each with subcategories. Edit or delete them under Categories. You can add subcategories one level deep.

Set your currency

Go to Settings → Company. Caribbean currencies supported: JMD, TTD, BBD, XCD, GYD, BZD. International: USD, GBP, EUR, CAD, AUD, NGN, GHS, KES.

Configure receipt

Under Settings → POS, set your receipt footer message (e.g. "Thank you for shopping with us!") and default tax rate. Enable Email receipt to customer if you have SMTP configured.

Open your first shift

Go to Shift → Open Shift and enter your opening float (cash in drawer). This enables cash reconciliation at end of day.

5. Using the Terminal

The POS terminal is at /terminal. The left panel shows your product grid; the right panel is the cart. Use category tabs to filter products.

Adding products to the cart

Click any product card to add it. Click again to add another unit. Use the + and − buttons in the cart to adjust quantities. The ✕ button removes a line item.

Category filtering

Top-level category tabs are shown by default. Clicking a parent tab with subcategories reveals a second row of subcategory tabs. Clicking a parent shows all products in that category and all its subcategories. Clicking a subcategory shows only that subcategory.

Product search

Type in the search box to filter by product name or SKU. The search filters within the currently selected category. Clear with the ✕ button.

6. Cart & Discounts

Percentage discount

Enter a number in the Disc % field. Applies to the entire order subtotal before tax.

Fixed discount

Enter an amount in the Disc field (currency symbol). Capped at the subtotal. Takes priority over percentage if both are filled.

Discount codes

Type a code in the Discount code field and press Enter or click the tag icon. The code is validated live — expired, inactive or fully-used codes are rejected with an error. A valid code shows a confirmation toast and is applied to the total after the percentage/fixed discount. Remove it with the ✕ button.

Loyalty points redemption

If a customer is selected and they have enough points, a redemption row appears. Enter how many points to redeem, click Redeem, and the equivalent discount is applied. The minimum redemption threshold is set in Settings → Loyalty.

7. Payment Methods

CashNumpad entry for amount tendered. Change calculated automatically. Sale recorded instantly.
CardProcess on your card terminal. Confirm in CWPOS and click Complete — no integration with card machines required.
TransferBank transfer, LYNK, WiPay peer-to-peer, Zelle, etc. Cashier confirms receipt then completes the sale.
CWPay integration: If you have CWPay installed, you can generate a payment link from the terminal for remote or phone orders. The sale is automatically recorded when the customer pays the link.

8. Receipts

Thermal receipt printing

After a sale, click Receipt in the success modal. A print-optimised page opens automatically. Use your browser's print dialog — select your thermal receipt printer and set paper size to match your printer (typically 80mm or 58mm roll). No driver installation is needed.

Email receipt

Enable in Settings → POS → Email receipt to customer. Requires SMTP configured under Settings → Email / SMTP and the customer must have an email address on file. The HTML email contains all line items, discounts, total and your receipt footer.

Receipt content

Receipts show: business name and address, transaction number, date/time, cashier name, payment method, all items with quantity and price, discounts applied, tax, total, cash tendered/change (if cash), customer name (if attached), and the receipt footer message from Settings.

9. Hold & Recall

Park the current cart to serve another customer without losing the sale. Click the pause icon in the cart header to hold the sale. Enter an optional label (e.g. "Table 4" or "Phone order") and click Hold.

Click the layer icon to open the Held Sales panel. All parked sales are listed with cashier, time, and total. Click the play icon to recall any held sale back into the cart. Click the trash icon to discard it.

Multiple held sales: There is no limit. Each held sale is stored in data/held_sales.json and survives page refreshes but not server restarts. Complete or discard held sales before closing the shift.

10. Open / Custom Items

Enable in Settings → POS → Allow open-price items. A Custom button appears in the search bar. Click it, enter an item name, price, and tax rate, and add it to the cart. Open items are not linked to any product in the catalogue — they appear in the receipt with the name you entered.

Note: Custom items do not affect stock levels, as they have no product ID.

11. Barcode Scanner

CWPOS supports standard USB and Bluetooth HID barcode scanners without any configuration. Scanners act as a keyboard — rapid keystrokes ending in Enter are intercepted by the terminal. The scanned value is matched against product SKU fields.

Setting up SKUs

Enter the barcode value (EAN-13, Code 128, QR, etc.) in the SKU / Barcode field when creating or editing a product. The scanner will match against this value (case-insensitive).

How it works

The scanner is active whenever no input field is focused on the terminal page. When a barcode is scanned, CWPOS first searches the visible product cards, then falls back to the server search endpoint. On a match, the product is added to the cart and a toast notification appears.

Sensitivity: CWPOS uses an 80ms threshold between keystrokes to distinguish scanner input from normal typing. If you have a slow scanner, contact support.

12. Products

FieldDescription
NameRequired. Shown on terminal cards and receipts.
SKU / BarcodeOptional. Used for barcode scanner lookup.
CategoryParent or subcategory for terminal filtering.
Selling PriceRequired. The price charged at the terminal.
Cost PriceOptional. For margin tracking — not shown to customers.
Tax Rate (%)Applied per line item. Defaults to the setting in Settings → POS.
Stock QuantityStarting stock if tracking is enabled.
Track StockEnable to deduct stock on each sale and trigger low-stock alerts.
Image URLOptional. Full URL to a product image shown on the terminal card.
ActiveInactive products are hidden from the terminal but kept in the system.

13. Categories

Categories are one level deep — a parent category can have subcategories, but subcategories cannot have their own children. CWPOS seeds 8 parent categories on installation, each with multiple subcategories.

Adding a top-level category

Use the Add Category form on the left. Set a name, colour (shown on product cards), and an optional emoji icon.

Adding a subcategory

Use the Add Subcategory form. Choose the parent, enter the name and colour. The subcategory appears indented under its parent in the tree and in the terminal's second tab row.

Deleting categories

Deleting a parent also deletes all its subcategories and moves all affected products to Uncategorised. Deleting a subcategory moves its products to the parent category.

14. Stock Management

The Stock page (Catalogue → Stock) shows all products with Track Stock enabled, sorted by stock level ascending.

Receiving stock

Click Receive on any product row. Enter the quantity received and an optional note (e.g. "Invoice #1042"). Stock is added immediately and logged.

Manual adjustment

Click the sliders icon to set an absolute stock count with a reason (e.g. "Stocktake — 3 damaged"). Use this for write-offs or corrections.

Stock history

Click the clock icon on any product to see all stock movements — sales, receives, adjustments, and void restorations.

Low stock alerts

Set the threshold in Settings → POS → Low Stock Alert Threshold (default: 5). When a product's stock drops to or below the threshold after a sale, an email is sent to the company email address. Alerts fire at most once per product per day.

Dashboard warning: The dashboard shows a banner with the count of low-stock and out-of-stock products. Click the banner to go directly to the filtered stock view.

15. Customers

The customer directory lets you attach a customer to each sale for purchase history, loyalty points, and receipt emails. Enable the customer field on the terminal under Settings → POS → Show customer selection on terminal.

Customer profile

Click the eye icon in the customer list to open the profile page. It shows lifetime spend, visit count, last visit, full purchase history, and loyalty points history.

Attaching a customer at the terminal

Type in the customer search field. Results appear as a dropdown with name, phone, email, and points balance. Click to select. The loyalty row appears if the customer has enough points to redeem.

16. Loyalty Points

Configure the programme under Loyalty in the sidebar (admin only).

SettingDescription
Points per $1 spentHow many points a customer earns per currency unit. E.g. 0.1 = 1 point per $10 spent.
$ value per pointMonetary discount per point. E.g. 0.01 = 100 points = $1 off.
Minimum to redeemPoints balance required before redemption is offered. Default: 100.

Points are awarded automatically after every completed sale. The loyalty row appears on the terminal when a customer with enough points is selected. Admins can manually adjust points from the Loyalty page with a reason note.

17. Discount Codes

Create and manage codes under Discounts in the sidebar (admin only). Cashiers enter codes at the terminal without needing access to this section.

FieldDescription
Code2–20 uppercase letters, numbers, hyphens and underscores. E.g. SUMMER20.
TypePercentage (e.g. 20% off) or Fixed amount (e.g. $500 off).
Max Uses0 = unlimited. When the limit is reached, the code auto-deactivates.
Expiry DateOptional. Code rejects after this date.

Discount codes are applied on top of any percentage/fixed cart discount. They cannot reduce the total below zero.

18. Shift Management

Shifts let you track cash drawer reconciliation per cashier. Open a shift before the trading day and close it at the end.

Opening a shift

Go to Shift → Open Shift (or click the banner on the dashboard). Count your cash drawer and enter the opening float. A shift is now active for your account.

Shift dashboard

View live revenue totals by payment method under Shift → Current Shift. The sidebar shows a shift indicator when a shift is open.

Closing a shift

Go to Shift → Close Shift. Count the cash drawer, enter the actual amount, add a note, and submit. CWPOS calculates the variance (expected cash vs counted cash) and saves the shift report.

Shift report

Shows opening float, cash sales, expected closing cash, actual counted cash, variance, card/transfer totals, and total revenue. Accessible in Shift History for any past shift.

19. Transactions

Every completed sale is recorded as a transaction with a sequential number (e.g. TXN-2026-0042). The number prefix and pattern are configurable in Settings → POS.

Voiding a transaction

Admin only. Opens the transaction, click Void and confirm. The transaction is marked voided, and stock levels for tracked products are restored automatically.

Refunds

Admin only. Marks the transaction as refunded with a note. Does not automatically restore stock — use the Stock Adjustment if needed.

Note: Voiding and refunding are manual records. CWPOS does not initiate a payment reversal with any gateway — you must process that separately through your card terminal or bank.

20. Reports

ReportWhat it shows
Daily SalesRevenue by day with bar chart, payment method breakdown, date-range filter.
Product SalesRevenue and quantity per product, sortable by revenue, with share bars.
End-of-DayFull day summary — KPIs, payment methods, cashier breakdown, shifts, top products. Printable.
Cashier PerformanceRevenue, transaction count, items sold, tax collected, share, and busiest trading hour per cashier.

All reports are filterable by date range. The End-of-Day report has a Print button that hides all UI chrome for a clean printout.

21. Settings

SectionContains
Company / ShopBusiness name, address, phone, email, TRN, currency, country, brand colour.
POS SettingsTransaction number prefix/pattern, default tax rate, receipt footer, low stock threshold, receipt email, open items, customer field.
Email / SMTPHost, port, username, password, encryption, from name and address. Test email button.
CWInvoice IntegrationWebhook URL and secret for pushing sales to CWInvoice.
CWPay IntegrationWebhook secret for receiving CWPay payment confirmations.
Change PasswordAdmin account password update.
LicenseCurrent key (masked) and field to enter a new key.

22. Staff Users

The admin account (created at install) has full access. Additional cashier and supervisor accounts can be created under Staff in the sidebar.

Roles

  • Admin — full access including settings, discounts, loyalty, shift history, void/refund, delete.
  • Supervisor — same as cashier plus void/refund access (when permission granted).
  • Cashier — terminal, transactions, and any modules explicitly enabled.

Permissions

Each user can be granted individual module access: Terminal, Products, Categories, Customers, Transactions, Reports. Unchecked modules are hidden from that user's sidebar.

Admin password: Change the admin password under Settings → Change Password. Staff account passwords are changed via the edit button on the Staff page.

23. Integrations

CWInvoice → CWPOS (inbound)

Not currently implemented. CWInvoice integration is outbound only.

CWPOS → CWInvoice (outbound)

After each completed sale, CWPOS posts a signed webhook to your CWInvoice installation. CWInvoice creates an invoice record marked as paid. Configure in Settings → CWInvoice Integration: enter the webhook URL from your CWInvoice install (Settings → CWPay Integration → Webhook URL) and the matching secret.

CWPay → CWPOS (inbound webhook)

When a CWPay payment link is paid, CWPay sends a signed webhook to CWPOS at /webhook/cwpay. CWPOS matches the transaction by the pos_txn_ref field and marks it completed. Configure the webhook URL in your CWPay installation under Settings → CWPOS Integration. The webhook URL for your CWPOS install is:

https://your-domain.com/cwpos-path/webhook/cwpay

The webhook secret must match in both systems.

CWFMS (via CWPOS → CWInvoice → CWFMS)

Direct CWFMS integration is not built into CWPOS. Route sales through CWInvoice, which can post journal entries to CWFMS.

24. Audit Log

Every significant action is recorded: sales, voids, refunds, logins, logouts, stock movements, category and product changes, user management, and settings updates. The log is append-only and stores up to 2,000 entries (oldest pruned automatically).

Filter by entity type (transaction, product, user, etc.) or action (sale, voided, login, etc.) using the dropdowns at the top of the Audit Log page.

25. Troubleshooting

ProblemSolution
500 error on all pagesCheck your PHP version is 7.4+. Verify .htaccess is uploaded and URL rewriting is enabled on your server.
404 on all routes except homepagemod_rewrite / LiteSpeed rewrite is not active. Contact your host to enable .htaccess processing or AllowOverride All.
Products not showing on terminalCheck products are marked Active on the Products page.
Stock not updatingVerify Track Stock Level is checked on the product. Check stock under Catalogue → Stock.
Receipt email not sendingVerify SMTP settings under Settings → Email. Use the Test Email button to confirm delivery. Check the customer has an email address.
License validation failsVerify the key format: CWPOS-XXXX-XXXX-XXXX-XXXX. Check curl is enabled in PHP. Ensure cwfms.com is reachable from your server.
Barcode scanner not workingEnsure no input field is focused when scanning. Check the SKU field on the product matches the barcode exactly.
data/ directory errorRun chmod 755 data/ via SSH or file manager. The web server user must be able to write to this directory.

26. Go-Live Checklist

  1. HTTPS is active and the padlock shows in the browser.
  2. Company name, address, phone, currency and TRN are set in Settings.
  3. At least one product is added, categorised and marked Active.
  4. Receipt footer message is set (Settings → POS).
  5. Default tax rate matches your jurisdiction (e.g. 15% GCT for Jamaica).
  6. Staff accounts created with appropriate permissions.
  7. SMTP tested and working if you want email receipts.
  8. Low stock threshold set and alerts tested (Settings → POS).
  9. License key is valid — check the dashboard loads without a license error.
  10. Open a shift before starting your first trading day.
Support: Questions? Email admin@cwfms.com or visit cwfms.com/contact.