RobOS Point of Sale · Retail, coffee shops and bars

Your counter. Your business. Your point of sale.

An open-source register for the way you work: scan a shelf item, build a custom coffee, or keep a tab open for the next round. Take orders, track stock, manage prep and count the drawer on your own computer.

No subscription or cloud account. A touchscreen interface, staff permissions, customer self-checkout and an open checkout API, with your shop data stored locally.

Choose your starting point

One register, three ways to run your counter

Each business has its own sample shop, step-by-step tutorial and short video. Try the sample, then make the menu, team and settings your own.

Main Street General Store

Retail store

Scan stocked goods, choose sizes, apply promotions, and handle returns with manager approval.

  • Barcode and camera scanning
  • Size variants and stock tracking
  • Promotions and manager-approved returns
Follow the retail store tutorial →
Recorded in the real app using sample data and demo payments. Watch on YouTube

Bean There Coffee

Coffee shop

Customize drinks, take cash with change due, and move paid orders through the barista queue to collection.

  • Required drink choices and priced extras
  • Cash tender, change and tips
  • Barista prep and customer-ready displays
Follow the coffee shop tutorial →
Recorded in the real app using sample data and demo payments. Watch on YouTube

The Rusty Anchor

Bar

Keep named tabs open, send rounds to prep stations, record an ID check, and close the tab with a tip.

  • Named tabs and repeated rounds
  • Separate bar and kitchen prep queues
  • Recorded ID checks, tips and split payments
Follow the bar tutorial →
Recorded in the real app using sample data and demo payments. Watch on YouTube

Shared setup and reference

RobOS Point of Sale Guide

Install the app, set up your team and payments, then use the reference below for cash, scanning, self-checkout and the checkout API. Sample card payments are demonstrations; configure a real payment workflow before trading.

Step 1

Install it and open your first shop

It is a normal RobOS app. You can also run it on any computer with Node.js, with no account and no internet connection.

  1. Open it. Launch RobOS Point of Sale from the App Launcher, or run cd packages/point-of-sale && npm install && npm start.
  2. Pick a starting point. On first launch choose Retail store, Coffee shop or Bar to get a ready-made menu, stock, taxes and team. You can edit everything afterwards, or replace it with another sample from Settings.
  3. Sign in with a PIN. The samples use owner 1111, manager 2222 and cashier 3333. Add your own team in Team & API and retire the sample PINs before real use.
  4. Open the drawer. Go to Cash, count your starting cash, type it on the number pad and press Open drawer. Card sales do not need the drawer; cash sales do.
  5. Ring a sale. On the Register tap items (or scan them with a scanner or the camera), press Pay, choose cash or card. The receipt appears with any change due.

Your data lives in one file, ~/.config/robos/point-of-sale/store.json, readable only by you. Back it up by copying it.

Step 2

Who can do what

Every team member signs in with a 4 to 8 digit PIN. Lower roles can borrow a manager for a single action without switching users.

RoleEveryday workAlso allowed
Cashier / serverSell, hold tabs, take cash and card, discounts up to the limit, prep screen, open and close their own drawer—
ManagerEverything a cashier doesRefunds, comps, voiding sent items, big discounts, paid in / paid out, receiving and counting stock, reports, cash payment settings, closing a drawer that is over or short
AdminEverything a manager doesMenu and catalog, taxes, promo codes, happy-hour rules, team, API keys, settings, loading samples

When a cashier taps something that needs a manager (a refund, a comp, a 40% discount), a PIN pad appears. The manager types their PIN, the action goes through, and the approval is recorded in the audit log next to the cashier's name. Five wrong PINs in a row lock the sign-in screen for a minute.

Step 3

The screens

Each screen is built for fingers: large buttons, an on-screen number pad for PINs, cash and quantities, and no tiny controls. Text fields such as item names use the device's own on-screen keyboard.

ScreenWhat you do there
RegisterChoose the order type (dine in, take-out, tab, retail), tap items, pick sizes and options, apply promo codes or discounts, add a tip, check ID, send to the kitchen or bar, hold, void or pay. Pay supports exact change, quick-tender buttons, split by 2, 3 or 4, or by item.
TabsOpen tabs and self-checkout orders waiting to be paid. Tap one to carry on. Type an order number to find a customer's order.
PrepOne screen per station (kitchen, barista, bar). Start, Ready, Picked up. The customer-facing board at /ready shows numbers that are ready.
OrdersRecent orders and receipts. Open one to refund items (a manager approves) and put returned items back in stock.
InventoryReceive a delivery, count the shelf (a reason is required), add stock items, import a CSV, spot low stock. Food and drink recipes use ingredients up automatically.
Menu & CatalogItems with sizes, barcodes and prep stations; option groups such as Size and Milk; categories; taxes; promo codes; happy-hour rules. Hiding an item keeps its history.
CashOpen and close the drawer, paid in and paid out, and the cash payment settings.
ReportsSales by category, tender and item for today or all time, drawer history, CSV export.
Team & APIAdd or deactivate team members and create checkout API keys.
SettingsBusiness name and type, tax included in prices or added on top, tipping, card provider, self-checkout options, stock rules, and sample businesses.

Step 4

Setting up cash payments

Managers and admins decide how cash behaves. Open Cash and scroll to Cash payment settings.

SettingWhat it does
Accept cash paymentsTurn off for a card-only shop. The Cash button disappears from the pay sheet and the server refuses cash.
Require an open drawerOn by default. Cash sales and cash refunds need a counted drawer so the day always balances.
Cash roundingNone, or nearest 5, 10, 25 cents or $1 for places without pennies. The rounding shows as its own line on the receipt and in the Z-report.
Quick-tender buttonsUp to six dollar amounts shown on the pay sheet, plus Exact and the next whole dollar.
Largest cash tenderGuards against a typo like $5000 instead of $50.
Over/short limitHow far off a cashier's count may be before a manager has to approve closing the drawer.
Bills and coins countedThe denominations shown as tap-to-count buttons when closing. The count is blind: cashiers do not see the expected total until they have counted.

End of shift: Cash → Count & close drawer, tap the bills and coins, press Close drawer. The Z-report shows expected, counted and over or short, plus the day's sales.

Step 5

Self-checkout and customer displays

Self-checkout is a customer-facing page that only does one thing: build a basket and pay. It cannot see staff data, prices of hidden items, or other customers' orders.

  • Open it from RobOS Point of Sale → Open self-checkout window, or browse to /kiosk. For a dedicated screen, start the app with --kiosk.
  • A tablet on the shop network. Run node serve.js --host 0.0.0.0 on the till computer and open http://<till-ip>:3410/kiosk on the tablet. There is no encryption on this connection, so use a network you trust.
  • Retail: a scan box accepts a barcode scanner that types into a field, and a camera button reads barcodes and QR codes from a webcam. Food: big icon tiles, required choices, tips.
  • Paying. Card is shown only when the card provider can run unattended (a gateway, not a standalone terminal where a worker types the approval code). Pay at the counter gives the customer a number; the cashier finds it under Tabs and takes cash.
  • Safety. Age-restricted items are never offered, and the server rejects them even if someone calls the API directly. Baskets nobody paid for are cleared after 30 minutes. Switch self-checkout off, or turn off pay-at-the-counter, in Settings.
  • Order-ready board. Put /ready on a second screen; it shows pick-up numbers as the kitchen marks them ready.

Retail and anywhere with a shelf

Barcodes, QR codes and the webcam

Plug in any barcode gun or use a webcam. The camera reads the classic UPC and EAN barcodes and the newer 2D codes: QR codes (including GS1 Digital Link, which carries a product number as a web address), Data Matrix and Aztec. However a code was printed, the register works out which product it means.

How a scan becomes a saleA barcode gun, a webcam and a shopper at self-checkout all send a code to the register, which works out the product from it and adds it to the order. Barcode guntypes the code + Enter Webcam on the tillreads 1D and 2D codes Self-checkout camerashopper scans a tag Work out the productany padding, any format Line added to the orderwith the right size
Every path ends in the same lookup, so a product can be printed as a UPC, an EAN or a QR code and still be found.

Three ways to scan

  1. Barcode gun (USB or Bluetooth). Most scanners act like a keyboard: they type the code and press Enter. Click the scan box on the Register (it is focused for you in a retail shop) and scan. No setup.
  2. Webcam. Press the camera button. Choose the camera if you have more than one, hold the barcode or QR code in front of it, and wait for the beep. A code held in view counts once; take it away and show it again to add another.
  3. Self-checkout. The same two options, for shoppers: the scan box for a gun, or the camera button.
  4. Adding products. On Menu & Catalog → Add item, press the camera button next to the barcode field and scan the package. A Digital Link QR is saved as the plain product number.

Cameras only work on localhost or an https:// address, and the desktop app asks for video access only. A tablet opening the till over plain http:// on the shop network should use a barcode gun instead.

What you can scan

What you scanWhat it containsHow the register uses it
UPC-A / EAN-13 / EAN-8 barcodeA product number (GTIN)Matched however it was printed: a UPC-A, the same number as an EAN-13 with a leading zero, or a 14-digit GTIN are one product.
UPC-E small-package barcodeA compressed UPC-AExpanded to the full UPC-A before matching.
QR code with a GS1 Digital LinkA web address such as https://id.gs1.org/01/09506000134352/10/LOT7The GTIN in the address is the product. Lot and serial numbers are ignored for pricing.
Data Matrix (GS1)A GTIN followed by lot or expiry data, e.g. 01…10LOT-7The GTIN is the product.
QR or Aztec code with your own textA SKU you made up, such as HM-MUGMatched to the SKU (or barcode field) of an item.
Sized goodsA barcode that belongs to one sizeAdds that exact size. A code that names only the product asks the shopper or cashier to choose a size.
Anything else (a web address, a code not in the catalog)—Nothing is added, and the screen says so.

Seen in the app

Each picture below is a real screenshot from the automated tests: a generated code is played into a test webcam and the register reads it. (Cameras for the pictures are simulated; the decoding and the register are real.)

A barcode gun types into the scan box and the item is added
A barcode gun types into the scan box and the item is added
Webcam: a classic UPC-A barcode
Webcam: a classic UPC-A barcode
Webcam: the same product as an EAN-13 (UPC-A with a leading zero)
Webcam: the same product as an EAN-13 (UPC-A with a leading zero)
Webcam: an EAN-8 on a small package
Webcam: an EAN-8 on a small package
Webcam: a QR code holding a GS1 Digital Link
Webcam: a QR code holding a GS1 Digital Link
Webcam: a GS1 Data Matrix with a lot number
Webcam: a GS1 Data Matrix with a lot number
Webcam: an Aztec code holding a SKU
Webcam: an Aztec code holding a SKU
Webcam: a QR code holding your own SKU
Webcam: a QR code holding your own SKU
A barcode that names one size adds exactly that size
A barcode that names one size adds exactly that size
A code that is not in the catalog is explained, nothing is added
A code that is not in the catalog is explained, nothing is added
Self-checkout: a shopper scans a tag
Self-checkout: a shopper scans a tag
Adding a product: the camera fills in the barcode field
Adding a product: the camera fills in the barcode field
Use cases tapped through on a touchscreen browser (13)
  1. register camera reads a UPC-A barcode and adds the item once, even if it stays in view
  2. the same product printed as an EAN-13 (UPC-A with a leading zero) is recognised
  3. a modern QR code carrying a GS1 Digital Link is read and matched by its GTIN
  4. a GS1 Data Matrix (GTIN plus lot number) is read
  5. an Aztec code holding a SKU is read
  6. a QR code holding a plain SKU is read
  7. a sized product is added with the exact size its barcode names
  8. an EAN-8 barcode (small packages) works once the shop has an item with that code
  9. a valid code that is not in the catalog is explained, and nothing is added
  10. self-checkout: a shopper holds a QR tag to the camera and it lands in the basket
  11. self-checkout: an unknown or age-restricted code is refused with a friendly message
  12. item form: scanning a QR with a GS1 Digital Link fills the barcode field, and it is saved as a plain GTIN
  13. without a camera, or with access blocked, the scanner says what is wrong

Every business

The cash drawer and cash settings

Cash is handled the way a till is: a counted float at the start, paid-in and paid-out entries with a reason, a blind count by bill and coin at the end, and a Z-report that shows over or short. Managers decide whether cash is accepted at all, whether prices round to the nearest 5 cents, what the quick-tender buttons are, and how much over/short a cashier may close without a manager. Use the business tutorials above to try a sample sale, then follow the drawer setup below.

Cash payment settings (manager)
Cash payment settings (manager)
Counting the drawer with bill and coin buttons
Counting the drawer with bill and coin buttons

For developers

The open checkout API

Websites, apps and agents can create a checkout session, update it, and complete it with a payment token. The shape follows the open Agentic Commerce Protocol checkout flow; amounts are whole cents and retries are safe with an Idempotency-Key. Card payments go through a plug-in provider, so the register never touches card numbers. The OpenAPI document is served at /api/openapi.json.

Endpoints

Method and pathPurpose
POST /api/v1/checkout_sessionsCreate a session from items (id, SKU or barcode, quantity, optional variant_id and modifiers), optional buyer and fulfillment_option_id. Returns 201.
GET /api/v1/checkout_sessions/{id}Current status, line items and totals.
POST /api/v1/checkout_sessions/{id}Change items, buyer, fulfillment option or add a promo code.
POST /api/v1/checkout_sessions/{id}/completePay with payment_data.token (and provider). A declined card returns 402 and the session stays open.
POST /api/v1/checkout_sessions/{id}/cancelCancel an unpaid session.

Status moves not_ready_for_payment → ready_for_payment → completed (or canceled). Totals come back as a list of items_base_amount, subtotal, tax and total in cents. Age-restricted items are refused at completion. Send Authorization: Bearer <key>; create keys in Team & API. This follows the shape of the Agentic Commerce Protocol checkout flow but is not a certified implementation, so test an agent against it before relying on it.

curl -X POST http://127.0.0.1:3410/api/v1/checkout_sessions \
  -H "Authorization: Bearer $POS_KEY" -H "Content-Type: application/json" \
  -d '{"items":[{"id":"<item id, SKU or barcode>","quantity":2}],"fulfillment_option_id":"takeout"}'

curl -X POST http://127.0.0.1:3410/api/v1/checkout_sessions/<id>/complete \
  -H "Authorization: Bearer $POS_KEY" -H "Idempotency-Key: order-1001" -H "Content-Type: application/json" \
  -d '{"payment_data":{"token":"tok_visa","provider":"mock"}}'

Good to know

What it does not do yet

Being honest about the edges saves surprises on opening day.

  • Card processing. The built-in card options are a standalone terminal (you key in its approval code) and a demo gateway that approves any card, which must never be used for real sales. To take cards online or unattended, add a provider for your processor; the README shows the small interface.
  • Tax. A flat rate per item, either added on top or already included in prices. There is no address-based lookup, so confirm your local rules.
  • Hardware. Barcode scanners that type into a text box work, and so does a webcam. The browser only allows camera use on localhost or an https:// address, so a tablet that opens the till over plain http:// on the shop network cannot use its camera; give it a hardware scanner or put the till behind HTTPS. Receipts print through the system print dialog and are also available as plain text for ESC/POS printers. There are no direct cash-drawer or printer drivers yet.
  • Not included yet: gift cards, loyalty, several locations syncing together, staff time clocks.
  • Backups. One shop file on one computer. Copy it regularly.