The POS module is a paid add-on (₹550/month — see Add-ons). It’s a fast, counter-style billing screen with thermal-receipt printing, split tender, line + bill discounts, hold/recall, item-based returns, and offline mode that queues sales locally and syncs when you’re back online.
Time to read: ~15 minutes. You’ll need: the POS add-on active, at least one product with Type = Goods and a sale price, and at least one Cash / Bank / UPI account in your Chart of Accounts.
What you get when this is done
- A counter screen optimised for speed: barcode scan, item grid, customer picker, three-box tender.
- Split tender across cash, card, and UPI — each settles to its own deposit account.
- Line discounts + bill discounts (both percent and flat), correctly pro-rated across GST buckets.
- Hold / Park a sale, recall it later.
- Returns / refunds: a real
sales_returnvoucher + per-tender refund splits. - 80mm thermal receipts that auto-print on confirm.
- Offline mode: catalogue cached locally, sales queue offline with idempotency keys, provisional receipts, auto-sync on reconnect.
Where to find the screen
From the sidebar: Daily → Point of Sale.
The POS lives in its own dedicated screen with a session card on top and the cart + tender below.
Step 1 — Open a session
Every POS sale belongs to a session (a shift / day at the counter). Before the first sale of the day:
- Open Daily → Point of Sale.
- The Open session card appears.
- Confirm or change:
- Cash float — the starting cash in the drawer.
- Tender accounts — per-mode deposit accounts (cash → cash GL, card → card-merchant GL, UPI → UPI settlement GL). Defaults are remembered per terminal in browser localStorage.
- Voucher book — the POS voucher book to use (defaults to “POS”; sales carry their own series like POS/2026/00001).
- Click Open session.
The session is active for the rest of the day. Subsequent sales add to this session until you Close session.
Step 2 — Take a sale
The main POS screen has three areas:
| Area | Purpose |
|---|---|
| Item grid / barcode (left) | Pick or scan products to add to the cart. |
| Cart (middle) | Edit qty, discount, tax-rate per line; see live total. |
| Tender (right) | Cash / Card / UPI boxes; change-due auto-computed. |
Adding items
Two ways:
- Barcode scan — scan / type into the barcode field. The product is added (qty 1 by default). Scan again to increment qty.
- Item grid — click the product tile. (Grid is searchable by name / SKU.)
Quick-add a customer (optional)
A walk-in cash sale doesn’t need a customer. For credit sales or customer-loyalty:
- Click the Customer pill (top of cart).
- Pick from the dropdown, or click + Quick add to create one with just a name + phone.
- The customer’s AR sub-account is created if it didn’t exist.
Discounts
On each line:
- D % — discount percent.
- D ₹ — flat discount (applied after percent, floored at 0).
Or at the bottom of the cart (whole-bill):
- Bill discount %
- Bill discount ₹ — applied after per-line discounts, capped at subtotal.
Bill discounts are pro-rated across lines in proportion to each line’s post-line-discount amount, so GST per tax bucket scales automatically. (Verified on mixed-bucket carts e.g. 5% + 18%.)
Treatment: contra-revenue (reduces Sales, not a separate expense).
Charge
When the customer is paying, fill the Cash / Card / UPI boxes — one, two, or all three. Change due auto-computes (only against cash).
- For card: tap your card terminal externally, type the approved amount into the Card box.
- For UPI: click the UPI QR button to show a dynamic QR with the amount pre-encoded; customer scans + pays from their UPI app; type the amount into the UPI box once confirmed.
Click Charge. Booksmor:
- Posts the sales voucher (per item lines + GST).
- Posts one receipt per non-zero tender split, each to its configured deposit account.
- Updates session totals.
- Opens the 80mm thermal receipt in the print dialog.
The cart clears; you’re ready for the next customer.
Hold / Park
Customer needs to step away mid-sale? Click Hold at the top of the cart. The sale is parked under the session.
To recall: click the Recall pill (it shows the parked count). Pick from the modal → the cart loads. Recall is destructive — recalling deletes the parked row.
Step 3 — Returns and refunds
For returning previously-sold items.
- From the POS header, click ↩ Return.
- In the modal:
- Lookup — search by voucher # / customer name / phone / ISO-date. Only POS sales are searchable.
- Pick the original sale; Booksmor shows its lines + already-returned-per-line.
- Tick the items being returned + set return qty per line.
- Refund splits — how the customer is being refunded:
- Cash — comes out of the drawer (records a CashRegisterMovement).
- Card — books to card_refunds_payable (you push the actual card refund via your terminal; payable nets later).
- UPI — books to upi_refunds_payable (you push the actual UPI refund; payable nets later).
- Leave empty — credit stays on customer’s AR for “store credit”.
- Click Process return.
Booksmor:
- Posts one sales_return voucher (Cr Accounts Receivable for the return amount).
- Posts one journal voucher per non-zero refund split (Dr AR / Cr [refund_account]).
- Restores stock at moving-average cost (Dr Inventory / Cr COGS).
Honest minimal: Booksmor only BOOKS the refund. Pushing the actual card/UPI refund happens externally on your terminal / app. The owner clears the payable accounts later (typically monthly).
Offline mode
The POS works offline, by design. Connection drops? Keep selling.
What works offline
- Catalogue lookup — item search, barcode scan, customer picker, all served from a local IndexedDB cache (refreshed on every successful unfiltered fetch when online).
- Sales — the Charge button enqueues the sale locally with an idempotency key + temp ID. A provisional 80mm receipt opens immediately with an “OFFLINE — PROVISIONAL” banner.
- The header shows a ⚠ Offline pill and a clickable N queued pill.
What doesn’t work offline
- Returns — need original voucher lookup, which needs the server.
- Z-report — needs full session aggregation, which needs the server.
- Reports + dashboards.
Auto-sync on reconnect
When connection returns, Booksmor drains the queue serially. Each queued sale is posted with its idempotency key, so even if the network blips again mid-sync, sales are never duplicated.
If a queued sale fails for a non-network reason (e.g. validation), it surfaces as a toast for manual review.
Stock conflicts on sync
If two offline terminals sold the last unit, one will succeed and the other will fail validation. Resolve via the per-item allow_negative_stock flag (set on the product if you allow it) or by manually adjusting one of the sales.
Z-report and closing the session
At end of day:
- Open the session card at the top of the POS screen.
- Click Close session.
- Booksmor shows the Z-report summary:
- Opening cash float.
- Cash sales received.
- Cash refunds out.
- Expected cash in drawer.
- Counted cash input — type the actual cash you counted.
- Difference (over / short).
- Confirm to close.
The session is closed; its data stays in your books for audit. New sales start a fresh session next time.
Common questions
Why a separate POS module — can’t I just use Sales Invoices? You can — but the POS module is built for counter speed (barcode scan, sub-second tender, thermal receipt). The standard Sales Invoice form is designed for full B2B invoices with multiple addresses, due dates, etc. — too slow for a 30-second retail transaction.
Can I use POS on a phone or tablet? Yes — it works as a PWA on mobile browsers. Layout adapts. The thermal receipt prints to any printer connected to the device (you may need a small bridge app for some Bluetooth thermal printers).
Which Cash account does cash settle to? Whichever you configured in the session’s Tender accounts → Cash. Defaults to the COA’s Cash account. You can pin a specific cash drawer’s GL account if you have multiple counters.
Card / UPI refunds — why don’t they auto-push to the gateway?
Booksmor doesn’t integrate with card terminals or external UPI gateways for refund initiation (intentionally — these vary by acquirer and terminal model). The refund payable accounts (card_refunds_payable, upi_refunds_payable) are the bookkeeping side; you handle the actual gateway refund + reconcile.
Can I have multiple terminals on the same session? Each terminal opens its own session by default. For “multiple cashiers on one logical till” semantics, you can have them all use the same tender accounts + voucher book — the sales aggregate at the GL level even if they’re on separate sessions.
Why does Recall delete the parked sale? By design — once recalled, the cart is editable. Booksmor doesn’t keep two versions of the same parked sale.
Loyalty / gift cards? Not in the current release. Loyalty + gift cards are on the roadmap.
Can the POS print a customer-facing display (price-shown-to-customer second screen)? Not in the current release. Customer-facing display is on the roadmap.
Troubleshooting
Barcode scan doesn’t add the item. The SKU on the product doesn’t match the barcode. Edit the product (Masters → Products), set SKU to exactly the barcode value, save.
UPI QR shows “amount missing”. The cart total is 0 (no items added). Add at least one item before generating the QR.
Charge button fails with “negative stock not allowed”.
A line item would push stock below 0 and the item doesn’t have allow_negative_stock enabled. Either reduce qty, replenish stock, or enable the flag on the product.
Offline pill won’t disappear after reconnect. Browsers can be slow to detect reconnect. Try clicking the page header refresh, or just trigger a small action (search a customer) — the connection check fires and the pill flips.
Queued sale didn’t drain after coming back online.
The auto-drain fires on the 'online' event. If it didn’t, click the N queued pill to open the queue and click Sync manually.
Need more help? Email support@booksmor.com with the session ID and what’s misbehaving.