HorecaPOSManual Introduction Go to the POS
EN

HorecaPOS manual

This manual comes in three parts: first for the staff (waiters), then for the manager and finally for the administrator. Each part builds on the previous one: a manager can do everything the waiters can, and the administrator can do everything.

What your role is allowed to do is set by the administrator in Settings → Permissions. If you don't see a button, your role doesn't have permission for it (yet).

This manual is also in the POS: tap the © button at the bottom right of any screen and choose Manual, or open http://<kassa-pc>:3000/handleiding. See also the introduction and the API documentation.

Part 1 · Staff

Getting started

Signing in. Open the POS on the till, tablet or phone and enter your PIN (4 to 8 digits). You will then see the floor plan.

Sign in with PIN

Opening a table. Tap a table. A free table gets a new order; at an occupied table you continue with the existing order. At the top you switch between rooms (for example Dining room and Terrace). For the counter use Quick sale, for takeaway orders Takeaway.

Floor plan

Ordering. Choose a category and tap the products. They appear on the receipt on the left. Optionally choose the course first (1 = straight away, 2 and 3 wait until you call them away). Tap Send order: the kitchen tickets then go to the kitchen and the bar. As long as you haven't tapped Send order, you can simply remove lines.

Checking out. Tap Checkout, choose Card / Bancontact, Cash or Gift card, optionally a tip, and confirm. With card payments the payment starts automatically on the card terminal. The receipt is printed; you can also email it.

Checkout

Logging out. Log out when you are done, so nobody else works under your name. After 8 hours you are logged out automatically.

No internet? The POS simply keeps working. If the top bar shows No internet · card manually, enter the amount on the card terminal itself and choose Already paid on the terminal in the checkout screen.

Several groups at one table

Several groups can sit at one table, each with their own bill and their own receipt.

Split the bill at checkout

Checkout screen

Checkout works as always: All at once. In the checkout screen the bill can now also be split, with the buttons below Back and Checkout (so they always stay in view, without swiping):

A partial payment only records the payment; the bill stays open and the order screen shows "already paid … · still open …". The receipt (with all payments on it) comes with the last payment, as with a normal checkout. Card payments via the integration are for exactly the partial amount. Once part has been paid, lines can no longer be moved to another group and no more discounts can be added; removing is only possible if enough is still open. Every partial payment is logged.

Quick sale and takeaway (without a table)

Table floor plan with Quick sale and Takeaway

At the top right of the table screen are Quick sale and Takeaway. Both immediately open an order without a table. Quick sale is a sale at the counter (eat-in VAT); Takeaway uses each product's takeaway VAT rate. With "Customer name" you add a name; it appears on the receipt ("Takeaway – Smith") and at the top of the kitchen ticket. Open orders without a table are listed under the room buttons ("No table: Takeaway #12 – Smith"), so you can find them again. If you go back without selling anything, the empty order disappears automatically.

Both buttons can be switched on or off per venue in Settings → Business, directly below the light/dark theme (on by default). Off = button hidden; orders without a table that are already open remain visible.

Delivery and time slots

Orders you take yourself at the till, for example by phone or at the counter, with the same rules as the webshop: delivery areas and a maximum number of orders per time slot. Turn on under Settings → Business → Delivery and time slots, directly below the Quick sale and Takeaway buttons (off by default).

Extensions (all off by default; without these settings it works exactly as above):

Code: lib/bezorgen.ts, routes/bezorgen.ts, BezorgDialoog.tsx, BezorgInstellingen.tsx, BezorgKaart.tsx and lib/kaart.ts (the map, without an extra package; the same code is in the webshop as public/kaart.js).

Telephony: recognise the customer on a phone order

Settings → Telephony (off by default; switching it off keeps everything). Two separate switches:

The search covers the loyalty card, the POS delivery and takeaway orders, the webshop, Thuisbezorgd, the delivery platforms and the reservations. Numbers are normalised (+31 6 1234 5678, 0031612345678 and 06-12345678 are the same; Belgian numbers too).

How the number comes in (more at once is possible; the same call counts once):

SourceForSet-up
Webhook / action URL3CX (CRM integration), Aircall, Voys / VoIPGRID, Yeastar P-Series, desk phones with an action URL for an incoming call (Fanvil, Grandstream, Mitel 6800/6900, Snom, Yealink: works with any phone system and provider), integration services (Zapier, Make, n8n, Power Automate)the address from Settings → Telephony (/api/telefonie/oproep?sleutel=...&nummer=...), GET or POST, JSON, form or query; also via the portal: https://<portaal>/telefonie/<kassa-id>/oproep?sleutel=...
Asterisk (AMI)Asterisk, FreePBX, Issabel, VitalPBX, Grandstream UCMaddress, port (5038; Grandstream UCM 7777), AMI user and password (permissions call)
FRITZ!BoxFRITZ!Box with telephonyaddress (fritz.box) and port 1012; turn on the call monitor once with #96*5*
USB caller ID modemanalogue landline with caller ID displayserial port (COM3, /dev/ttyACM0), baud and init command (default AT+VCID=1)
Android phonethe built-in phone of a business Android phoneHorecaPOS app on that phone, Settings → Telephony → Pair this phone (Android 10+: choose the app as the caller ID app)

The response contains the caller, also as contact (firstname, lastname, phone, email, address) for a 3CX CRM template. Outgoing and internal calls are not shown; Only these lines limits it to certain lines or desk phones. Calls are deleted after the retention period (default 30 days, GDPR). Test call simulates a number calling.

Code: apps/pos-server/src/lib/telefonie.ts, routes/telefonie.ts, packages/shared/src/telefonie.ts; screens Telefonie.tsx, BezorgDialoog.tsx; Android android-app/native/java/Beller*.java. Log: Telephony.

Own drivers: runs, cash handover and track & trace

For businesses with their own drivers. Turn it on under Settings → Business → Delivery → Own drivers (off by default). The driver does not need an app: they use a page in the browser on their own phone (if they prefer, they can use the Optimum Bezorger app: see Driver app below).

Creating a run. The till has a Runs button (showing the number of deliveries still to go out plus the runs that are on the way).

  1. Under Ready for delivery, tick the orders that are going along. These are the delivery orders from the till, the webshop and Thuisbezorgd (only own delivery; not those with a Thuisbezorgd driver).
  2. Choose the driver (a staff member) and the float they take along (by default the amount from the setting), and tap Create run.
  3. A QR code appears. The driver scans it with their own phone and sees, per address, the name, the address with a Route button (navigation), Call, the note, the requested time and what to collect. There is a change calculator (customer gives € 50 → change € 31,50). No login is needed. Only share the link with the driver: anyone who has it can see the addresses on this run. QR code for the driver creates a new link; the old one then stops working.
  4. Tap Depart when the driver leaves. The float is taken from the drawer (cash out, with the reason). The customer is told the order is on the way:
    • for an order from the till by text message and/or email, if Messages to the customer is on (see Delivery and time slots);
    • for the webshop as set up in the webshop (email, text message or push notification);
    • for Thuisbezorgd via Thuisbezorgd.

If the run has not left yet, it can still be cancelled.

  1. On the road the driver taps, per address, Delivered, cash, Delivered, card (their own card terminal) or Delivered (already paid). The till sees this immediately. If the driver cannot report it, it can also be done in the till. Back at the business, the driver taps I'm back at the restaurant.

Cash handover. After the run, tap Checkout (permission Manage cash drawer):

Track & trace (turned on separately in the setting). When the order is on the way, the customer gets a link to a tracking page on the portal. The link is in the text message or email, and in the webshop on the status page (Track your driver). The tracking page shows:

The pages appear in the phone's language (all portal languages). In the till you can see with each run when the location was last updated (with a link to the map).

Privacy. The portal keeps the data of a run (names, addresses, phone numbers, the location) only while the run is in progress. Everything is deleted when the run is settled, or otherwise after 24 hours. The customer only sees their own order. The driver's location is only visible during the run, and no longer once the driver is back.

Route planning (optional)

Turn it on under Settings → Business → Delivery → Route planning (off by default; works with own drivers). The Runs window then has a Suggest runs button. The POS combines the orders still waiting to go out into runs:

Use this run ticks those orders, in that order; choose the driver and tap Create run. For a run that has not left yet, Best order puts the addresses in the fastest order (also on the driver's phone). Each run shows the distance and the travel time.

Settings: addresses per run, maximum run duration, the time window, the courier's speed (bike ~15, scooter ~25, car ~35 km/h in town) and the minutes per address (parking, ringing the bell, payment; default 2). The manager may also set these numbers: in the Runs window with the Set up route planning button (permission Set up route planning, on by default for the manager; can be changed under Settings → Permissions). Switching route planning on or off and the routing service (address, API key) remain with the administrator.

Distance and travel time, chosen by the manager:

Test tries out the service. If the service fails, planning falls back to the estimate and says so. An address whose location is unknown (no valid postcode and house number) appears in the suggestion under no known location and is not planned. The configuration export includes the settings, but not the key.

Code: lib/ritplanning.ts.

Driver app (optional)

Turn it on under Settings → Business → Delivery → Driver app (off by default; works with own drivers and the management portal). Each driver then pairs their own phone once, instead of scanning a QR code for every run:

  1. Under Paired phones, choose the driver (a staff member), optionally the name of the phone, and tap Pair phone.
  2. A QR code appears. The driver scans it in the Optimum Bezorger app (Pair button), or with the phone's camera: the page then opens in the browser. It also works without the app and can be added to the home screen.
  3. The pairing stays valid until you revoke it; the phone then immediately stops seeing anything. A new pairing for the same staff member replaces the old one (for example with a new phone).

The app or page shows all of the driver's own runs (every run the till creates for this driver), with the same buttons as for a run: Route, Call, amount to collect with change calculator, Delivered and I'm back at the restaurant. Can be turned on separately:

The Android app is available on Google Play and on the portal's download page (/download/). An iPhone version is ready but will only be released once there is an Apple developer account; until then iPhones use the web page. A run the driver picked up themselves shows picked up in the app by the driver.

Code: lib/bezorgersapp.ts, in the portal src/volgen.mjs and the app in the horecapos-bezorger repo.

The log records who created a run, dispatched it, marked it delivered and settled it, with the amounts. Turning it off: no Runs button; runs and settings are kept.

On the portal: /bezorger/<sleutel> and /volg/<code>. Code: lib/bezorgers.ts, routes/bezorgers.ts, Bezorgers.tsx and in the portal src/volgen.mjs.

Alert for long lead time

A takeaway or delivery order that is ready later than promised: the till spots it and alerts you, and can send the customer an apology straight away, optionally with a credit voucher. Switch it on under Settings → Business → Delivery → Alert for long lead time (off by default).

Code: lib/telaat.ts, routes/telaat.ts, TeLaat.tsx and packages/shared/src/telaat.ts.

The Send order button: what it does and when you need it

Tapping a product and tapping Send order are two separate steps:

Why two steps? At the table you take the whole order (drinks, starter, main course), adjust things if the guest changes their mind, and then send it to the kitchen in one go, with one ticket per station instead of one ticket per product. That way the kitchen can get started long before anyone pays.

What else happens when you tap Send order:

You can also check out directly. If you tap Checkout while there are still new lines on the bill, the till sends them first automatically, so the kitchen and the bar always get their ticket. At the bar or for takeaway you don't need to tap Send order first: tap the items and go straight to Checkout. If the automatic send fails (no connection, all-you-can-eat rule, black box), the checkout screen stays closed and you see why.

Rather not print a ticket for the bar when you check out straight away? Under Settings → Business → Ordering and checkout, tick Direct checkout without order ticket. Then only what you send with Send order goes to the kitchen and bar; whatever you check out straight away gets no order ticket.

Large or small Checkout button

With the Large "Checkout" button checkbox ticked, the order screen shows a large Checkout button directly below the ordered products: wide, tall and with the amount on it, so it is quick to hit. If part of the bill has already been paid, the button shows the amount still open. The small button at the bottom next to Send order is then hidden.

With the large button, the buttons in the checkout screen are large too: Checkout (for Card, Gift card and the other payment methods) and, for Cash, Exact cash and Checkout are wide and tall, easy to hit, even with dirty fingers (for example at a butcher's). The payment methods are a bit larger and the tip buttons a bit smaller, so everything stays on screen.

On a new installation the checkbox is off: then the small button at the bottom next to Send order and a checkout screen with normal buttons. Prefer large? In Settings → Business, directly below light/dark theme, tick Large "Checkout" button. A till that was already in use keeps what it had. The choice applies to all tills and tablets of the business.

Mark a product as "sold out"

Anyone can long-press a product in the order screen (or right-click it) and choose Sold out. The product then turns grey and can no longer be ordered on any till. In the same way you restore it with Available again. Every change is logged. The administrator can still do this in Settings → Products too. The till server also refuses a product marked "sold out" ("Cola" is sold out), so also from a tablet that hadn't received the change yet or orders stored offline; that tablet then shows "Could not send".

Kitchen display (KDS)

Alongside (not instead of) the kitchen ticket printers, the kitchen or bar can use a display. On a tablet/PC in the kitchen open http://<kassaserver>:3000/keuken, sign in with a PIN and choose the station: these are the same names as the printers (kitchen, bar, ...), so the display shows exactly what would be on that kitchen ticket. "All" shows all stations.

The display updates itself instantly. Kitchen tickets still print as usual; if you don't use the display, you won't notice any difference.

Kitchen display: sending on, order and course

Settings → Printers → Kitchen display. Each part can be switched on separately and is off by default; switching off keeps everything.

Kitchen printer off or no kitchen display

The POS always keeps working, even if the kitchen or bar printer is off (or out of paper, or the cable is loose) and even without a kitchen display:

Courses (starter, main course ...)

The course buttons are only shown when they are needed: as soon as there is a set menu (composite product) on the order, or when something is already in course 2 to 4. With ordinary products, such as a cola, you don't see them and everything goes straight to the kitchen. There is nothing to set.

Below the order list is Course 1 2 3 4. By default course 1 is selected and everything works as always: "Send order" sends everything to the kitchen straight away, without course headings on the kitchen ticket. If you choose course 2 (or higher) before tapping products, then:

Course 1 always goes straight away. If course 2 has already been called, a dish added later in course 2 also goes straight away.

Allergens per product

Off by default: allergens are then not shown anywhere. Switch on via Settings → Business → Enter and show allergens per product.

All-you-can-eat

Off by default. Turn it on via Settings → Business → All-you-can-eat (administrator only). You create one or more packages, e.g. Fish, Meat and Sushi, each with:

Use ↑ ↓ to set the order. It matters when a dish belongs to several packages: it then counts for the top one the group has chosen. Delete removes a package for new tables; tables already running keep their price lines (fewer people is still possible there, more is not).

At the table:

Gift cards

Two switches under Settings → Business → Gift cards:

Top-up credit (optional)

For clubs, sports canteens, youth centres and events: a gift card with balance becomes a top-up pass. Switch it on under Settings → Business → Top-up credit, below the gift cards (off by default; only works if Sell gift cards with balance is on).

Meal vouchers

Only for businesses in Belgium, off by default: Settings → Business → Checkout → Meal vouchers. Meal vouchers are an employee benefit: the employer loads them onto the employee's card (Edenred, Monizze or Pluxee). The guest pays with it on the normal card terminal; no connection with the issuers is needed.

Foreign currency

Cash payment in another currency, e.g. for British or American tourists, or Swiss francs in border regions. Off by default: Settings → Business → Checkout → Foreign currency. Add the currencies (CHF, CZK, DKK, GBP, HUF, NOK, PLN, SEK, TRY, USD) with a rate per currency: how many euros you charge for 1 unit (e.g. 1 GBP = € 1.15).

Extra buttons for ordering and checkout

Buttons for things not every business needs. Everything is off by default; turn them on per button under Settings → Business → Ordering and checkout (permission Set up business, payments and printers). Off = the button appears nowhere in the POS and the POS server refuses the action. In the Netherlands everything works without a black box; in Belgium a button only works once that function has been tested with the black box (the button says so if that is not yet the case).

When opening a table:

When ordering (order screen, for whatever you tap next):

At checkout:

Afterwards (Receipts):

Code: apps/pos-server/src/lib/kassaopties.ts, routes/kassaopties.ts; screen KassaOpties.tsx. Log: Setting changed, SPV redeemed, Correct receipt, Unpaid.

Deduct advance

An advance (deposit, e.g. for a party or a reservation) is sold as a regular product with Advance turned on (Settings → Products; always has an open price). Create one per VAT rate if the advance must be per rate (e.g. Advance food and Advance drinks), or one product if it is part of the quote. The guest pays the advance beforehand and gets a receipt.

Turn on: Settings → Business → Ordering and checkout → Deduct advance (off by default). At the final checkout, tap Deduct advance on the order screen and enter the receipt number of the advance. The POS adds the advance lines of that receipt to the bill with a negative quantity (same product, price and VAT). What has already been deducted cannot be deducted again. If the advance is more than the bill, the guest gets the difference back (refund). In Belgium the deducted lines go to the black box as a refund (REFUND) (UC4110, UC4111, UC4113). Log: Advance deducted.

Receipt by email

Off by default. Turn it on via Settings → Business → Receipt also by email.

SMTP_HOST=smtp.voorbeeld.nl
SMTP_PORT=587
SMTP_GEBRUIKER=kassa@voorbeeld.nl
SMTP_WACHTWOORD=...
SMTP_AFZENDER=bon@voorbeeld.nl

Restart the till after filling this in. Checkout then shows the field Also email the receipt (optional): leave empty = print only, as always; enter an email address = the same receipt (with VAT breakdown and fiscal lines) is also emailed to the guest, with the business name as sender.

Reservations

Turn it on under Settings → Business → Reservations (off by default). There you also set how many minutes beforehand a reserved table appears on the floor plan (default 60) and the default duration of a reservation (default 120 minutes).

TheFork POS integration: table opens on arrival, bill sent back

With TheFork's POS API the till works together with TheFork Manager (off by default), in addition to fetching the bookings above. Switch it on under Settings → Booking platforms → TheFork POS integration; runs via the management portal.

TheFork documentation: https://docs.thefork.io/POS-API/introduction

Waiting list for walk-ins

For guests without a reservation who are waiting for a table. Turn it on under Settings → Business → Waiting list (walk-ins) (off by default). Only visible when SMS via CM.com is set up; otherwise the waiting list appears nowhere in the till (not even in the settings). Works separately from reservations: also when those are off. That is also where you set the text of the message (empty = "Hallo {naam}, uw tafel bij {zaak} is klaar. Wilt u zich melden bij de bediening?"; {naam}, {zaak} and {personen} are filled in).

Loyalty card / points

Turn it on under Settings → Business → Loyalty card / points (off by default, then none of it is visible anywhere). There you also set: points per euro (0 = stamp cards only), after how many points a reward is given and how many euros discount that reward is worth.

Guest profile: VIP, dietary requirements and preferences (optional)

Turn on under Settings → Business → Guest profile, below the loyalty card (off by default; only works when the loyalty card is on). Then:

Favourites / quick buttons

Off by default. Settings → Business → Favourites / quick buttons:

Another round

On the order screen there is the ↻ Another round button (as soon as something is on the bill, even if it has not been ordered yet). One tap adds the last round (everything sent in one go with "Send order", or what you just tapped) once more as new lines; then just tap Send order. Prices are the current ones (including happy hour).

Table time on the floor plan

Every occupied table shows ⏱ 45m · 12m: how long the table has been occupied and how long ago something was last entered (tap and hold the table, or hover over it with the mouse, for the exact times). If nothing has been ordered for a while, the table gets an orange border: time to check in. You set the number of minutes under Settings → Business → Table time (default 20, 0 = no orange border). If nothing has been entered yet, the time counts from when the table was opened.

If several groups (separate bills) sit at one table, there is a line per group, e.g. G1 ⏱ 50m · 12m and Jansen ⏱ 10m (the group name, otherwise the group number). A group that has been idle too long gets an orange label and the table an orange border.

Move a whole table

The order screen has Move table. Choose the area (e.g. Terrace) and a table: all groups at the table move along, each with its own bill. If you choose an occupied table, the tables are merged (the groups are added). If you only want to move part of it, use Split / move as before. If everything has to go on one bill, use Merge.

Keep working offline (tablet without Wi-Fi)

If the connection between a tablet and the till server drops (Wi-Fi on the terrace, server briefly off), a yellow bar appears and the tablet keeps working with the last saved tables, products and open orders:

Number of guests

Optional and off by default: Settings → Business → Ordering and checkout → Track number of guests. Off = as few taps as possible: a free table opens with one tap, guests are not shown anywhere, and the report, dashboard and daily summary show no guests and no spend per guest.

On: when you tap a free table, the POS asks how many guests (large buttons 1-8, or type it in; "Skip" = 1). On the floor plan, an occupied table shows "3/4 ppl" (people/seats, yellow if more people are seated than there are seats). In the order screen you change it with the "3 ppl" button in the group bar; with multiple groups the table adds up all groups.

Without guest numbers everything keeps working: Split equally at checkout starts at 2, all-you-can-eat asks for the number of adults and children itself, and reservations and the waiting list keep their own number of guests (the table then opens without guests).

HACCP records

Every hospitality business must monitor and record food safety: in the Netherlands under the Hygiënecode voor de Horeca (Hygiene Code for the Hospitality Sector, inspected by the NVWA), in Belgium under the FAVV self-checking system (guide G-023). Switch on HACCP records under Settings → Laws and rules (off by default).

Tap system and flow meters

Every pour reported by a tap computer or flow meter goes on the bill, so nothing "leaks away". Turn it on under Settings → Tap system (off by default).

Controlled pouring and Kegboard

With controlled pouring, a tap only opens after the glass has been rung up on the till, and then only for that amount. That way nothing is poured that is not on the bill. It only works when the tap system is on, and you turn it on per tap (off by default).

Control music from the POS

Staff control the music from the POS touchscreen, so no separate screen is needed at the bar. Turn it on under Settings → Business → Screens and operation → Control music from the POS (off by default). The Music button then appears in the top bar: per source (e.g. Bar and Terrace) Play, Pause, Next, Previous, Louder, Quieter and a volume slider, along with what's playing now. Back to the POS closes the panel. Turning it off: the sources are kept.

The manager adds the sources with + Music source, chooses how each one is connected and checks it with Test:

The POS talks to the players from the server, so they must be on the same network as the POS (Soundtrack via the internet). Anyone who is logged in may control the music; setting it up requires the permission Set up business, payments and printers. The token and the password are never shown again and never appear in the log; the log only records the setup (on/off, sources), not every button press. The configuration export only includes on/off (the sources belong to a single business).

Second screen on a tablet or phone

The music and the cameras can also be shown on a staff member's own tablet or phone, as a second screen next to the POS. The Music or Cameras window has the On a tablet or phone button: it shows a QR code with the address, e.g. http://192.168.1.20:3000/muziek or .../camera.

  1. Connect the tablet or phone to the venue's Wi-Fi network.
  2. Scan the QR code with the camera (or type the address into the browser).
  3. Sign in with your own PIN. You only see what you're allowed to: the music for everyone, the cameras only with the View camera feeds permission.
  4. Done: Log out at the top right. If the sign-in has expired (e.g. the tablet was idle overnight), the screen asks for the PIN again.

Tip: add the page to the tablet's home screen (in the browser: Add to Home Screen) and it opens like an app.

That's why the POS looks up the IP address of the POS PC on the network (if the PC has more than one, e.g. Wi-Fi and cable, you choose the network). On the management portal (remote POS) it is the portal's address. The POS generates the QR code itself, without internet.

Pairing tablets: one button to the tablet (optional)

Even easier: pair a tablet once, and the POS sends the music or the cameras to that tablet with one button. Turn it on under Settings → Business → Screens and operation → Tablets as second screen (off by default).

  1. On the tablet: open http://<kassaserver>:3000/tablet (the setting shows On a tablet or phone with the QR code), log in with a PIN and give the tablet a name, e.g. Bar tablet. Pair.
  2. On the POS: the Music or Cameras window now has the button To Bar tablet (with a green dot when the tablet is on). Tap it: the tablet opens that screen by itself. For music, the chosen source goes along (e.g. Terrace).
  3. On the tablet: Close goes back to waiting; Unpair this tablet removes the pairing.

Keep the page open on the tablet; if the tablet is off or asleep, it opens the screen as soon as it is on again. The tablet stays logged in as the staff member who logged in on it: sending and viewing the cameras is only possible with the View camera feeds permission. In the setting, the administrator sees which tablets are paired and whether they are on, and can rename or remove them. The tablet keeps its own key; the POS only stores a hash of it. Turning it off: paired tablets are kept. The log shows who paired, renamed or removed a tablet.

Pick-up screen for takeaway

A screen for guests with Preparing on the left and Ready on the right, with large numbers, as in a chip shop or fast-food restaurant. Turn it on under Settings → Business → Screens and operation → Pick-up screen for takeaway (off by default).

No pairing needed: on a TV with a browser (smart TV, stick or mini PC), a tablet or a second monitor, open the till address followed by /oproep, e.g. http://192.168.1.20:3000/oproep. The setting and the Call window have the buttons On a separate screen and On a tablet or phone (QR code with the address). No sign-in needed: the screen only shows numbers. Tap the screen once so the browser is allowed to play sound.

What appears on it:

The number: for the webshop, Thuisbezorgd and the delivery platforms, the order number the guest or courier already has; otherwise the pick-up number (1 to 999). It is printed large on the receipt, with an explanation that the number will appear on the screen when the order is ready (in the receipt language).

Optional (off by default, in the setting):

The till has the Call button (showing how many orders are still being prepared):

  1. Ready marks a number as ready by hand (without a kitchen display, or when it is quicker). For a webshop or Thuisbezorgd order the status is updated too, so the guest is notified as well.
  2. Back puts it back under Preparing.
  3. Picked up removes it from the screen (with Undo).

In the setting you also choose whether the first name is shown next to the number (off by default, for privacy) and whether the screen plays sound. Turning it off: no Call button and no pick-up number on the receipt; the settings are kept. The log shows who manually set what to ready, back or picked up.

Clocking in and out

Clocking is off by default: then it is not visible anywhere in the till (no button in the top bar, not on the login screen, no Working hours tab). Turn it on via Settings → Business, under Staff clock in/out:

Staff who don't use the till (e.g. the kitchen) clock on the login screen: tap Clock in / out and enter your PIN. This toggles between in and out, without logging in.

When clocking is on, the administrator sees in Settings → Working hours:

In Belgium every clock-in and clock-out is also reported to the black box. If it cannot be reached, clocking does not go through (just like checkout). Whether this fully meets the Belgian staff registration requirements still has to be confirmed.

Weighing and labels (scale)

When the scale is on (Settings → Scale), products can have a price per kilo. All other products stay per piece.

Uber Eats, Deliveroo and HubRise

Besides Thuisbezorgd.nl / Takeaway.com, orders from Uber Eats (Netherlands and Belgium), Deliveroo (Belgium only; Deliveroo left the Netherlands at the end of 2022) and everything on HubRise (incl. Uber Eats, Deliveroo, Just Eat/Takeaway.com and smaller ordering apps) also come into the till. Each platform can be switched on separately under Settings → Delivery platforms (off by default; switching off keeps everything). The tab shows per platform in which countries it operates and warns if it does not operate in the business's country.

Orders. An order becomes a regular order (bezorgen or afhalen, group name <platform> <nummer>) with the platform's prices: products are recognised by their ID (from the menu), code or PLU number; unknown = a separate line with the platform's price (and an alert); delivery fees, surcharges and discounts as separate lines; if the total still does not match, a "Difference" line. The kitchen ticket goes straight to kitchen/bar. Platforms button in the top bar (with the number of open orders; orange when something needs accepting): accept or reject (with reason), being prepared, ready, out for delivery, delivered or picked up, cancel, and Complete (paid online). Whatever the platform supports is sent back (Uber Eats: accept, reject, cancel; Deliveroo: accept, reject, being prepared, ready, picked up; HubRise: all statuses). If the business delivers itself (own delivery), the order also appears under Runs, and departure and delivered are passed to the platform automatically. A cancellation by the platform makes the order lapse. If the till has not been connected to the portal for more than 2 minutes, the portal rejects a new Uber Eats order and tells Deliveroo (with tablet) that it failed, so the business sees it on the tablet.

Code: apps/pos-server/src/lib/bezorgplatforms.ts, routes/bezorgplatforms.ts; screens Bezorgplatforms.tsx. Portal side: horecapos-portaal/src/platforms.mjs. Log: Delivery platforms (on/off, settings, orders). Everything is included in the till's backups.

Smaller platforms in the Netherlands and Belgium (Homie, Hebtrek, sneleten.nl, Bistroo ...) have no public POS integration; if they are on HubRise, they work via HubRise. Otherwise: see the backlog.

Cash recycler (closed cash system)

Off by default: cash works as usual. With a closed cash system, staff do not handle the cash: the customer or staff member puts the money into the machine, which counts it, checks for counterfeit money and gives change.

The © button

OptimumPOS details

At the bottom right of every screen (PIN, floor plan, ordering and kitchen) there is a small © button. It opens the OptimumPOS details: logo, address, phone, email and website. The icon is stored locally in the app, so it also works without internet. The same icon is the app icon (browser tab and home screen).

Part 2 · Manager

Getting started

By default a manager can do everything a waiter can, and in addition give discounts, process returns, close the day, manage the cash drawer and view the log and stock, among other things. Most of this is under the Report button:

Stock

Off by default. Turn it on via Settings → Business → Track stock. Off = not visible anywhere in the till.

Order from suppliers

Off by default. Turn on under Settings → Stock → Order from suppliers (only with Track stock on). Off = the order list works as usual.

Review management

Read and reply to reviews from Google and Trustpilot in the POS. Turn it on under Settings → Loyalty and reviews → Review management (off by default, then none of it is visible anywhere). Read and reply under Report → Reviews (permission Read and reply to reviews, by default also for the manager). If you turn it off, the integrations and the reviews are kept.

Text and email marketing

Messages to loyalty card customers who gave their consent. Without the loyalty card, neither can be turned on.

Tips per staff member

Under Settings → Business → Tip (only if "Show tip buttons at checkout" is on) you choose how tips per staff member appear on the interim total (X), the Z report (receipt and email) and Revenue per period (also in the CSV):

ChoiceDistribution
Off (default)only the tip total, as always
Own tips eachtips from the bills each person checked out themselves
Pool by hoursall tips together, by clocked-in hours in that period (requires clock in/out; nobody clocked = equal)
Equal poolall tips together, split equally among those clocked in (without clocking: whoever entered or checked out something)

Leftover cents go to whoever is closest to the next cent, so the total always adds up. It is an overview: the till pays nothing out (you can do that with "Money out of the drawer"). Old Z reports stay as they were.

Z report by email

Under Settings → Business → Email Z report to, enter the administrator's email address once (more addresses: separate with a comma, max. 3). After Close day the Z report is then sent automatically to that address, alongside the printed receipt. Empty = no email, as always.

Summary of the day (optional)

If there is an address under Email Z report to, the checkbox With a short summary of the day at the top of the email appears below it (off by default). On = a few lines in plain language at the top of the Z report email, using only the till's own data (no AI, nothing leaves the till):

The Z report itself (receipt and email) stays exactly the same. Preview for today shows the summary from the last end-of-day closing until now. The summary is in Dutch, just like the Z report email.

Dashboard

Dashboard tab in Report (Revenue per period permission), read-only:

Gift cards sold do not count as revenue, and discounts and menu headers are not in the top 10 (as in the other reports). A day runs from 00:00 to 24:00.

Extra reports

Three extra tabs in Report, each switched on separately via Settings → Business → Management and reports → Extra reports (off by default: then no tab). They require the same permission as Revenue per period and are read-only. Period: this week, last week, this month, last month, the last 90 days, this year or custom (at most just over a year).

Discounts

A manager or administrator sees the % Discount button next to the total in the order screen:

The discount appears as a separate line on the receipt ("Discount 10%", with the reason below it) at the same VAT rate, so the total and VAT breakdown are correct. On the whole receipt the discount is split per VAT rate. To remove it: tap the amount of the discount line. If a line with its own discount is voided, that discount is dropped with it. If you remove a product from a receipt with a percentage discount on the whole receipt, the POS recalculates that discount over what remains (in Belgium UC226); a fixed amount stays and is spread over the lines again at checkout. If nothing is left to pay because of a 100% discount, close with "Close (nothing to pay)". Discounts are shown in the log, and in the X/Z report and the period overview as "of which discount". When a receipt with a discount is returned, the discount is applied proportionally.

Discount codes (optional)

Codes with a discount on the whole receipt, for example for a promotion (ZOMER10). Turn on under Settings → Business → Discount codes (off by default); create the codes under Settings → Discount codes (permission Manage products):

The order screen has the Discount code button (anyone may enter a code; the code is created in advance by the business). The discount appears as the line "Discount code CODE" on the receipt, split across the VAT rates; one code per receipt, and not once (part of) the bill has been paid. If you remove the line again or the order is cancelled, the usage no longer counts. Removing a used code turns it off (the reports stay correct). Everything is in the log (Discount code). Code: lib/kortingscodes.ts, routes/kortingscodes.ts, Kortingscodebeheer.tsx, KortingscodeDialoog.tsx.

They do not appear in the list under Settings → Discount codes (the number per promotion does, under Report → Marketing) and are passed on to the webshop as long as they are valid and unused.

Reports and end-of-day closing

Report - interim total (X)

Report button in the top bar:

Export to your accounting

Report → Revenue per period → Accounting export (journal) (permission Revenue per period) creates a CSV with one journal entry per day, ready to import into e-Boekhouden, Exact, SnelStart, Twinfield etc. (via their CSV/general journal import), or one of the formats below (UBL, XAF and ready-made for 14 packages).

One document per day (KASSA-JJJJMMDD) that always balances (debit = credit):

SideWhat
Debitreceipts per payment method (cash, card, gift card, online, other), incl. tips
Creditrevenue per VAT rate (excl. VAT) and VAT payable per rate
Credittips (payable to staff, not revenue)
+/-rounding difference (cash rounding to 5 cents)
+/-money in/out of the drawer (cash management) against suspense accounts, and cash difference from the Z report

Returns and discounts are already in the receipts and reduce revenue. Columns: Datum; Boekstuk; Dagboek; Rekening; Omschrijving; Debet; Credit; Btw-code; Btw-% (semicolons, comma decimals). After downloading, the till reports whether there are days that do not balance or have a larger difference than rounding.

Next to the button you choose the format (the choice is remembered in the browser). The same journal, but formatted so that the package can import it directly. The list only shows the formats for the business's country (Settings → Business), first the standards (CSV, UBL, XAF), then the packages in alphabetical order:

FormatFileImporting into the package
General (CSV)journaal_…csvany package with a CSV/journal import (map the columns)
UBL 2.1 / Peppol (XML), NL and BEjournaal_…_ubl.xml (multiple days: .zip)one "daily receipts" invoice per day to Kassaverkopen (already paid) according to Peppol BIS Billing 3.0, with one line per VAT rate and the revenue account in AccountingCost; only revenue and VAT (payment methods, tips, rounding, drawer and cash difference do not belong in an invoice). For uploading into Adsolut, Billit, BUNNI, DigiBoox, Expert/M, Moneybird, Popsy, Rompslomp, Storecove and TriFact365, among others; not for sending via the Peppol network. Name, VAT number and address come from Settings → Business
XML Auditfile Financieel (XAF 4.0), NLjournaal_…_xaf.xafaudit file of the Dutch Tax Administration (Belastingdienst) (XSD XmlAuditfileFinancieel4.0): one file for the period, ledger, VAT codes, periods and one general journal transaction per day; can be imported into Caseware, Exact Reeleezee and Visma Cash, among others
AccountView (XML), NLjournaal_…_accountview.xmlXML entries (VFPData, one transact per entry line with dj_code, period, inv_date, inv_nr, acct_nr, trn_desc and amount: debit positive, credit negative), one document per day in the general journal; import with an import definition (Document → Importeren → Importdefinitie aanmaken, type XML); the field names are AccountView's own, so map them 1-to-1 once. Have the first import checked
AFAS Profit (XML)journaal_…_afas.xmlXML for the UpdateConnector FiEntries (financial entries), one entry per day with year, period, company and journal; import into Profit via Import → XML; enter the company number (default 1)
Asperion (CSV), NLjournaal_…_asperion.csvFMUTA layout (Extra → Import financiële mutaties), one header line per day plus the entry lines; Asperion sets up the import definition via its helpdesk
Daily statement (HTML), NL and BEjournaal_…_dagstaat.htmlreadable daily statement per day (revenue per VAT rate, payment methods, tips, cash difference) and totals; print as PDF or email, for packages without import (Accountable, Dext, Dexxter, Jortt, Kleisteen, MoneyMonk)
e-Boekhouden.nl (CSV)journaal_…_eboekhouden.csvDate; Document number; Description; General ledger account; Amount (debit positive, credit negative); VAT code GEEN (the VAT is already on the VAT accounts); Import → Entries, type general journal
Exact Online (XML)journaal_…_exact.xmleExact-XML (topic GLTransactions): one general journal entry per day (type 90) in the journal; Import/export → Import XML
InformerOnline (TXT), NLjournaal_…_informer.txttab-separated general journal (Geavanceerd → Memoriaal → uploaden); the journal must be a number 1–99 (otherwise 90)
KING ERP (XML), NLjournaal_…_king.xmlKING_JOURNAAL: one posting batch (not final) with one journal entry per day
KOMAS (CSV), NLjournaal_…_komas.csvKOMAS free format (0401 Importeren journaalposten): Datum; Grootboek; Omschrijving; Bedrag
Odoo (CSV), NL and BEjournaal_…_odoo.csvAccounting → Journal Entries → Import records; journal and account by name or code
Sage BOB 50 (Excel), BEjournaal_…_bob.xlsxImportation de données externes → Opérations diverses (map the columns once)
SAP Business One (ZIP), NL and BEjournaal_…_sapb1.zipData Transfer Workbench, Journal Entries: JournalEntries.csv and JournalEntries_Lines.csv
SnelStart (CSV)journaal_…_snelstart.csvDate; Document number; Description; General ledger account; Debit; Credit (dd-mm-yyyy, decimal comma, without BOM); import as general journal, you choose the journal when importing
Twinfield (XML)journaal_…_twinfield.xmljournal transactions as draft (destiny="temporary"), the accountant makes them final; enter the company code (empty = the company you import into)
Winbooks (CSV), BEjournaal_…_winbooks.csvK_DOC.CSV, one document per day in the journal (Winbooks numbers it itself)
Yuki (XML)journaal_…_yuki.xmlJournal-XML (GeneralJournal), one general journal entry per day, same structure as the live link; company ID optional

Overview: which accounting package works which way

By segment, in alphabetical order. NL/BE = the country in which the package works: under Settings → Accounting → Accounting package you only see the packages for the business's country (Dutch packages do not work in Belgium and vice versa). Live = the till posts every day by itself (choose under Settings → Accounting → Accounting package); on request = there is an API, but it first requires partner registration or approval from the supplier (let us know). File = the format under Accounting export. Where both are possible, you can use both. The list is in packages/shared/src/boekhoudcatalogus.ts and also appears under Settings → Accounting.

PackageNLBELiveFileNote
Small businesses and freelancers
Accountable–✓–Daily statement (HTML, for PDF or email)
AccountView (Visma)✓–on requestAccountView (XML), General (CSV)File: XML entries for an import definition (Document → Importeren); the generic CSV also works with an import definition. Live via the AccountView.Net API after applying to AccountView.
Acumulus✓–✓–Live as a paid sales invoice per day, with one line per VAT rate.
AFAS Profit✓–✓AFAS Profit (XML)
Asperion✓–on requestAsperion (CSV)Live after registering as an API partner with Asperion.
Billit–✓on requestUBL 2.1 / Peppol (XML)Upload UBL via Fast input; live after approval by Billit.
BUNNI✓––UBL 2.1 / Peppol (XML)No public API documentation yet.
Dexxter–✓–Daily statement (HTML, for PDF or email)
DigiBoox (Visma DigiBTW)✓––UBL 2.1 / Peppol (XML)
e-Boekhouden.nl✓––e-Boekhouden.nl (CSV)Also for former Ficsus customers.
Exact Online✓✓✓Exact Online (XML)
Exact Reeleezee✓––XML Auditfile Financieel (XAF 4.0)
Horus–✓✓–
InformerOnline✓––InformerOnline (TXT)
Jortt✓––Daily statement (HTML, for PDF or email)No import: post the daily revenue as income with the daily statement as an attachment.
KING✓–on requestKING ERP (XML)Live after partner registration with KING Software.
Kleisteen✓––Daily statement (HTML, for PDF or email)
KOMAS (Adfinis)✓––KOMAS (CSV)
Minox✓–on request–Live after a partner link via Minox.
Moneybird✓–✓UBL 2.1 / Peppol (XML)
MoneyMonk✓––Daily statement (HTML, for PDF or email)MoneyMonk is getting an API for integrations in 2026.
Octopus–✓on request–Live after requesting a software house ID from Octopus.
Popsy / Allegro–✓–UBL 2.1 / Peppol (XML)
Rompslomp✓––UBL 2.1 / Peppol (XML)
Sage BOB 50–✓–Sage BOB 50 (Excel)
Silvasoft✓✓✓–Live as a sales entry per day, with one line per VAT rate; payment methods, tips and cash difference are not included.
SnelStart✓–✓SnelStart (CSV)
Twinfield✓–✓Twinfield (XML)
Visma Cash✓–on requestXML Auditfile Financieel (XAF 4.0)API with a key from CASHWeb; the record layout for entries is still being confirmed.
Visma eAccounting✓–on request–Live after approval by Visma (partner registration).
Winbooks–✓on requestWinbooks (CSV)
Wolters Kluwer Adsolut–✓on requestUBL 2.1 / Peppol (XML)UBL with the revenue account per line; in Adsolut turn on "grootboekrekening verwerken bij verkopen".
Wolters Kluwer Expert/M–✓–UBL 2.1 / Peppol (XML)
Yuki✓✓✓Yuki (XML)
International
QuickBooks Online✓✓✓generic CSVNo Dutch or Belgian edition: check the VAT settings.
Xero✓✓✓generic CSV
Zoho Books✓✓✓generic CSV
Enterprise and chains
Exact Globe+✓✓–Exact Online (XML)Same XML as Exact Online; have the first import checked.
Microsoft Dynamics 365 Business Central✓✓✓–
Odoo✓✓✓Odoo (CSV)
Oracle NetSuite✓✓on requestgeneric CSV
SAP Business One✓✓✓SAP Business One (ZIP)
Unit4 ERPx✓✓–generic CSV
Platforms and aggregators
Apicbase✓✓on request–Sales per receipt for stock and food cost: integration under Settings → Recipes (not as an accounting package).
Caseware✓✓–XML Auditfile Financieel (XAF 4.0)
Combidesk✓–on request–Combidesk builds and manages the link itself (to Exact, Moneybird, SnelStart and Twinfield, among others); on request as a partner.
Dext✓✓–Daily statement (HTML, for PDF or email)Email the daily statement (PDF) to your Dext address.
Jamix✓✓on request–Sales for stock and food cost via the JAPI interface of Jamix; custom work on request from Jamix.
Omniboost✓✓on request–Passes data on through the Omniboost partner programme to many accounting and hotel systems.
Storecove (Peppol)✓✓on requestUBL 2.1 / Peppol (XML)
TriFact365✓––UBL 2.1 / Peppol (XML), Daily statement (HTML, for PDF or email)
Any other package✓✓–generic CSV, UBL or XAF (NL)

Have the accountant check the first import. The layout is in packages/shared/src/journaalexport.ts (with tests).

Settings → Accounting (Set up business, payments and printers permission): journal code (default MEM) and the general ledger account per item. Empty = example account (NL: 8000/8010/8020 revenue, 1500/1510 VAT, 1000 cash, 1100 card; BE: 7000xx revenue, 451000 VAT, 570000 cash). Have the accountant fill in the real accounts.

Link with an accounting package

Live links with Acumulus, AFAS Profit, Microsoft Dynamics 365 Business Central, Exact Online, Horus, Moneybird, Odoo, QuickBooks Online, SAP Business One, Silvasoft, SnelStart, Twinfield, Xero, Yuki and Zoho Books. After each day the till posts the same journal as the export above (revenue and VAT per rate, payment methods, tips, rounding, drawer and cash difference) as a general journal entry in the chosen package, with the journal and ledger accounts from Settings → Accounting. At most one package is ever on.

PackageCountryConnect withWhat the till posts
AcumulusNLcontract code, user and password of an API userone paid sales invoice per day with one line per VAT rate; Acumulus emails errors to ACUMULUS_FOUTMAIL
AFAS ProfitNLenvironment, token, administrationgeneral journal (FiEntries)
Business CentralNL, BEtenant, environment, company, client ID and secret of a Microsoft Entra app (API.ReadWrite.All)lines in the general journal with the Journal code
Exact OnlineNL, BElog in (OAuth, own app: see Exact Online below; Belgium: start.exactonline.be)general journal entry in the journal (e.g. 90)
HorusBElog in (OAuth, app below), optional filemiscellaneous operation
MoneybirdNLAPI token, optional administrationgeneral journal (general journal document)
OdooNL, BEaddress, database, user, API keyjournal entry in the journal with the short code (e.g. MISC)
QuickBooks OnlineNL, BElog in (OAuth, app below; QUICKBOOKS_OMGEVING)journal entry; accounts by number
SAP Business OneNL, BEService Layer address, database, user, passwordjournal entry (JournalEntries)
SilvasoftNL, BEuser and API keysales entry to the relation Kassaverkopen, one line per VAT rate (payment methods, tips and cash difference are not included)
SnelStartNLconnection key and subscription keygeneral journal
TwinfieldNLlog in (OAuth, app below), optional officejournal transaction
XeroNL, BElog in (OAuth, app below), optional organisationmanual journal; accounts by code
YukiNL, BEAPI key, optional administrationgeneral journal (GeneralJournal)
Zoho BooksNL, BElog in (OAuth, app below; European data centre by default), optional organisationjournal entry; accounts by code

Cash register audit file (XAA)

For Dutch businesses, Report → Revenue per period has the button Cash register audit file (XAA) next to the accounting export: the XML Auditfile Afrekensystemen 3.2 of the Dutch Tax Administration (Belastingdienst) and the XML Platform (SRA) over the selected period (at most just over a year; permission Revenue per period). This is the file the Belastingdienst recommends for supplying a till's data during a tax audit or to the accountant; the rules are set out in the Handreiking voor een betrouwbaar afrekensysteem (Guide to a reliable checkout system, docs/xaa).

In the file (auditfile_kassa_<van>_tm_<tot>.xml, schema docs/xaa/XmlAuditfileAfrekensystemen3.2.xsd):

Amounts are positive with C (sale, money received) or D (return, payout); times are in Dutch time with offset. All keys are the database ids without hyphens, so they can be traced back in the till.

Signing (chapter 6 of the specification): if Optimum POS has set up a certificate, the audit file comes signed in an envelope (XML Signature) and the file is named …_ondertekend.xml; otherwise it is a plain audit file, and the till reports this when downloading.

Payment on account

Business customers (a company that has lunch collected every week, a hotel, a club) buy on account and pay later, with an invoice. Switch it on under Settings → Invoices → Payment on account (only with Invoices on; off by default).

Bank: match transfers to invoices

Under Report → On account → Bank the till looks up the invoice on account for each incoming payment:

Camera feeds in the POS

All of the business's camera feeds on one page, without a separate screen or app. Turn it on under Settings → Business → Screens and operation → Camera feeds in the POS (off by default). The Cameras button then appears in the top bar for anyone with the View camera feeds permission (manager and administrator by default; can also be turned on for waiters under Settings → Permissions). All cameras are shown side by side; tap a camera for a large view. Turning it off: the camera systems are kept.

Also as a separate screen: On a separate screen opens http://<kassaserver>:3000/camera (e.g. a monitor behind the bar), and On a tablet or phone shows a QR code: a staff member scans it with their own tablet or phone and signs in with their own PIN (there too only with the View camera feeds permission). On a narrow screen the cameras are stacked. See Second screen on a tablet or phone.

The manager adds the camera systems with + Camera system, checks them with Test and chooses for each camera its name and whether it's on the page:

Without ffmpeg: the photo.

Privacy: the POS fetches the images from the camera system and only passes them on; nothing is stored (no recordings, no cache). Users and passwords stay on the server and never appear on screen or in the log. The log shows who viewed the cameras. The page requests the images themselves with a key (valid for 12 hours, as long as the staff member is signed in), because an image in the browser can't send a token. The configuration export only includes on/off.

Log of sensitive actions

Report → Log (manager or administrator) shows who did what and when.

What is recorded: voids, discounts (and their removal), returns, receipt copies, pro formas, manual card payments, opening the drawer, cash in/out of the drawer, opening float, end-of-day closing, moving lines or tables, closing empty orders, changing product price/name/VAT, new or deleted products, changing staff and settings, adjusting working hours, logging in and out, wrong PINs and clocking in and out. With payment on account also: customers, sales and payments on account, importing bank statements, the bank connection and fetching from the bank. With the alert for long lead time: late orders and apologies sent. With Mailchimp or Klaviyo: connecting, choosing a list, disconnecting and unsubscribes from there. With music control: on/off and adding, editing and removing music sources. With camera feeds: who viewed the cameras (at most once per half hour per staff member), on/off and the camera systems. With alerts: every alert, how it was handled and switching it on and off.

Alerts: fraud and anomalies

Settings → Alerts. Two parts, each switched on separately and off by default; switching off keeps all alerts and settings. Anyone with the Configure alerts permission (by default the manager and the administrator) can set it up; anyone allowed to view the log can see and handle the alerts. The till checks every 5 minutes (and with Check now); not on the shadow till.

Fraud and theft detection (per staff member, per business day from 05:00), each rule switched on or off separately with its own threshold:

Anomaly alerts, compared with the same weekday and time in recent weeks (default 4; days without revenue don't count, at least two comparison days):

Each alert is raised once (per rule, staff member and day; kitchen time at most once per hour) and goes to:

Each channel has a Test message button. Tokens and keys stay on the till (the screens only see whether they are filled in). An alert is not proof: check the bill and the log and discuss it with the staff member.

Receipts: copy and return (credit note)

Receipts

Receipts button in the top bar:

Cash drawer with sensor and drawer per staff member

Off by default. Set up under Settings → Payments → Cash drawer.

Part 3 · Administrator

Getting started

Installing. You install HorecaPOS with the installer for your system, available on the OptimumPOS download page: Android (app), Windows (installer), macOS (installer for Macs with Apple Silicon and Intel), Linux (graphical installer, or the .deb or .rpm package), Raspberry Pi (graphical installer or .deb for a Raspberry Pi 3, 4 or 5 with 64-bit Raspberry Pi OS) and Chromebook (the Android app from Google Play). Choose for all users for a POS server that tablets and the kitchen display connect to, or just for me for only a till on that device. The installer sets up everything that is needed, including the database, and makes a backup every night. To update, install the new version: your data stays in place. The installer starts in the language of your computer (otherwise English); on Windows and Linux you can choose another language on the first screen. The POS then starts straight away in that language. The .deb and .rpm packages and the Android app follow the system language, otherwise Dutch.

The administrator sets up the till via Settings. There you find tabs such as Business, Staff, Permissions, Working hours, Products, Happy hour, Stock, Floor plans, Payments, Printers, Accounting, Backups, Import/export and Database. Which tabs a manager also sees depends on the permissions.

Database. Under Settings → Database (administrator only) you choose between MySQL / MariaDB, the built-in database and PostgreSQL; when you switch, all data comes along (see Database). If Optimum POS already set a fixed address during installation, that address applies and there are no input fields. Otherwise you fill in the Server, Port, Database, User and Password yourself. The till stores them itself, shows them filled in again afterwards, and you can always change them with Change MySQL/MariaDB details or Change PostgreSQL details. Leaving the password empty means: keep the stored password (for the same user). The installer and an update do not change DATABASE_URL or the chosen database.

Settings: products

Accounting

Everything for accounting is under Settings → Accounting. Fill in the journal and the ledger accounts together with your accountant. If you want the till to post the daily revenue by itself every day, choose your package at the top under Accounting package, Exact Online included: you only see the packages that work in your business's country. Right below it you fill in that package's details and connect. For packages you log in to (such as Exact Online, Twinfield or Xero), first fill in the app: client ID and client secret. If Optimum POS fixed the package or a setting during installation, you will not see that choice or that field. There you will also find an overview of all packages: which can be linked live and which get a file. You create a file under Report → Revenue per period → Accounting export: choose your package's format, or UBL (Peppol), XAF or a daily statement. Always have your accountant check the first entry or import.

For a Dutch business there is also Cash register audit file (XAA): the XML Auditfile Afrekensystemen of the Dutch Tax Administration (Belastingdienst) with all receipts, lines, payments and events of the till over the selected period. You give it to your accountant or, during a tax audit, to the Belastingdienst.

Payroll and scheduling

If your staff clock in and out, Settings → Working hours shows Payroll and scheduling at the bottom, in two blocks. Under Payroll administration you choose your payroll package or (in Belgium) your social secretariat, and enter for each staff member their personnel number in that package. Then you create the file with the hours worked and the revenue per staff member for a period, and import it into your payroll package. Under Staff scheduling you choose your scheduling system: with Deputy, Dyflexis and Shiftbase the revenue goes automatically every hour, with the others you create a revenue file. This way you see the wage costs next to the revenue in your scheduling. If you work without clock in/out, you can still send the revenue to your scheduling: it is then at the bottom of Settings → Accounting, under Revenue to your scheduling. If Optimum POS fixed something during installation, you will not see that choice or that field.

Backups

The till makes a backup automatically every night, and always before an update. Under Settings → Backups you see all backups (when, by whom or automatic, size) and you can make one yourself with Create backup. If the last backup is more than two days old, a red warning appears: contact Optimum POS in that case.

Settings: backups

Restoring is done with the Restore button next to a backup. Everything that happened after that backup is then lost. You have to tick a box and enter your own PIN again. The till first makes a safety backup of the current state and then logs everyone out. In Belgium this cannot be done from the till (the black box counters keep running); there Optimum POS does it.

Database

Under Settings → Database (administrator only) you see where the till keeps its data. At the top is the current database with program, version, tables, rows and address or folder. For staff and tablets the till works the same with every database. On Windows, macOS, Linux and Raspberry Pi you choose from three databases:

When MySQL or MariaDB? If your business already has a MySQL or MariaDB server, if your IT administrator works with it, or if you want to read the data in your own reporting, Excel or BI software. In doubt? Choose built-in: it works straight away.

What do you need for MySQL or MariaDB?

CREATE DATABASE horecapos CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'horecapos'@'localhost' IDENTIFIED BY 'wachtwoord';
GRANT ALL PRIVILEGES ON horecapos.* TO 'horecapos'@'localhost';

If MySQL or MariaDB runs on another computer, put the IP address of the till server instead of localhost in the last two lines.

Migrating to MySQL / MariaDB:

  1. Under MySQL/MariaDB address, fill in the fields: Server (default localhost), Port (default 3306), Database (default horecapos), User and Password; the same for MariaDB. If the address is already set, the fields are already filled in; if you leave the password empty, the stored password is kept (for the same user). The till saves the address itself; if Optimum POS has already set a fixed address, that address applies and there are no fields. If the till already runs on MySQL/MariaDB, you change the details later with Change MySQL/MariaDB details. Optimum POS sets up an encrypted connection for you.
  2. Tap Test connection: you see the program and version, or why it fails.
  3. Tap Migrate to MySQL/MariaDB, tick that you understand and enter your own PIN.

Migrating works in every direction between the three databases, and all data comes along:

  1. The till briefly accepts no requests (usually less than a minute); tablets then carry on by themselves.
  2. First the till makes a backup of the current state (under Settings → Backups).
  3. Everything goes to the new database and the till counts per table whether everything is there exactly.
  4. Only when everything matches does the till continue on the new database. Signed-in staff stay signed in.

If anything fails, nothing changes and the till keeps working on the old database. The old database stays in place, so you can always go back. Till data that was already in the new MySQL/MariaDB or PostgreSQL database is replaced. This also works in Belgium: the black box counters are carried over exactly.

Backups and restoring work the same with all three databases (Settings → Backups). A backup from one database can be restored in any other, including a PostgreSQL backup in MySQL or MariaDB.

What is in MySQL or MariaDB? Every table of the till, with the same name and columns (times in UTC). Each table gets the extra key column _hp_sleutel, and in the helper tables _horecapos_stand, _horecapos_kolom, _horecapos_reeks and _horecapos_wijziging (log of changes, kept for 14 days) the till keeps track of the state, the column types, the counters and the changes. Other programs read the data; only the tills write.

How it works: the till calculates in a fast working copy on the till server and writes every change to MySQL/MariaDB in the same step. If that fails, the change does not go through and the till shows an error, so keep MySQL/MariaDB reachable. On startup the till reads everything from MySQL/MariaDB.

Several tills on one database. As with PostgreSQL, several tills can use the same MySQL/MariaDB database, for example each location of a chain with its own till server. Changes are made one after another and each till first takes over what the others did, so nothing is lost when changes happen at the same time. If a till restores a backup or a till with a newer version updates the database, the other tills automatically read everything in again; so update all tills at the same time. A till that was off for more than 14 days reads everything in again on startup.

During installation you also choose the database: MySQL / MariaDB, built-in (recommended) or PostgreSQL with its address. If it cannot be reached, the till installs itself with the built-in database; you can migrate here afterwards. An update keeps the choice.

Linking tablets and displays

Customer display

A screen on the till that faces the customer. The customer sees roughly what has been ordered and, very clearly, the amount and how it is being paid. It has no controls: the screen simply follows what the till does. Off by default; turn it on via Settings → Business → Customer display. On a till PC with two screens the till turns it on automatically the first time; if you turn it off afterwards, it stays off. Without a customer display (off, or none connected) everything works exactly as always: the till sends the image in the background and staff never notice an error or a missing screen.

What the customer sees:

Connecting, in two ways (both set up on the device itself):

The customer display does not ask for a PIN (there is nothing to operate) and only shows the image of the till it is paired with. The image is only kept in the till server's memory; after a restart the screen is empty until the next change. The setting (on/off and welcome text) is included in the backup and in Import/export (Other settings).

Digital receipt via QR (optional)

Off by default. Turn it on via Settings → Business → Kitchen and customer display → Digital receipt (the option appears when the customer display is saved as on). After checkout a QR code appears with Thank you; it then stays for 45 seconds instead of a few seconds. The guest scans it with their own phone and sees the receipt exactly like the paper receipt (same text, on a Belgian till also with the FDM block). On the phone they can print the receipt, save it as a PDF or download it as a text file.

Customer display when idle: slideshow (optional)

Off by default. Turn it on via Settings → Business → Kitchen and customer display → Customer display when idle. When there is no bill on the customer display, the slides alternate (by default every 8 seconds, adjustable from 4 to 60):

Without slides the customer display shows the welcome screen, as always.

Happy hour

Off by default. Turn it on via Settings → Business → Use happy hour; the Settings → Happy hour tab then appears.

Dayparts and seasons

Off by default. Turn it on via Settings → Business → Dayparts and order types → Menu per daypart and season; the Settings → Dayparts tab then appears. If you turn it off, all products can always be sold again and the dayparts are kept.

Menu and prices per order type

Off by default. Turn it on via Settings → Business → Dayparts and order types → Menu and prices per order type. If you turn it off, the normal price applies everywhere again and everything can be sold everywhere; the prices entered are kept.

Off by default. Turn it on via Settings → Business → Use menus.

Recipes and cost price (Apicbase)

Integration with Apicbase (recipes, cost price, stock and purchasing) via the Apicbase Generic POS API (off by default, each part can be switched on or off separately). Set up under Settings → Recipes (permission Set up business, payments and printers). The POS talks to Apicbase itself (outgoing traffic only, no portal needed).

  1. Connect (all to be filled in by the administrator), in one of three ways:
    • Paste token: in Apicbase Library Settings → API Settings → New token → Service Account Token (scopes accounts, library, sales); paste the access token and refresh token;
    • Log in with the business's own API-app (client-id and client secret from API Settings): Log in to Apicbase, then paste the code Apicbase shows;
    • An expired token (after 7 days) is renewed automatically by the POS with the refresh token.
  2. Outlet: Fetch outlets and choose this business's outlet. The POS sets the POS there to Generic POS API with its own location-id (editable; default HORECAPOS-…, unique per POS).
  3. On, with checkboxes:
    • Products, groups and options to Apicbase: product groups, products (PLU = the product's PLU number, otherwise the code, otherwise the id), options as modifiers, with price and VAT. Automatically after every change (after one minute) and every day. In Apicbase you then link each POS product to a recipe;
    • Every paid receipt to Apicbase: oldest first, at most 100 at a time, within a quarter of an hour after payment (and every 5 minutes). Discount is spread over the lines; open amounts, disposables surcharge and deposit appear as separate products in Apicbase; weighed products as 1 piece with the total amount. If it fails, the POS stops (Apicbase wants the receipts in order) and tries again later: checkout is not affected. When switching on, you choose from which day (default from now);
    • Fetch cost per portion (every 6 hours): per linked recipe the food cost (ingredients and waste), with personnel cost, the selling price and the margin according to Apicbase. Calculated using the cheapest supplier, the last ordered price or the average stock value;
    • Take over selling price from Apicbase (off by default): set the selling price of linked products in the POS (recorded in the log).
  4. At the bottom: Cost price per product with cost price, cost price with personnel, price in the POS, cost price % and margin. Buttons Send catalogue now, Send receipts now and Fetch cost prices now.

Code: apps/pos-server/src/lib/apicbase.ts, routes/apicbase.ts; screen Apicbase.tsx. Log: Apicbase. Requirement: the Apicbase API module. For the Pin Voordeel app for all customers: partnership and certification with Apicbase (see the backlog). Documentation: https://developers.apicbase.com/docs/generic-pos-api-guide

Hotel software: charge to room

For a restaurant or bar at a hotel: charge the bill to a guest's room. Off by default: Settings → Hotel (permission Set up business, payments and printers).

Sirvoy only sends something when a booking changes: bookings from before connecting become known to the POS only after a change in Sirvoy. Messages may arrive out of order; a message older (generatedAt) than what the POS already has is skipped. In the hotel = not cancelled and not checked out, checked in or arriving today or earlier, and departing today or later. Test connection shows how many bookings came in.

All hotel software is available in the Netherlands and/or Belgium. Test connection checks the details. Code per integration: apps/pos-server/src/lib/pms/<naam>.ts.

Code: apps/pos-server/src/lib/hotel.ts, routes/hotel.ts, the integrations in lib/pms/, catalogue packages/shared/src/hotelcatalogus.ts; screen Hotel.tsx. Log: Hotel. Secrets (tokens) are stored only in the database, never on screen.

Wine management with Vinify

Settings → Wine management (off by default; switching it off keeps everything). Vinify keeps track of the wine cellar, the wine list and the stock, and is the main source of the wines. In line with Vinify's POS requirements, the POS offers an API that lets Vinify:

Authenticate, using all three methods Vinify supports (the administrator chooses which are on):

  1. API ID and API key (X-Api-Id and X-Api-Key, or Authorization: Bearer <id>:<sleutel>);
  2. API key and API secret with a signature: X-Api-Key, X-Timestamp and X-Signature = hex HMAC-SHA256(secret, <timestamp>\n<METHODE>\n<pad met query>\n<sha256 van de body>), at most 5 minutes old.

The POS creates the key and the secret (shown once); the screens only show whether they are filled in. Reachable via the portal at https://<portaal>/vinify/<kassa-id>/... (no port opened on the premises; the address is in Settings → Wine management). Which products are wine: whatever Vinify creates, plus the groups you tick. If Vinify provides an address to send sales to, the POS also sends them itself (push, with a token): after every paid receipt and every 5 minutes whatever has not yet gone through. Vinify enables the HorecaPOS integration (hello@vinify.no). Everything is in the log. Not to be confused with Vinify.nl, an online wine shop: it is listed under the suppliers (Order from suppliers).

Quick address entry with postcode and house number

Turn on under Settings → Business → Quick address entry (off by default; only for a business in the Netherlands). Type the postcode and house number (also with a letter or addition, e.g. 12A or 12-1) and tap Find address: street, house number, postcode and town are filled in. If there are several addresses at that number (12, 12A, 12B), choose the right one. You can still change everything yourself afterwards.

Notification of a new version

Turn it on under Settings → Business → Update notification (off by default).

Booking platforms

Bookings from TheFork, Formitable, Zenchef, Resengo (Belgium only), OpenTable (Netherlands only), PlanPanther, RestoManager and Aqqo (Netherlands only) appear automatically in the till and on the floor plan. Switch on under Settings → Booking platforms (off by default). Only possible if Reservations is switched on.

Loyalty programmes and reviews

Two separate switches under Settings → Loyalty and reviews (both off by default, then none of it is visible anywhere). If you turn them off, the settings and anything that has already happened are kept.

Loyalty programme from another platform: the guest earns points with Joyn (Belgium) and/or Piggy (Leat; the Netherlands and Belgium). This is separate from the POS's own loyalty card, which can simply stay on alongside it.

Ask for reviews: after the visit, one email with a button to Google and/or Trustpilot.

Mailchimp and Klaviyo integration

Your loyalty card customers in your own email program: under Settings → Business → Mailchimp and Klaviyo (below text and email marketing). There is no switch: without a connection with a chosen list, nothing happens.

Code: lib/mailinglijst.ts, routes/mailinglijst.ts and MailingKoppelingen.tsx.

BI and data export

Sales data to Power BI, Looker Studio, Excel, Google Sheets, Tableau, Qlik Sense, Metabase, a BI service (for example YourBI, BI4Horeca or Moore DRV) or your own data warehouse. Switch it on under Settings → BI and data export (off by default). Read-only: an integration cannot change anything in the till. No guest data.

Payroll and scheduling

With Clock in/out on (Settings → Business), Settings → Working hours shows Payroll and scheduling at the bottom (permission Manage settings), in two separate blocks. If clocking is off, there are no hours: then only the Staff scheduling block (the revenue, live or as a revenue file) is shown at the bottom of Settings → Accounting, under the heading Revenue to your scheduling:

PackageNLBELiveFileNote
Payroll software and payroll providers
ADP✓✓on requestHours list per staff member and day (CSV)Integration via ADP (on request); until then the hours list per staff member and day.
AFAS Payroll✓–on requestHours list per staff member and day (CSV)Payroll administration in AFAS Profit (same environment as the accounting in AFAS); integration on request, until then the hours list.
BCS HR✓–on requestHours list per staff member and day (CSV)Integration via BCS (on request); until then the hours list.
Buddee✓–on requestHours list per staff member and day (CSV)HR and payroll software; integration on request, until then the hours list per staff member and day.
Employes✓–on requestHours list per staff member and day (CSV)Employes has an API for hours worked (token from the customer); the integration will follow after coordination with Employes. Until then the hours list.
Exact Online Loon✓–on requestHours list per staff member and day (CSV)Payroll administration in Exact Online (same environment as the accounting in Exact); integration on request, until then the hours list.
Humanwave✓–on requestHours list per staff member and day (CSV)Integration via Humanwave (on request); until then the hours list.
Loket.nl✓–on requestLoket.nl Variabele gegevens (CSV), Hours list per staff member and day (CSV)File for Werkgever → Collectieve mutaties → Importeren → Variabele gegevens (hours per staff member over the period). Live via the Loket API after signing up with Loket.
Nmbrs✓–on requestHours list per staff member and day (CSV)Hours list per staff member and day, to transfer into Nmbrs. Live via the Nmbrs API after registering an app with Nmbrs.
Salar (Van Winckel)✓––Hours list per staff member and day (CSV)Hours list per staff member and day for the payroll bureau; the import format of Salar is not public.
Social secretariats
Acerta–✓on requestHours list per staff member and day (CSV)Social secretariat: you get the layout of the performance file from Acerta; until then the hours list.
Group S–✓on requestHours list per staff member and day (CSV)Social secretariat: you get the layout of the performance file from Group S; until then the hours list.
Liantis–✓on requestHours list per staff member and day (CSV)Social secretariat with an API that Liantis releases per company; until then the hours list.
Partena Professional–✓on requestHours list per staff member and day (CSV)Social secretariat: you get the layout of the performance file from Partena; until then the hours list.
SD Worx✓✓–SD Worx Tijdsregistratie (TXT), Hours list per staff member and day (CSV)Belgium: Tijdsregistratie file (fixed positions, per staff member per day) for "Tijdsregistratie importeren". Netherlands: the hours list.
Securex–✓on requestHours list per staff member and day (CSV)Social secretariat: integrations run via partners; until then the hours list.
Scheduling and time tracking
Book'u–✓on requestRevenue per day and hour (CSV)Book'u files the Dimona declarations; a till integration is available on request. Until then the revenue list.
Deputy✓✓✓Revenue per day and hour (CSV)Live: the revenue per hour goes to Deputy (Sales) every hour. You create a permanent token in Deputy under API integrations.
Dyflexis✓–✓Revenue per day and hour (CSV)Live: the revenue per hour goes to Dyflexis (information streams) every hour. You get the API token via Dyflexis.
Eitje✓–on requestRevenue per day and hour (CSV)Eitje connects via its partner programme; until then the revenue list per day and hour.
Exact Horeko✓–on requestRevenue per day and hour (CSV)Integration via Horeko (on request); until then the revenue list.
Fooks✓–on requestRevenue per day and hour (CSV)Fooks builds till integrations itself; until then the revenue list per day and hour.
L1NDA✓–on requestRevenue per day and hour (CSV)L1NDA builds till integrations together with partners; until then the revenue list per day and hour.
Mr. Einstein✓–on requestRevenue per day and hour (CSV)HR, rotas and wage costs for hospitality; Mr. Einstein builds till integrations together with the POS supplier (apply via mreinstein.nl/contact). Until then the revenue list per day and hour.
Nostradamus✓✓on requestRevenue per day and hour (CSV)Nostradamus accepts the revenue via its till interface (API token and the business's domain, after applying to Nostradamus); until then the revenue list per day and hour.
Plan-Me–✓on requestRevenue per day and hour (CSV)Plan-Me files the Dimona declarations; a till integration is available on request. Until then the revenue list.
Planday✓✓on requestRevenue per day and hour (CSV)Planday has an open API for till systems; the integration will follow after coordination. Until then the revenue list.
Shiftbase✓–✓Revenue per day and hour (CSV)Live: the revenue per day goes every hour to the department's logbook in Shiftbase. You create the API key in Shiftbase under App center.
Shyfter–✓on requestRevenue per day and hour (CSV)Shyfter files the Dimona declarations and accepts revenue per day via its API; the integration will follow after coordination with Shyfter. Until then the revenue list.
Strobbo✓✓–Strobbo revenue import (Excel), Revenue per day and hour (CSV)Excel file for Planning → € → Importeer omzet (revenue per day per workplace).
Tamigo✓✓on requestRevenue per day and hour (CSV)Integration via Tamigo (on request); until then the revenue list.
Werktijden.nl✓––Revenue per day and hour (CSV), Hours list per staff member and day (CSV)Werktijden.nl records the hours itself and does not (yet) accept revenue via its API; the lists are there for comparison.
XPS Logic✓–on requestRevenue per day and hour (CSV)XPS Logic focuses on flexible and temporary agency staff; an integration is available on request. Until then the revenue list.

Legal requirements in Belgium and the Netherlands

What the law requires and what HorecaPOS does for it (have your accountant confirm what applies to your business):

CountryRequirementHorecaPOS
BelgiumRegistered cash register system (GKS 2.0) with black box for hospitality businesses that must comply (incl. with more than € 25.000 annual revenue from meals, excl. VAT)link with the black box (FDM), the mandatory data on the receipt and the counters on the Z report (country Belgium under Settings → Business, FDM_API_KEY and FDM_TERMINAL_ID); at the top of Settings → Business you choose whether the business is GKS-obligated: Yes = check out only with a working black box, No = without, with a declaration by the admin (renewed every year); as long as nothing is chosen, checkout is not possible. The till counts the revenue from meals and warns above € 25.000
BelgiumE-invoicing via Peppol: since 1 January 2026, invoices between Belgian VAT-registered businesses must be structured electronic invoices (UBL, Peppol BIS 3); till receipts to consumers are not coveredexport of daily turnover as UBL according to Peppol BIS Billing 3.0 for the accounting package (Accounting export); and invoices from a receipt for business customers (Settings → Invoices): UBL according to Peppol BIS Billing 3.0 plus a printable invoice, sent by email, via Billit to the Peppol network, to your own address or downloaded (see Invoices for business customers)
BelgiumHospitality VAT since 1 March 2026: takeaway meals and non-alcoholic drinks 12% (eat-in and takeaway), alcohol 21%, meals the customer still prepares themselves (fondue, gourmet) 6%VAT assistant (Settings → Laws and rules): the type per product, the correct rate immediately or from a date; the descriptions of rates A/B/C have been updated
NetherlandsAlcohol Act: no alcohol for young people under 18, including online sales and delivery (check age on delivery)Age check: products containing alcohol; in the webshop the customer confirms 18+ themselves (box not pre-ticked) with a notice that their age will be checked on delivery; "18+" on kitchen ticket, delivery slip and receipt
NetherlandsDisposable cups and containers (SUP): since 2024 a separate, visible price for plastic disposable packaging for takeaway and deliveryDisposables charge per product, as a separate line on the receipt (product's VAT) and separately in the turnover
NetherlandsDeposit on cans and plastic bottlesDeposit per product (€ 0.15 / € 0.25), separate line without VAT for takeaway and delivery, separately in the turnover
NetherlandsCash payments: since 1 January 2026 no € 3,000 or more in cash for goodsWarning for takeaway and delivery (also at the cash machine); confirming is possible and is recorded in the log
Netherlands and BelgiumVAT change: a rate or a product gets a different VAT percentage from a certain dateSchedule VAT change: the till carries it out on the day itself (in Belgium per product, the letters A/B/C/D are fixed)
NetherlandsAccommodation (overnight stays) 21% since 1 January 2026VAT rate configurable per product
EUOmnibus Directive: a struck-through "was" price may only be the lowest price of the last 30 daysthe webshop only strikes through against the lowest price of 30 days (the till keeps the price history; happy hours that recur every week count too)
EUEuropean Accessibility Act (since 28 June 2025): webshops accessible (WCAG 2.1 AA)the webshop works with keyboard and screen reader ("Skip to content" link, visible focus, labels) and has an accessibility statement (link at the bottom)
NetherlandsXML Auditfile Financieel (XAF): the standard of the Dutch Tax Administration (Belastingdienst) for transferring (part of) the accounting records; XAF 4.0 is mandatory from 2027export as XAF 4.0 (Accounting export)
NetherlandsReliable checkout system: keep the till data (all receipts, corrections and events) and be able to supply it digitally during a tax audit; for this the Dutch Tax Administration (Belastingdienst) recommends the XML Auditfile Afrekensystemen (XAA)export as XAA 3.2 (Report → Revenue per period → Cash register audit file), optionally signed with the supplier's certificate
BelgiumAttendance registration with a registered cash register system: recording the start and end of employees' working time in the cash register systemClock in/out (Settings → Business; Required = clock in first) is recorded in the black box
BelgiumDimona: declare every employment (including flexi-jobs and students) to the RSZ before it startsthis is done by your social secretariat or scheduling tool (e.g. Shyfter, Book'u, Plan-Me); HorecaPOS supplies the hours worked and the revenue (Settings → Working hours → Payroll and scheduling)
NetherlandsRecording of working and rest times (Working Hours Act, Arbeidstijdenwet)Clock in/out with the hours worked per staff member, adjustable by the manager (with log), and the hours list for the payroll package
Netherlands and BelgiumHACCP / food safety: record temperatures (chilling, freezer, hot holding, cooking, cooling down, goods receipt) and cleaning; NL Hygiënecode voor de Horeca (NVWA), BE FAVV self-checking (guide G-023)HACCP records in the POS (Settings → Laws and rules, HACCP button at the top): measuring points with limits, cleaning and check tasks, mandatory corrective action for a deviation, cannot be changed, overview with missed records as CSV or print (see HACCP records)
Netherlands and BelgiumRetention obligation (NL 7 years, BE 10 years)receipts, Z reports and the log are stored in the database and in the backups; the log cannot be changed or deleted from the till

Laws and rules

Settings → Laws and rules (administrator; the VAT assistant also with the Manage products permission). Everything is off by default; without these settings the till works as always.

Invoices (mandatory between businesses in Belgium) are described under Invoices for business customers. Still to do: GKS 2.0, find out the status of the certification (see docs/backlog-concurrenten.md).

Invoices for business customers

Settings → Invoices (administrator; off by default): switch on Invoices for business customers (UBL / Peppol). Once it is on, below it you will find Payment on account, the Invoice details, the Peppol services, the Bank connection (with payment on account) and the list of all invoices. In Belgium e-invoicing between businesses has been mandatory since 1-1-2026.

Self-service kiosk

Guests order themselves on a stand or tablet, like in a fast-food restaurant, and pay at the till or by card at the kiosk. The ordering screens are part of the till itself, so the menu, prices, options, set menus, happy hours, day parts, photos, allergens, languages and the receipt all come from the till and don't need to be set up anywhere else. The kiosk runs the PinPortal Kiosk 2 app (Android, including Sunmi, and Windows, Linux and macOS), which shows the page and prints the receipt. Off by default.

Switching on and setting up (administrator): Settings → Business → Screens and operation → Self-service kiosk.

The scanner itself is set up on the kiosk: in the PinPortal Kiosk 2 app under admin → Barcode scanner (as a keyboard, the built-in scanner or a COM port), with a scanner test. A scanner that works as a keyboard also works without the app.

Adding and linking a kiosk

  1. Under Kiosks, enter a name (e.g. Kiosk entrance) and choose Add kiosk. You get a link code of 6 digits (valid for 30 minutes).
  2. Choose for the kiosk how the guest pays: at the till by default. If it is a kiosk with a card terminal, choose by card or the guest chooses, and choose this kiosk's card terminal (from Settings → Payments).
  3. Open the kiosk page on the kiosk:
    • in the business: in the app under management → Vast adres, the address shown with the setting, e.g. http://192.168.1.20:3000/kiosk;
    • or via the management portal (https, also if the kiosk is not on the same network): link the kiosk address shown with the setting to the app's kiosk code, just like with the old kiosk.
  4. Enter the link code on the kiosk. Done: the kiosk remembers its own key. Link again gives a new code; Remove unlinks it.

Each kiosk shows whether it is online.

How the guest orders

  1. Start screen with the welcome text; the guest chooses their language (all POS languages) and taps to order.
  2. Eat here or take away.
  3. The menu per product group, with photos, the price (with happy hour), allergens and what is sold out. Products with choices or a set menu open the choice window.
  4. The basket: change quantities and optionally Anything else?.
  5. Order (paying at the till): the guest sees their pickup number large on the screen with the amount, gets the slip and pays at the till. In the till the order is open as Kiosk Entrance · 42 (the number the guest gives); settle the bill as usual. After that it shows as paid on the pickup screen, and goes to the kitchen if that was only to happen after payment.
  6. Pay by card: the till puts the amount on this kiosk's card terminal (the same card payment link as at the till). If it fails, the guest can try again or cancel (or, if the guest may choose, pay at the till after all). Only when the payment has succeeded does the order go to the kitchen and get settled. The guest sees their pickup number large on the screen and gets the receipt.
  7. After a few seconds the kiosk goes back to the start.

During an outage: alert and emergency mode (in the kiosk app, admin → Bij storing; off by default). If the kiosk cannot reach the till, it shows Even gesloten. Two extras:

In the till a kiosk order is an ordinary order (takeaway or eat-in, named Kiosk Entrance) in the name of the staff member Kiosk. The till creates it itself; nobody can log in with it. Do not set it to inactive, or the kiosk cannot order. Kiosk orders appear in the reports, in Receipts and on the pickup screen. An order that is not completed on the kiosk (not ordered or not paid by card) expires by itself after 30 minutes.

Card payments in test mode (Settings → Payments)? Then the kiosk doesn't really take payments; handy for trying it out. Without internet, card payment is not possible; the kiosk then says you can order at the counter.

Outage: if the till cannot be reached, the kiosk app shows "Temporarily closed" and resumes by itself. If the kiosk runs via the management portal and the internet goes down, the app can fall back on the till on the local network (in the app: admin → Extensions → Fall back on the local network during an outage); the kiosk passes that address on itself.

Switching off: the kiosk says it is closed for a moment. The kiosks and settings are kept. The log records on/off, the settings, added and removed kiosks, linking and cancelled orders.

Digital menu board

The menu with prices on a TV (or another monitor with a browser), straight from the till. Off by default; turn it on via Settings → Business → Screens and operation → Digital menu board. Then open http://<kassaserver>:3000/menubord on the TV (or use the On a separate screen / On a tablet or phone button with the QR code). No login and no pairing.

Staff and PINs

Settings → Staff (administrator only): add staff, change name, role and PIN, and set them to inactive.

Log in with a card (optional)

Off by default. To turn it on: Settings → Staff, tick Log in with a card (NFC, RFID or iButton). Required: a USB card reader that works as a keyboard (for NFC or RFID cards, key fobs, wristbands or iButton keys). Such a reader "types" the card number and presses Enter; no driver or connection is needed.

Permissions per role

Settings → Permissions (administrator only): tick per role what waiters and managers may do. By default everything is exactly as above (as the till always did); a box that differs is coloured.

PermissionWaiterManager
Remove lines after ordering (void)yesyes
Give discount / remove discountnoyes
Mark product as "sold out"yesyes
Print a copy of a receiptyesyes
Return (credit note)noyes
Check out on account and receive payments on account (only with payment on account on)noyes
Interim total (X report)yesyes
Close day (Z report)noyes
Revenue per periodnoyes
Manage cash drawernoyes
Manage gift cards (only with gift cards with balance)noyes
Read and reply to reviews (only with review management on)noyes
Manage loyalty card (only with the loyalty card on)noyes
View lognoyes
View camera feeds (only with camera feeds on)noyes
Manage stock (only with stock on)noyes
Managing productsnono
Manage floor plansnono
Set up business, payments and printersnono
View and edit working hoursnono

Business details

Settings - Business

Settings → Business (administrator only): name, address, postcode, town, phone and VAT number of the location. These appear at the top of every receipt and pro forma. The text at the bottom of the receipt can also be set here (several lines allowed; empty = no text; default "Bedankt en tot ziens!"), and below it the receipt language (Dutch by default; see Languages). A preview of the receipt updates live. After saving, the next receipt uses the new details immediately. The country and fiscal details (GKS) deliberately cannot be changed here. In Belgium the VAT number is mandatory. With the Round cash payments to 5 cents checkbox (off by default) the total is rounded for cash payments (€ 6,62 → € 6,60, € 6,63 → € 6,65); the difference appears as "Rounding" on the receipt. Card payments always stay exact to the cent.

Managing products

Settings - Products

Log in as administrator and choose Settings → Products.

Product photos

Each product can have a photo.

Barcode scanner

With a barcode scanner on the till you scan products, discount codes, loyalty cards and gift cards. Turn it on under Settings → Scanner (tab next to the printers and the scale; off by default). Tick what a scan on the order screen does:

The till checks the products first, then the loyalty cards, the gift cards and the discount codes. Scanning works on the order screen when you are not in an input field. In an input field the code simply goes into that field.

Scanner test: under Settings → Scanner you see the code for each scan and what the till makes of it, even while the scanner is still off. If it doesn't work:

On the kiosk you set up the scanner separately (Settings → Business → Kiosk); see Self-service kiosk.

Print labels

Product labels with the name, the price and a barcode, on a label printer (Brother, Dymo, Zebra ...) installed on the computer or tablet. Turn on under Settings → Business → Print labels (off by default). There you also choose the format of the label (38 × 25, 57 × 32, 62 × 29 or 100 × 50 mm) and whether the price and the barcode are printed on it. Print sample prints one test label.

Setting up the scale (A&D, Aclas, Adam Equipment, Avery Berkel, Avery Weigh-Tronix, Balanzas Marques, Baxtran, Bizerba, Brecknell, CAS, Datalogic, Dibal, DIGI, Dini Argeo, Excell Precision, Gram, Ishida, Kern & Sohn, Mettler Toledo, Minebea Intec, Ohaus, Precia Molen, Precisa, Rice Lake, Rongta, Sartorius, Star Micronics, T-Scale, UWE, Wedderburn, Wintec, Zebra)

Separate tab Settings → Scale (Set up business, payments and printers permission, by default administrator only; the tab is always there, even if the scale is still off). Off by default: the till then works exactly as before. Can't see the tab?

Automatic search. If nothing has been set up yet, the till searches automatically when you open this section (the Search button does it again):

Found = filled into the form with the Enable and use button: one tap and it works. (Searching sends a W to every free COM port; a port that is in use, e.g. by the card terminal, is skipped.)

All Aclas scales. For each scale you choose the model; the POS then knows how it can be connected. There are two kinds:

One list, two tick boxes. All scales are in one list. For each scale you tick what it does: Weigh at the till (the POS asks for the weight when ordering) and/or Scan labels (the scale prints a label with a barcode that the POS scans, and receives the PLUs from the POS). A PC or AI scale such as the TS6X can do both; an LS label scale only labels. Labels can come from one scale per venue.

ModelTypeConnectionsIn the POS
OS6XPOS scaleRS232, USB, Bluetoothconnected, several at once
OS2XPOS scaleRS232, USBconnected, several at once
CS6X, CS3XCash register scaleRS232, USB, Ethernet, wificonnected, several at once
TS6X, TS3X, TS5EX, TS5NX, TS5GXPC scale (Windows, Android, Linux)RS232, USB, Ethernet, wifion this device (1x), also as label scale
iS6X, iS2X, iR6X, Ti6X, iL8XAI scale with product recognition (Windows, Android, Linux)RS232, USB, Ethernet, wifion this device (1x), also as label scale
iS5X, OiT2XAI scale (Linux only)RS232, USB, Ethernetconnected or as label scale
LS2S, LS2RX, LS2CX, LS2NX, LS5SX, LS5RX, LS5CX, LS5NX, LS6CX, LS6RX, LS6NXLabel scaleRS232, Ethernet, wifiscan labels and PLUs
PS1CX, PS1DX, PS6CX, PS6DXPrice computing scaleRS232connected, several at once
PS1BXPrice computing scale without connectionnoneweight by hand
LH15XHanging scale with label printerRS232, Ethernet, wificonnected or as label scale

A&D, Adam Equipment, Avery Berkel, Avery Weigh-Tronix, Balanzas Marques, Baxtran, Bizerba, Brecknell, CAS, Datalogic, Dibal, DIGI, Dini Argeo, Excell Precision, Gram, Ishida, Kern & Sohn, Mettler Toledo, Minebea Intec, Ohaus, Precia Molen, Precisa, Rice Lake, Rongta, Sartorius, Star Micronics, T-Scale, UWE, Wedderburn, Wintec and Zebra. The commonly used models of these brands are included for which it is established how the POS talks to them (to be tested = the protocol is not literally stated in a source; the POS chooses the most obvious one). All connected (several at once), or as a label scale whose label the POS scans:

BrandModelTypeConnectionProtocol (factory default)In the POS
A&DEK-i (incl. EK-610i), HV-WPCash register scale (weight only)RS232, EK-i also USBContinuous (stream mode), 2400 baud, 7E1connected, several at once
Adam EquipmentSwiftPrice computing scaleRS232, USB (optional)Continuous (continuous to PC), 9600 8N1 (to be tested)connected, several at once
Avery BerkelFX110, FX120, FX131 (built-in with scanner)Cash register scaleRS232, FX131 also USBMettler Toledo 82/7 = Toledo 8217 (POS sends W), 9600 baud, 7E1connected, several at once
Avery BerkelFX125Price computing scaleRS232Checkout-Dialog 06 (9600, 7O1)connected, several at once
Avery BerkelXs, XTs, XTiLabel scaleEthernet, Wi-Fi, USBown PLUs on the scalescan labels
Avery Weigh-Tronix7820, 7829, ZP900Cash register scaleRS232, 7820 also USB, ZP900 also USB and EthernetNCI (POS sends W), 9600 baud, 7E1connected, several at once
Balanzas MarquesBM1000P TOPCash register scale (weight only)RS232METTLER (POS sends W, Toledo), 9600 baud, 7E1connected, several at once
Balanzas MarquesBM5 Junior Tower Label, BM500 ETQLabel scaleEthernet, USB, RS232, BM500 ETQ also wifiown PLUs on the scalescan labels
BaxtranTW, VW, XTA, XTA-PPrice computing scaleRS232Toledo (POS sends W), 9600 baud, 7E1connected, several at once
BizerbaCS 300 (also built-in)Cash register scaleRS232Checkout-Dialog 06 (9600, 7O1)connected, several at once
BizerbaK-Class Flex, KH IILabel scaleEthernetown PLUs on the scalescan labels
Brecknell6702U, 6710U, 6720UCash register scaleRS232, USB (virtual COM port)NCI (POS sends W), 9600 baud, 7E1connected, several at once
CASPD-II, PDN, PDI, PDS-BCash register scaleRS232, PDN also USB and Bluetooth, PDI also USBECR type 2 = Toledo (POS sends W), 9600 baud, 7E1connected, several at once
CASCL3000, CL5500, CL7200Label scaleEthernet, USB, RS232, CL5500 and CL7200 also wifiown PLUs on the scalescan labels
DatalogicMagellan 9300i, 9400i, 9800i (scanner with scale)Cash register scaleRS232 (separate scale port), USBMettler Toledo 8217 (POS sends W), 9600 baud, 7E1connected, several at once
DibalKS-400, D-POS 400Cash register scaleRS232, D-POS 400 also USBCheckout-Dialog 06 (9600, 7O1)connected, several at once
DibalG-325, PI-100Price computing scaleRS232Checkout-Dialog 06 (9600, 7O1)connected, several at once
DibalM-500 (Mistral), D-900, CS-2200Label scaleEthernet, Wi-Fi, USBown PLUs on the scalescan labels
DIGIDS-781Price computing scaleRS232DIGI Type B (POS sends ENQ), 9600 8N1connected, several at once
DIGISM-120, SM-6000Label scaleEthernet, Wi-Fiown PLUs on the scalescan labels
Dini ArgeoDFW, DGT, 3590ECash register scale (weight only)RS232, USB, Ethernet, DFW and 3590E also wifiContinuous (ST,GS, 0.512,kg), 9600 8N1connected, several at once
Excell PrecisionTPE, AM4, FD4-P, FDP4-P, GE4, GEP4Price computing scaleRS232Continuous (ST,GS,+0.876kg), 9600 8N1 (except TPE, to be tested)connected, several at once
GramXFOC RS, XFOC+ RS, ZFOC RSPrice computing scaleRS232, USB (Gram cable)Gram (POS sends ENQ, then DC1), 9600 8N1 (XFOC to be tested)connected, several at once
IshidaUni-3, Uni-5, Uni-7, Uni-9Label scaleEthernet, Wi-Fi, USBown PLUs on the scalescan labels
Kern & SohnRPB, RFCPrice computing scaleRS232, USBCheckout-Dialog 06 (Prot = DLG-06, 9600, 7O1)connected, several at once
Kern & SohnRFE (price), IFB, EOCPrice computing / cash register scaleRS232Continuous, 9600 8N1connected, several at once
Mettler ToledoAriva-SCash register scaleRS232, USB (virtual COM port)Toledo 8217 (POS sends W), 9600 baud, 7E1connected, several at once
Mettler ToledoVivaCash register scaleRS232Toledo 8217, 9600 baud, 7E1connected, several at once
Mettler ToledobPlus, UC EvoLabel scaleEthernet, Wi-Fiown PLUs on the scalescan labels
Minebea IntecSignum, Combics, Midrics, PuroCash register scale (weight only)RS232, USB, Signum and Combics also EthernetContinuous (SBI, automatic printing), 9600 8N1connected, several at once
OhausAviator 7000Price computing scaleRS232 or USBCheckout-Dialog 06 (9600, 7O1)connected, several at once
OhausValor 7000, Ranger 3000, Ranger 4000, Ranger 7000, Defender 3000Cash register scale (weight only)RS232, USB, EthernetContinuous (Auto Print Continuous), 9600 8N1connected, several at once
Precia MolenDP400Cash register scaleRS232, USBCheckout-Dialog 06 (9600, 7O1)connected, several at once
Precia MolenDPOS CR, C 210 B, C 210 CPrice computing scaleRS232Checkout-Dialog 06 (9600, 7O1; C 210 to be tested)connected, several at once
Precia MolenCorail 500Label scaleEthernet, Wi-Fiown PLUs on the scalescan labels
PrecisaXB, XT, LS, LX (precision balances)Cash register scale (weight only)RS232, LS and LX also USBContinuous (print mode CONTINUOUS), 9600 8N1connected, several at once
Rice LakeBenchPro BP-S, BenchPro BP-RCash register scaleRS232BP-S Toledo 8213, BP-R NCI (both: POS sends W), 9600 baud, 7E1 (to be tested)connected, several at once
RongtaRLS1000, RLS1100Label scaleEthernet, RS232, wifiown PLUs on the scalescan labels
SartoriusEntris, QuintixCash register scale (weight only)RS232, USBContinuous (SBI, automatic printing), 9600 8N1connected, several at once
Star MicronicsmG-T12, mG-T30, mG-T60, mG-S8200Cash register scale (weight only)RS232, USB (virtual COM port)Continuous, 9600 8N1 (to be tested)connected, several at once
T-ScalePA10, PA15, PEA10Label scaleEthernetown PLUs on the scalescan labels
UWEASEPPrice computing scaleRS232Continuous, 9600 8N1 (to be tested)connected, several at once
WedderburnTSDS983Cash register scaleRS232DIGI Type B (POS sends ENQ), 9600 8N1 (to be tested)connected, several at once
WedderburnTSDS781T, TSDS782TPrice computing scaleRS232DIGI Type B, 9600 8N1 (to be tested)connected, several at once
WedderburnTSSM120Label scaleEthernet, RS232own PLUs on the scalescan labels
WintecScalePOS ACS-S60E (POS with built-in scale)Cash register scaleinternal COM6 (Windows) or COM4 (Android)Continuous, 9600 8N1 (to be tested)connected
ZebraMP7000, MP72 (scanner with scale)Cash register scaleRS232 (AUX port)SASI = Toledo (POS sends W), 9600 baud, 7E1 (to be tested)connected, several at once

The same list is in the POS under Settings → Scale → All scales (ACLAS_MODELLEN in packages/shared/src/weegschaal.ts, with the brand per model).

Fill in as little as possible: when you choose a model, the POS prepares the rest the way the brand sets it at the factory: connection COM port / USB on the first free port, 9600 baud (A&D: 2400) and the brand's protocol (Toledo: Aclas with 8N1, and with 7E1 Avery Berkel FX, Avery Weigh-Tronix, Balanzas Marques, Baxtran, Brecknell, CAS, Datalogic, Mettler Toledo, Rice Lake and Zebra; Dialog 06: Avery Berkel FX125, Bizerba, Dibal, Kern & Sohn RPB/RFC, Ohaus Aviator and Precia Molen; DIGI Type B: DIGI and Wedderburn; Gram: Gram; Continuous: A&D, Adam Equipment, Dini Argeo, Excell Precision, the other Kern & Sohn, Minebea Intec, the other Ohaus, Precisa, Sartorius, Star Micronics, UWE and Wintec), and a name (e.g. OS6X, OS6X 2). A PC or AI scale becomes On this device (e.g. TS6X (ingebouwd); on Linux on the internal port /dev/ttyS0). If something is wrong, Search finds the right port, speed and protocol.

On this device (Aclas Scale Module): the scale shows the legal-for-trade weight; the POS sends the price per kilo and the tare (as preset tare) and takes over the amount the scale calculates, just like with Dialog 06.

Aclas software is included with the POS: the Scale Module for Windows (aclas-module), AclasScaleDriver for Android (aclas-android) and the Aclas Sync SDK for Windows and Linux (aclas-sdk). Aclas allows us to ship them. The Windows and Linux installers include them; nothing to download or install separately.

Bluetooth (e.g. the OS6X): pair the scale first. Windows turns it into a COM port (Bluetooth settings → More Bluetooth options → COM ports), Linux /dev/rfcomm0: enter that port. In the Android app you enter the Bluetooth address (00:11:22:AA:BB:CC); the app asks once for permission for Nearby devices and connects via Bluetooth SPP.

AI scales (product recognition): the camera recognises the product in the Aclas software on the scale. Weighing works via the Scale Module (on this device) or the RS232 port; AI label scales print a label with a barcode after recognition, which the POS scans (as with the TS6X).

Aclas AI Recognition Plugin (AI scale with the POS on it, e.g. the iS6X with Windows): the Aclas plugin recognises the product and types its barcode into the POS, just like a scanner (followed by Enter); the order screen adds the product with its weight to the order. This is how you set it up:

Aclas OS6X (POS scale at the till, RS232/USB; the other connected scales work the same way):

Scan labels (tick box at the scale: Aclas TS6X, another PC or AI scale, the LS series or the LH15X; scale + label printer, one per venue):

Management portal: the report to the portal has the function Scale (A&D, Aclas, Adam Equipment, Avery Berkel, Avery Weigh-Tronix, Balanzas Marques, Baxtran, Bizerba, Brecknell, CAS, Datalogic, Dibal, DIGI, Dini Argeo, Excell Precision, Gram, Ishida, Kern & Sohn, Mettler Toledo, Minebea Intec, Ohaus, Precia Molen, Precisa, Rice Lake, Rongta, Sartorius, Star Micronics, T-Scale, UWE, Wedderburn, Wintec, Zebra) with on/off and which scales per model (e.g. TS6X (op dit apparaat), 2x OS6X, PS1CX, Ariva-S, DS-781, LS6RX, 5 producten per kilo); no IP addresses, COM ports or Bluetooth addresses.

Weights and measures law: a scale you sell with must be calibrated (class III, like the OS6X). With Toledo/continuous the till calculates with the weight the scale provides; with Dialog 06 the calibrated scale calculates the price itself.

Code: packages/shared/src/weegschaal.ts (protocols, labels, PLU file), apps/pos-server/src/lib/weegschaal.ts and routes/weegschaal.ts; screens WeegschaalInstellingen.tsx and WeegDialoog.tsx.

Thuisbezorgd.nl / Takeaway.com

Orders from Thuisbezorgd.nl come straight into the till, without an intermediary (no Deliverect, HubRise or similar): Just Eat Takeaway JET Connect talks to the Pin Voordeel management portal, and the till collects its messages from there.

In Belgium the platform is called Takeaway.com: the same company (Just Eat Takeaway) and the same integration. For a Belgian business, the screens, notifications, kitchen ticket and management portal show Takeaway.com everywhere instead of Thuisbezorgd.nl. Below, Thuisbezorgd stands for both.

Why via the portal? The till only needs PORTAAL_URL and PORTAAL_SLEUTEL (see Management portal) and only makes outgoing requests.

Setup (Settings → Delivery platforms → Thuisbezorgd.nl / Takeaway.com, permission Set up business, payments and printers; previously this was under Settings → Business):

  1. Turn on Use Thuisbezorgd (takes effect immediately, separate from Save).
  2. Register with Thuisbezorgd. The business then chooses OptimumPOS / Pin Voordeel as its POS at Thuisbezorgd (Partner Hub or account manager). JET then starts an onboarding session; the portal finds the registered till (by postcode and name, otherwise Pin Voordeel links the session manually in the portal), sends the configuration and asks the till for the menu. The integration then goes live.
  3. Tick the products that can be ordered via Thuisbezorgd (per group or individually), optionally with a description for Thuisbezorgd. The menu (price, options as modifiers, allergens, VAT) is included automatically; PLU = id of the product/option. After a change in the catalogue the till updates the menu within 30 seconds; only "sold out"/"available again" goes via the availability API.
  4. Thuisbezorgd opening hours: separately for delivery and collection (e.g. 16:00-22:00, several blocks separated by a comma). They are saved with the Save opening hours button below and are sent to Thuisbezorgd as service times as soon as the integration is ready.
  5. Temporarily closed / Open again (in NL/BE open again by 07:00 the next morning at the latest).

Orders. An order becomes a normal order without a table (bezorgen or afhalen, group name TB <ordernummer>) with the prices the customer paid, plus delivery/service charges as a separate line and Thuisbezorgd discounts as a discount line; if the total still doesn't match, a line "Verschil Thuisbezorgd" is added. The kitchen ticket goes to the kitchen/bar immediately (can be turned off). The till confirms within seconds to the portal, which reports it to JET; if that fails within 3 minutes or the till is offline, JET receives "failed" and the business falls back on the Orderpad.

Thuisbezorgd button in the top bar (with the number of active orders): list, customer and address, ready/delivery time and the timeline (track & trace): received, courier on the way to the restaurant, courier at the restaurant, on the way to the customer, delivered (from JET), plus own steps (in preparation, ready, on the way/delivered when delivering yourself, picked up). JET Connect does not offer the till a live map of the courier; the customer sees that in the Thuisbezorgd app. A new order, a cancellation and "courier at the restaurant" trigger an orange bar and a sound. Complete (paid online) checks out with payment method online; if the customer pays at the door, just check out as usual. A cancellation from Thuisbezorgd voids the order and prints a "GEANNULEERD" (cancelled) kitchen ticket.

Code: apps/pos-server/src/lib/thuisbezorgd.ts, routes/thuisbezorgd.ts; screens ThuisbezorgdInstellingen.tsx and Thuisbezorgd.tsx. Portal side: horecapos-portaal/src/thuisbezorgd.mjs (see the portal's README).

Count in the management portal. The number of Thuisbezorgd orders per day is included in the report to the management portal (verkoopTelling in lib/portaal.ts): received and not cancelled, on the day received. A Thuisbezorgd order checked out in the till (including Complete (paid online)) is not counted again there under takeaway/delivery. The Thuisbezorgd data is stored in the till database and is therefore simply included in the till's backups.

Webshop and online ordering

Each business can get its own webshop: an ordering site (and app) in its own branding for takeaway, delivery, ordering at the table with a QR code and reservations, with online payment (MultiSafepay or Buckaroo) or payment on collection/delivery. The webshop is a separate project, horecapos-webshop (Node.js, see the README there), and runs on the same server as the management portal.

Turning on and setting up is done in webshop management: the Manage webshop button in the customer portal (owner) or at the installation in the management portal (Pin Voordeel). There you find on/off, the web address (<zaak>.<webshopdomein> or your own domain), branding (colours, logo, header image, font), opening hours and time slots for takeaway and delivery, delivery area (postcodes, radius or an area on the map, with charges and minimum), payment, discount codes, texts, languages, QR codes for the tables, reservations and the app (installable as a PWA; an Android app via a Trusted Web Activity), and push notifications (optional, off by default): the guest turns on a notification on the page of their order and gets a push notification when the order is ready or on its way; those who want can also get an occasional offer, which the business sends from webshop management (Push notifications tab). Works on Android and computers (Chrome, Edge, Firefox, Samsung Internet), in the Android app, and on iPhone and iPad (iOS 16.4 or later) if the guest adds the webshop to their home screen. No text message or email is sent and no name or number is stored. Details in the webshop README.

Menu. The till sends the menu automatically: all active products (not sold per kilo), per product group, with price, choice options, allergens, sold out and the product photo, plus the tables and the business details, and which marketing channels are on (for the "receive offers" checkbox at checkout, see Text and email marketing). This happens at startup, as soon as the webshop is turned on, within 30 seconds of a change in the catalogue and within a few seconds of a change under Settings → Business, such as marketing or the loyalty card (or with Send menu now). You can keep a product out of the webshop in webshop management (hide), or in the database with artikel.webshop = false.

Orders. Takeaway and delivery become a regular order without a table (group name WEB <bestelnummer>) with the prices the guest saw, plus delivery charge and transaction costs as separate lines and a discount code as a discount line; if the total still does not match, a "Webshop difference" line is added. The guest's tip does not count as revenue: it is added to the payment as a tip with Complete (paid online). Ordering at the table (QR code) goes to that table's open bill (paid online: as a separate group at that table). The kitchen ticket goes straight to kitchen/bar (can be turned off in the Webshop window). The till confirms within seconds with the receipt number; the guest then gets "received" and an email. If the till is offline, the webshop does not accept orders (the guest sees this immediately) and emails the business if an order is left waiting too long. Reservations from the webshop go to Reservations (only if reservations are turned on in the till). If a maximum per time slot is set (Delivery and time slots), webshop orders with a time in that slot count too.

Belgium (black box). A webshop order goes straight to the black box as an order (signOrder), before the work ticket, just like Send order at the POS. If that fails, it does not reach the POS and the webshop resends it later. Anything not yet tested with the black box is switched off in the webshop menu (gift cards, discount codes, on account, charge to room, menus, options with a surcharge, happy hour and tips) and is rejected if an old webshop sends it anyway. Complete checks tips, on account and charge to room just like the POS.

Charge to room (hotel integration, Settings → Hotel → Self-service → In the webshop): the menu gets kamer: { maxBedrag }; the webshop sends betaling.wijze = "kamer" with kamer and achternaam. The POS checks the guest with the hotel software (not at the table, not with a gift card) and stores it with the order; Complete (charge to room) settles to the room and posts the receipt to the hotel bill. Collective invoice for on account: the receipt then remains as an open item.

Webshop button in the top bar (with the number of active orders): list, customer and address, requested time or "as soon as possible", payment method and the timeline. The guest sees the steps In preparation, Ready and On the way live in the webshop (and by email, if the business wants). Checked out in the till = Completed; Cancel voids only the lines of that webshop order, prints a "CANCELLED" kitchen ticket, and the webshop refunds an order paid online. Arrived, no-show or cancelled for a reservation is also sent back to the webshop. A new order or reservation shows an orange bar and plays a sound.

Code: apps/pos-server/src/lib/webshop.ts, routes/webshop.ts; screen Webshop.tsx. Portal side: horecapos-portaal/src/webshop.mjs.

Till and webshop in sync (each part can be switched on separately, off by default; an older webshop ignores the new fields). What is turned on in the till also works in the webshop:

For this, the menu for the webshop has versie: 2 with the fields menuArtikelen, allergenenAan, happyhours, menus, klantenkaart, cadeaubon, kortingscodes, pauze, drukteMin, volgt, bezetting, reserveren.online, ayce, opRekening, wachtlijst and upsell. The confirmation to the portal also has cadeaubonnen (codes), klant (points) and plek (waiting list).

Count in the management portal. Takeaway and delivery via the webshop are counted separately (webshop, webshopGeannuleerd in verkoopTelling), on the day received, and not again under takeaway/delivery. Ordering at the table is simply counted under table.

Card payments and terminals

Settings → Payments (administrator only):

If there is at least one terminal with an API key (or test mode is on), Checkout → Card / Bancontact starts the payment automatically on the terminal, for the amount calculated by the server.

While the integration is on, the server only accepts "card" with a successful terminal payment for exactly that order and that amount. The requests are sent as a regular form, just as in the official PHP SDK, with the backup API (api-backup.pinvandaag.com) if the main API does not respond. Every API response is shown with [pin] in the server window, handy when troubleshooting. A successful payment that has not yet been processed (e.g. tablet crashed) is found again the next time that order is checked out.

Tips (card, cash and gift card)

The checkout screen shows a row of tip buttons for each payment method: None, 5%, 10%, 15% (rounded up to 10 cents), Rounding (to the next whole euro) and Other amount. With card the customer pays amount + tip in one go on the terminal; with cash the tip is included in the change and the cash drawer. The receipt shows the card amount with "of which tip" below it; the TOTAL and VAT stay the same, because tips are not revenue. The X/Z report shows the tips per payment method and as "Total tips".

The administrator sets up the tip buttons under Settings → Business → Tip: on/off, which percentages (at most 4, e.g. "5, 10, 15"), whether the "Rounding" button is included and for which payment methods (card, cash, gift card) tips are possible. "None" and "Other amount" are always included.

"Make it …" is always there, for every payment method, even when the tip buttons are off (no setting): the customer rounds the bill up themselves and the difference is the tip. There are buttons with the next whole euro and the next round amounts (e.g. € 28,00 → 29, 30, 40; € 44,00 → 45, 50, 60) and Other total to type in the total yourself. Tap the chosen button again = no rounding. At most € 500 tip (same limit as the till server).

No internet

The till works on the local network and does not need internet; only card payments via the integration do. If the business has no internet, the top bar shows No internet · card manually (checked every minute). The checkout screen then shows, also after a failed start on the terminal, the Already paid on the terminal button: take the card payment on the terminal itself and record it this way.

Floor plans and tables

Floor plan editor

Settings → Floor plans (administrator only):

Copy configuration to a second venue

Settings - Import/export

Settings → Import/export (administrator only). Once you have fully set up one business, export the configuration to a .json file and import it into the till of the second business. You can choose per section:

Never included: name, address, postcode, town, phone, email, VAT number and receipt footer of the business, the email address for the Z report, card terminals and their keys, staff and PINs, and all revenue, receipts, customers and stock quantities.

Importing is heavily protected: a large red warning, a checkbox "I understand...", the administrator's own PIN again, no open orders, the same country (VAT rates) and an automatic backup beforehand. The import happens in a single transaction: if anything goes wrong, nothing changes. Existing products, groups, ingredients and tables are not erased but removed from the till (as with Delete), so old receipts and reports stay correct.

Import from another till

Switch without retyping everything. Always available (no switch): Settings → Import/export (administrator only) contains the section Import from another till.

Languages (42, including Turkish, Arabic, Darija, Berber, Polish, Bulgarian, Hungarian, Russian, Serbian, Albanian, Persian, Tigrinya, Amharic, Somali, Papiamento, Sranan Tongo, Hindi, Urdu, Indonesian, Vietnamese, Syriac-Aramaic, Chinese and Ukrainian)

Next to the © button at the bottom right, every screen has a language button (e.g. NL and the flag). Tap it for the menu: the languages are in alphabetical order, with the name in the language itself before the flag: Bahasa Indonesia (Indonesian), Čeština (Czech), Darija (Moroccan Arabic in Latin script), Deutsch, English, Español, Français, Hrvatski (Croatian), Italiano, Kurdî (Kurmancî), Latviešu (Latvian), Lietuvių (Lithuanian), Magyar (Hungarian), Nederlands, Papiamentu (Papiamento), Polski, Português, Română, Shqip (Albanian), Slovenčina (Slovak), Soomaali (Somali), Sranantongo, Srpski (Serbian, in Latin script), Tarifit (Riffian Berber), Tiếng Việt (Vietnamese), Türkçe, then in Cyrillic script Български (Bulgarian), Русский (Russian) and Українська (Ukrainian), then the languages in Arabic script: اردو (Urdu), الدارجة (Darija), العربية (Arabic), دری (Dari), فارسی (Persian, Farsi), پښتو (Pashto) and کوردی (سۆرانی) (Kurdish Sorani), then in Syriac script ܣܘܪܝܝܐ (Syriac-Aramaic, Suryoyo), in Devanagari हिन्दी (Hindi), in Ge'ez script ትግርኛ (Tigrinya) and አማርኛ (Amharic), in Tifinagh ⵜⴰⵎⴰⵣⵉⵖⵜ (Tamazight, Berber), and finally 中文(简体)(Chinese, simplified script). All screens, buttons, messages and error messages from the till server are translated.

For developers: every visible text is in the code as vt('Nederlandse tekst') (apps/pos-web/lib/i18n.ts); the Dutch text is the key. The translations are in apps/pos-web/lib/vertalingen/<taal>.ts. If a translation is missing, the till shows the Dutch; the i18n test (pos-web) checks that every text is translated in every language and that the {0} placeholders match. Messages from the till server stay in Dutch and are translated in the browser (also with {0}, e.g. a product name in the message).

Setting up printers

A new till has no printers. Log in as administrator (demo: 1111) and choose Settings in the top bar.

Identical products are combined when printing: twice 1x Cola becomes 2x Cola, on the kitchen ticket and on the receipt. Only products with the same options and note are combined.

The Linux installer adds the till user to the lp and dialout groups, so the till is allowed to use USB and serial printers.

Need help?

Optimum POS · 085 560 00 60 · support@optimumpos.nl · Mon–Fri 9:00–20:00, Sat–Sun 14:00–20:00