Oksa Satya.
Deep dive · POS

Dexova POS — Cashier & Reconciliation

A multi-outlet cashier with Midtrans QRIS, split payments, and per-shift cash reconciliation.

Role
Architect & Full-Stack Developer
Period
2025 – present
Category
Deep dive · POS
Source
Private repo
Stack
GoPostgreSQL + sqlcMidtransNext.js (dex-pos)Web Bluetooth (ESC/POS)

Context

Dexova POS serves two personas: cashiers work in the cashier app (dex-pos); owners and managers run products, outlets, and reports from the admin dashboard (dex-fe). The core design goal: a cashier should be productive without lengthy training, while every rupiah stays traceable.

Transaction flow

  • Product search + barcode scanning (html5-qrcode), with variants and add-ons.
  • Tiered pricing per product: retail, wholesale, member.
  • Hold & resume carts — a cashier can serve the next customer without losing a pending transaction.
  • Customer selection for member pricing and history.
  • Large catalogs stay smooth — the product list is virtualized (TanStack Virtual), and one codebase serves a tablet split-panel layout and a phone slide-up cart.
Dexova POS cashier screen: product grid on the left, cart on the right
dex-pos — cashier transaction screen (demo data)

Payments

Every payment method common in Indonesian retail, in one checkout flow:

  • Cash with change calculation.
  • Midtrans QRIS — static (one QR for all transactions) and dynamic (per-transaction QR with a locked amount).
  • Bank transfer and EDC.
  • Split payment — one transaction paid with a combination of methods.
  • Promo codes and discounts governed from the admin dashboard.
Dexova POS payment dialog with totals, tax, discount, and promo code
dex-pos — payment dialog: multi-method + split (demo data)

Shifts & cash reconciliation

The part that separates a serious POS from a sales recorder — per-shift cash accountability:

  • Open a shift with opening cash; a single-active-shift rule prevents transactions without an accountable owner.
  • Close a shift with reconciliation: the system compares expected cash against the physical cash the cashier counts.
  • Shift summaries and daily cash reconciliation are available as owner reports.
Buka shiftkas awalTransaksibarcode · varian · holdPembayarantunai · QRIS · splitTutup shifthitung kas fisikRekonsiliasisistem vs fisikvoid / retur → stok kembali otomatis (sinkron modul Inventory)
Diagram alur — rekonstruksi, bukan tangkapan layar aplikasi kasir.

Void & returns

  • Void for unfinished transactions; partial or full returns for paid ones.
  • Stock restores automatically on returns — real-time WebSocket sync with the Inventory module, no manual step.
  • Void/return access is role-scoped (cashier vs manager), revocable from the dashboard.

Hardware & reports

  • Thermal receipts over Web Bluetooth — a hand-written ESC/POS driver (not an off-the-shelf library), with reprint.
  • Owner reports: best sellers, dead stock, margins, taxes, shift summaries — PDF/Excel export.
  • Multi-outlet with per-outlet staff placement.
POS reports page in the Dexova dashboard
dex-fe — sales reports for owners (demo data)

Outcome

  • Non-technical cashiers are productive immediately; the transaction flow is built for rush hours.
  • Cash is accountable per shift — differences surface the same day.
  • Sales, returns, and stock stay consistent because POS and Inventory share one source of data.

Lessons learned

  1. 01

    Reconciliation isn't a reporting feature — it's the trust contract between owner and cashier, and it must exist from the first transaction.

  2. 02

    Automatic stock restoration on returns eliminates an entire class of 'stock doesn't match' bugs.

  3. 03

    Payment integrations (Midtrans) are safest modeled as explicit status flows, never as an assumed 'it worked'.

Need a system like this?

I take on business-system projects — from architecture planning to an application running in production.