← Back to Blog
Retail Technology

Building WIK POS: An Offline-First Point of Sale for Kenyan Retail

April 26, 2026 10 min read By WIK Technologies Team

Walk into most small or medium retail shops in Nairobi today and you will find one of two things: a battered exercise book with handwritten stock tallies, or a shared WhatsApp group used to relay sales to the owner. Most existing POS software either costs more than the shop earns in a week, requires a stable internet connection that cuts out whenever the rain comes, or ships without any M-Pesa support at all. We built WIK POS to fix that.

WIK POS is a native Windows desktop application that runs entirely offline, stores everything in a local SQLite database, and treats M-Pesa as a first-class payment method — not an afterthought. This post covers the full journey: from the problem we identified in Kenyan retail, through the standard version, to the Premium edition and everything it adds.

The Problem: POS Software Was Not Built for Kenyan Shops

Kenyan retail has a very specific operating environment that most off-the-shelf POS products ignore entirely:

  • Internet is unreliable. Power cuts, congestion, and ISP outages happen daily. A cloud-dependent POS that locks you out during downtime is a liability, not a tool.
  • M-Pesa is the primary payment method. Cash is still king, but M-Pesa is used for the majority of transactions. Most imported POS systems have no concept of it.
  • Hardware budgets are tight. Most shops already own a basic Windows laptop or desktop. Requiring new, proprietary hardware is a non-starter.
  • Piracy is a real risk. Selling software without protection means a single licensed copy gets installed on twenty machines.
  • Multi-staff accountability matters. Shop owners need to know who processed what sale, restocked which product, and when.

The product requirement was clear: build something that works on the hardware shops already own, runs without internet, handles Cash and M-Pesa natively, attributes every action to a named staff member, and cannot be pirated without consequence.

What WIK POS Standard Delivers

Cash, M-Pesa, and Split Payments

The checkout modal handles three payment methods in one consistent flow. Cash shows quick-denomination buttons (50 / 100 / 200 / 500 / 1,000) and auto-calculates change. M-Pesa displays the expected amount prominently for the customer to send, and captures the M-Pesa reference code — required for Admin users for accountability, optional for Cashiers to keep checkout fast. Split payment lets a customer pay part by M-Pesa and the remainder in cash; entering one amount auto-fills the other, and live validation ensures the two parts equal the total.

Inventory Management with Full Audit Trail

Every stock change — whether from a sale, a manual restock, or a damage adjustment — writes a row to the stock_movements table recording who made the change, what changed, when, and why. This is not optional telemetry; it is the core of how the system keeps the owner honest and gives them a tool to reconcile discrepancies. Low-stock alerts appear on product cards and as a banner on the inventory page when stock falls to or below the configured reorder level.

Staff Roles and PIN Login

Every app launch requires a staff PIN login. Staff are either Admin (full access including reports, settings, and staff management) or Cashier (checkout and inventory). PINs are stored as SHA-256 hashes — plain PINs never touch the disk. Every sale, restock, and adjustment records the staff_id of the logged-in user, so the owner always knows who did what.

Reports and Analytics

The reports module covers three tabs: Sales (KPI cards, daily revenue bar chart, payment method pie chart), Products (top products by units sold, gross profit margin per product, drill-down into every individual sale of any product), and Stock (total inventory valuation, low-stock and out-of-stock lists, movement summary for the period). All date ranges are timezone-aware — local day boundaries are converted to UTC before hitting SQLite, so "Today" always captures the correct Nairobi business day.

Thermal Receipt Printing and Database Backup

Receipts print to any 58mm or 80mm thermal printer through the system print dialog. Past receipts can be reprinted at any time from the Receipts page. Database backup saves a timestamped copy of the SQLite file to any folder the shop owner chooses, and restore brings it back with an automatic app restart. Automatic backup runs on a configurable schedule (daily, weekly, or monthly) silently in the background.

Why Premium Happened

After shops started using the standard version, the feedback we heard most was consistent: the core works well, but growing shops needed more. Loyalty schemes to retain repeat customers. Automatic discounts and promotions without the cashier manually applying them. Barcode scanners to speed up checkout. Supplier purchase orders so restocking had a paper trail. A second screen facing the customer so they could see what they were being charged.

The decision was deliberate: keep Standard clean and approachable for small shops, and build Premium as a separate product for retailers that are scaling. Cramming all of that into one tier would have made the simple checkout feel heavy and confusing for shops that just need to ring up sales and go home.

What WIK POS Premium Adds

Promotions Engine

Managers configure promotion rules — BOGO (Buy X Get Y Free), cart-level percentage or fixed discounts, product-specific discounts, and category-wide discounts. At checkout, all active eligible promotions are evaluated simultaneously and the system automatically applies the one that gives the customer the best saving. No coupon codes, no manual selection. If the cashier has already applied a manual cart discount, that takes precedence.

Customer Loyalty CRM

Every customer has a points balance. Points are earned automatically based on spending and can be redeemed as a checkout discount. The Customers page shows a searchable directory with full purchase history per customer. For shops running any kind of repeat-customer business — supermarkets, butcheries, pharmacies — this turns the POS into a lightweight CRM without requiring a separate subscription.

Product Variants

Products like beverages, clothing, or electronics often come in multiple sizes or configurations with different prices and independent stock levels. Premium handles this with a variants system — each variant has its own SKU, price, cost, and quantity. At the POS, adding a product with variants opens a picker so the cashier selects the right one. The variant name is recorded on the receipt.

Customer-Facing Display

A second window can be opened on a monitor facing the customer, showing their live cart — items, quantities, discounts applied, and the total amount due. It updates in real time as items are added or removed. After payment, it switches to a confirmation screen showing the amount paid and change returned. The entire communication happens over Electron IPC — no network connection needed, no second device, just a second monitor plugged into the POS machine.

Barcode Label Printing and USB Scanner Support

Every product in inventory has a label printing button. The label dialog lets you choose between 38mm and 58mm sizes, set the quantity to print, and generates a real CODE128 scannable barcode from the product SKU as an offline SVG — no internet required. At checkout, plugging in any standard USB HID barcode scanner requires zero configuration. The system distinguishes scanner input from keyboard typing by keystroke timing: scanner keystrokes arrive under 50ms apart, while manual typing does not.

Procurement and Supplier Management

Suppliers are stored in a directory with contact details. Purchase orders are created against a supplier with multiple line items. A purchase order moves through a lifecycle — Draft, Ordered, Received. When marked as Received, the stock quantities for every line item are automatically updated in inventory. The purchase order history stays on record for financial review and reconciliation.

Audit Log and Z-Report

Every sensitive operation — product deletions, sale voids, manual adjustments — is permanently written to an audit log with the staff member's name and timestamp. Admins can filter by date range and action type and export to CSV. The Z-Report generates an end-of-day summary for any calendar date: total sales, payment method breakdown, tax collected, discounts applied, and net revenue — printable directly to a thermal printer or PDF.

Why We Made the Technology Choices We Did

Electron + React + TypeScript

We chose Electron because it produces a real native Windows application — not a web app running in a browser tab. It installs like normal software, has its own taskbar icon, and works without any browser. React and TypeScript on the renderer side gives us a fast, type-safe UI layer with the full ecosystem of modern web tooling. The result is a desktop app that looks and feels polished but was built at web-development speed.

SQLite via better-sqlite3

SQLite requires zero configuration, runs in the same process as the app, and stores everything in a single file that the shop owner can back up to a USB drive. There is no database server to maintain, no connection string to configure, and no monthly database hosting fee. For a shop running on one Windows machine, it is exactly the right tool.

Hardware-Bound JWT License

Every installation is cryptographically tied to the specific machine's CPU and MAC address. The license key generates a signed JWT that includes the machine fingerprint. On every launch the app recomputes the fingerprint and compares it — if it does not match, the token is invalidated. This prevents a single key from being passed between machines while still allowing the shop to operate fully offline for up to seven days before it needs to check in with the license server.

Technical Challenges Worth Knowing About

1. The Offline Grace Period

The hardest licensing problem was this: how do you protect against piracy without punishing a legitimate shop that loses internet for a week? The answer is a 7-day offline grace period baked into the JWT. On every launch, the app verifies the JWT locally — no internet needed. If more than 7 days have passed since the last successful server check, the app attempts a server ping. If offline, it grants grace and lets the shop in. If the server responds and finds the license revoked, access is denied immediately. A background heartbeat runs every 15 minutes while the app is open, so revocations (such as for a stolen device) take effect within 15 minutes of the device coming back online.

2. The Timezone Bug That Silently Broke Reports

SQLite's current_timestamp stores UTC, but JavaScript's Date parses strings without a timezone suffix as local time. When the app first launched, receipt timestamps were 3 hours behind East Africa Time (UTC+3), and the "Today" filter in Reports was missing sales made before 3am UTC — which is midnight Nairobi time. The fix was applied in two places: formatDate() now appends Z to SQLite timestamp strings before parsing, forcing UTC interpretation; and getDateRange() converts the local start-of-day and end-of-day boundaries to UTC before passing them to the SQL WHERE clause.

3. Virtualized Product Grid

A shop with 200 products in the POS grid would bring most React apps to a crawl if every card was rendered into the DOM at once. We solved this with DOM virtualization — only the product cards currently visible in the viewport are mounted. Scrolling replaces them. The result is that the POS page loads and scrolls at the same speed whether the catalogue has 20 or 2,000 products.

4. Distinguishing Barcode Scanner from Keyboard

USB HID barcode scanners appear to the operating system as a keyboard — they just type very fast. The challenge is that both a cashier manually typing a product name and a scanner scanning a barcode produce keydown events on the same input. The solution is keystroke timing: scanner keystrokes arrive less than 50ms apart. The POS page measures the gap between consecutive keystrokes; if a burst arrives at scanner speed and ends with an Enter key, it is treated as a barcode scan and matched directly to a product SKU, bypassing the search filter entirely.

What We Learned Building It

1. Offline-first is non-negotiable for Kenyan retail

Every architectural decision flowed from this. SQLite instead of a hosted database. Local license verification before any server check. Electron instead of a web app. If the product cannot run without internet, it cannot be trusted as a business tool in Nairobi.

2. License protection must not punish legitimate users

A POS that locks a shop out of their own sales data because of an internet outage is worse than no protection at all. The grace period was not a concession — it was a product requirement. Get that balance wrong and legitimate customers suffer while pirates just crack the binary anyway.

3. Keep tiers genuinely separate

It was tempting to add Premium features to Standard with a flag. We did not. The two products have different codebases, different UI, and different pricing. A small shop should never feel like they are using a crippled version of something bigger. Standard is complete on its own terms.

4. Build the audit trail from the very first commit

Adding stock movement logs retroactively to an existing product means backfilling data that does not exist. Starting with stock_movements on day one means every sale, restock, and adjustment from the first transaction is in the log. Shops that have been running for months have a complete reconciliation record — which is exactly when it becomes most valuable.

Try WIK POS for Your Shop

Both editions are available for Kenyan businesses. Standard is built for shops that need a clean, fast, offline POS. Premium is built for retailers that are scaling and need loyalty, promotions, barcode scanning, and procurement in one system.

Get in touch and we will walk you through a live demo, help you choose the right tier, and handle installation and staff training.

Request WIK POS Demo Request Premium Demo View Portfolio

WIK POS reflects how we approach software at WIK Technologies: start with the real operating environment, not an idealized one. Build around the constraints — unreliable internet, tight budgets, M-Pesa as a payment standard — and the product will actually be used.