From Wolt order to KDS to printed receipt — the full path in VIND
How a Wolt order travels from the customer's phone to your kitchen ticket and to a sequentially-numbered fiscal receipt — and what we still owe the road map.
If you run a restaurant, the most expensive minute of your day is the minute between an aggregator order landing and your kitchen seeing the ticket. If that minute slips, food goes out cold, drivers wait, and reviews drop. The POS’s job is to make that minute boring.
This post walks through exactly what VIND does between “customer taps order in Wolt” and “fiscal receipt prints in your kitchen”. It is also honest about the gaps that are still on our road map — see our compliance honesty post for why we’d rather say “beta” than “production-ready”.
The four hops, in order
There are four moving parts between Wolt and your kitchen:
- Wolt’s order webhook posts the order to our
aggregator-bridgeservice. aggregator-bridgevalidates, normalises, and writes the order into the VIND order schema with the right tenant ID, table ID, and item mapping.api-gatewaybroadcasts the new order to your venue’s POS and KDS over a tenant-scoped channel.- POS + KDS render the new order locally and (when payment is confirmed) emit a sequentially-numbered fiscal receipt and a kitchen ticket.
Each hop has its own failure mode. Each hop has a retry. The combined system has a budget of two seconds end-to-end for 95 % of orders, and we measure it.
Hop 1 — Wolt → aggregator-bridge
Wolt POSTs to our endpoint with the order payload (items, customer note, delivery time, total). We validate the HMAC signature on the request — the same way you’d validate any webhook — and acknowledge with 200 OK only after the payload is durably written. If we 200 OK and then crash, Wolt thinks we have the order and we don’t; that’s the worst failure mode in this stack.
If the validation fails (wrong signature, malformed JSON), we 400 and Wolt retries with the same idempotency key. Idempotency is enforced — duplicate webhook deliveries (which Wolt does on their own retries) don’t create two orders.
The same path handles Bolt Food. The payload shape is different; the contract is the same.
Hop 2 — Mapping Wolt items to your menu
This is the hop that quietly costs the most engineering time. Wolt’s menu, the items in your POS, and your inventory don’t always line up. Wolt knows the item by an ID that means nothing to your kitchen. The kitchen knows it as “the Margherita pizza with extra olives”.
VIND solves this with a per-tenant item-mapping table maintained in the backoffice. When you connect Wolt, we sync your menu and you confirm or correct the mapping once. After that, every order from Wolt arrives with the canonical VIND item ID and your kitchen sees “Margherita + olives” the same as a walk-in order. Modifiers carry through. Allergen notes carry through. The 80-character free-text “customer note” carries through to the kitchen ticket header.
We refuse orders for items we can’t map. The driver gets notified, the customer gets the order voided, and the ops team gets a Slack ping. We never let a kitchen pick up an order without knowing what to cook.
Hop 3 — api-gateway → POS / KDS
Once aggregator-bridge has the canonical order, the api-gateway pushes it to the right venue. This is a server-sent event over a tenant-scoped channel. The POS and KDS at the venue both receive it within ~50 ms in our internal numbers.
The interesting decision here is server-sent events, not WebSockets. SSE is one-way (server → client) and free over plain HTTP. WebSockets is bidirectional and free over WS. The POS doesn’t need to push anything back over the channel — its writes go via the normal /sync/push path. So SSE is enough, and an SSE connection survives proxy boundaries that mishandle WS (we found one in Maltese ISP land during testing).
The KDS at the venue holds a separate SSE connection from the POS. They are siblings, not parent-and-child. The POS doesn’t have to be running for the kitchen to receive Wolt orders.
Hop 4 — POS records the sale, KDS shows the ticket
When the order lands on the POS, the cashier sees an “Aggregator inbox” with the new ticket. If the venue uses auto-accept (most do for Wolt — there’s a driver waiting), the order moves straight to “preparing” and the kitchen ticket prints automatically. If the venue uses manual accept (some do for trial periods), the cashier confirms the items and the rest of the flow runs.
The fiscal receipt is emitted on payment confirmation. For an aggregator order, payment is already confirmed by the aggregator before the order arrives — Wolt has taken the customer’s card. So the receipt prints alongside the kitchen ticket. The receipt is numbered from the same fiscal range as a walk-in sale; aggregator orders are not a parallel sequence. That matters at Z-time, when total daily takings have to reconcile.
The road-map gaps — and why we say so
We were tempted to publish this post without this section. Two reasons we didn’t:
- Aggregator integrations have known scenarios where we still owe more work. The Bolt menu sync is hourly; if you change a price at 09:01, Bolt sees it at 10:00. We’re moving to a webhook-on-change model for Bolt over Q3 2026. Wolt is already live with that pattern.
- The driver-arrival pickup-window logic is currently a static “ready in 15 minutes” estimate per item. We’re integrating with the kitchen’s real load (KDS WIP count + average prep time) to give a dynamic estimate; that’s a Q4 item.
If you’re considering switching, ask us specifically about the integration depth for your aggregator mix. We will tell you what’s live and what’s still on the road map. The same is true for Peppol — we’d rather call it beta and ship the truth.
Where to read more
- Product · Integrations — full inventory of supported integrations.
- Compliance · MTCA — the receipt-numbering rules that aggregator orders also follow.
- Pricing — aggregator integrations included from the Professional tier.
The path from a customer’s phone in Pieta to a ticket in your kitchen in Sliema runs through six services and one regulator. Our job is to make those six services look like one boring tool. Every line of aggregator-bridge, the SSE channel, the item-mapping pane, the fiscal-numbering ledger — every one of those is part of the same answer to a single question: can you cook the order before it goes cold?
See how VIND handles your real-world workflow.
15-minute demo, Maltese or English. No card.
Request a demoMore like this
-
What to look for in a POS in 2026 — beyond the brochure
Most POS demos look identical for the first ten minutes. Here are the seven questions that actually separate a good POS from a brochure with a card reader.
-
What MTCA actually wants from your POS in 2026
A plain-English checklist of MTCA fiscal requirements — what your POS has to do, what counts as compliant, and the five gotchas we see most often.
-
How VIND keeps selling when GO or Melita goes down
Offline-first POS isn't a feature, it's the floor. How VIND handles a 90-minute outage — cash, cards, kitchen tickets, Z-readings — and what reconciles when the link returns.