Fooodo / Docs

POS integration requirements

Evaluation spec for POS vendors — connectivity requirements, the connector contract, performance envelope, failure semantics, and how an integration is scoped.

Fooodo is a guest-facing ordering and payments layer that operates on top of an existing POS. Guests order and pay from the table via QR; orders are written into the POS through a server-side connector and arrive identically to orders entered at a terminal. The POS is not replaced: it remains the system of record for the menu and the source of truth for kitchen operations and reporting.

This document specifies what a Fooodo integration requires from a POS — the operations the POS API must expose, entity-level data expectations, connectivity and performance requirements, and failure semantics — followed by an evaluation checklist and the path to production. The intended reader is a POS vendor's engineering team assessing feasibility and effort.

Integration direction: Fooodo calls the POS API. The connector is implemented and operated by Fooodo; your side provides, documents, and supports an API surface reachable from Fooodo's cloud. No Fooodo software is installed or hosted on the POS side. A reference connector implementing this contract runs in production across a multi-location chain; new connectors are scoped per-customer once a chain signs on.

How the integration is shaped

  • Fooodo is the guest-facing ordering and payments layer; the POS keeps running the kitchen — same printer routing, same KDS, same reports.
  • The contract is: an order created through Fooodo arrives in the POS indistinguishably from an order typed in at a terminal. Kitchen staff don't need to know Fooodo exists.
  • Fooodo is the calling side. Reads are polled on a schedule (menu, order state); writes go out the moment an event happens (order created, order paid). Fooodo does not consume webhooks or event push from the POS — you don't need to build any.
  • Your side provides, documents, and supports the API — Fooodo builds and runs everything else.
  • Reference data is read-only across the boundary: Fooodo never modifies the POS menu, prices, modifiers, or other master data.

What your POS needs to expose

The connector contract covers four domains — locations, menus, orders, and payments. Concretely, as operations — named generically here; your API will have its own names for them:

OperationDirectionRequired?
Fetch the full menu — products, categories, prices, tax flagsFooodo readsRequired
Fetch modifier groups and ingredientsFooodo readsRequired
Check whether the location is onlineFooodo readsRequired
Read per-item availability ("sold out" flags) — may be served by the menu fetch or a status read, whichever your API exposesFooodo readsRequired
Get table-level order stateFooodo readsRequired
Get full order detailsFooodo readsRequired
Create or update an order — including appending items to an open order, and handling orders locked open at a terminalFooodo writesRequired
Mark an order as paidFooodo writesRequired
Send a kitchen messageFooodo writesOptional
Apply a loyalty card / serve loyalty-priced menuFooodo reads + writesOptional — only if the chain runs a POS loyalty programme

This is also the complete write surface — there is no cancel, void, or refund write across this boundary. Voids happen at the POS terminal as they do today (Fooodo picks them up through the in-progress order refresh), and refund handling sits outside the connector entirely — it never touches your API.

Fooodo runs two ordering flows — Pay-First, and Pay-Later multi-round dine-in, where rounds are appended to an open POS order and paid at the end (see fooodo.com/docs/order-flows). The operations above cover both; the append-to-open-order capability is what Pay-Later leans on hardest.

The contract is defined as operations, not as a wire format — the connector is built per-customer against the interface you already have. The transport and format of your API are reviewed during scoping; what matters for feasibility is that the operations above are exposed somehow.

If your POS can't expose one of the required operations directly, that is not automatically a dead end — it's the first thing a scoping call works through.

What the data looks like

Entity-level expectations, so your team can map them against your own data model. (Field-level schemas live in the integration repo, which partners receive during onboarding.)

  • Menu — categories containing products; products carry prices, tax flags, variants (e.g. sizes), and modifier groups (ingredient add / remove / swap, each with its own price). The POS stays the source of truth: Fooodo reads this structure, never writes it.
  • Order — a reference to a specific table at a specific location; line items with the chosen variant, modifiers, and quantities; totals. Orders can be appended to while open (the Pay-Later flow adds rounds to an open POS order), and discount or loyalty effects are reflected in the order the POS receives.
  • Payment — a "paid" mark applied to an existing order. Tips can route to a designated line in the POS. Card or wallet data never appears anywhere in this flow.
  • Status — location online/offline; per-item availability ("sold out" flags); per-order state, including "locked — open at a terminal". Orders pulled from the POS may carry the assigned waiter identifier, which Fooodo uses for staff attribution in reports.

Connectivity requirements

This is the part most evaluations turn on.

  • Every location's POS API must be reachable from Fooodo's cloud over the internet, via HTTPS, at a stable per-location URL. Fooodo's configuration holds an API endpoint and a location identifier for each restaurant — that endpoint must answer when Fooodo calls.
  • On-premise POS: the venue needs a reliable broadband connection, and the POS API must be exposed to Fooodo in a secured way — through your vendor cloud gateway, a VPN tunnel, or a hardened reverse proxy at the venue. Which mechanism is agreed during scoping; "the POS is only reachable from the local network" is the single most common gap.
  • Cloud POS: a server-to-server (S2S) connection between Fooodo's cloud and your cloud API, with per-location credentials and identifiers.
  • Connection quality matters, not just existence. Order creation and mark-paid sit on the guest's checkout critical path, and the online/offline check runs every minute so Fooodo can flip the location to read-only the moment the POS becomes unreachable. A link that drops for a few minutes is handled gracefully; a link that flaps all day degrades the guest experience at that location, no matter how good the integration is.

The performance envelope

The reference deployment runs these cadences per location, around the clock during service:

What runsCadence
Location online/offline checkevery minute
Pull new orders opened at the POS terminalevery 4 minutes
Refresh in-progress order state (waiter edits, voids)every 2 minutes
Refresh menu-item availability ("sold out" flags)every 5 minutes
Full menu / category / price refreshdaily, pre-service

Your API should sustain this polling for every connected location concurrently, and the two critical-path writes — create order, mark paid — should complete in seconds. Writes that fail are retried on an exponential backoff schedule, so a momentary rejection is recoverable; a chronically slow endpoint is not.

Failure semantics Fooodo relies on

The integration is built to tolerate a POS being briefly unavailable, and it leans on the POS returning distinguishable errors:

  • "Order is locked / open at a terminal" must be tellable apart from a hard failure. The reference connector recognises specific lock error codes and responds by retrying on a short backoff (about five attempts over ~2.5 minutes) rather than erroring out. Mark-paid rejections retry on a slower schedule (~17 minutes) because a paid order is reconciling, not blocking service.
  • Unreachable POS flips the location to read-only automatically. The cached menu still loads for guests, new orders are blocked at checkout with a clear message, and queued updates drain when the POS comes back — no operator intervention.
  • Retried writes must be safe. Fooodo retries failed order submissions; during scoping we verify together that a retry after a timeout cannot double-create an order on your side.

Multi-location chains

Fooodo is built for chains. Each restaurant in a company carries its own POS endpoint, location identifier, and credentials — different locations can point at different POS instances — and, as further connectors are built, at different POS systems. Evaluate for the chain's worst-connected location, not its best.

Security

  • All connector traffic runs over HTTPS/TLS, with per-location credentials. The credential mechanics (API key, token, OAuth, mTLS) are agreed during scoping.
  • Card data never crosses the POS boundary. Payments run through Fooodo's separate payment service (Mollie — card, Apple Pay, Google Pay); your POS receives an order and later a "paid" mark, never payment instrument data. The integration adds no card-data flows to your POS.
  • Fooodo's broader security posture — encryption, sub-processors, GDPR — is documented at fooodo.com/security.

Environments and testing

  • A test instance of your POS is expected. Fooodo's staging environment runs against your test environment; production traffic never touches it.
  • Mock mode lets early development run against the Fooodo menu app with POS traffic mocked end-to-end — useful before any connectivity is in place.
  • Partners receive the integration repo — the full connector contract, with version pinning — during onboarding.

Evaluation checklist

For your effort estimate, the work on your side typically concentrates in four places: closing any gaps against the required operations; exposing the API per location (see Connectivity); issuing per-location identifiers and credentials; and standing up a test environment.

If you can answer yes to these, the integration is very likely feasible:

  1. Does your POS expose an API covering the required operations above — menu read, order create, appending items to an already-open order, mark paid, location status?
  2. Can that API be made reachable from the internet over HTTPS for every location — vendor cloud, S2S, VPN, or secured proxy?
  3. Does each location have a stable identifier and credentials?
  4. Does the API return distinguishable errors for "order locked at a terminal" vs hard failures?
  5. Can it sustain per-minute polling per location, and complete order writes in seconds?
  6. Is there a test environment Fooodo's staging can run against?
  7. Do orders created via the API behave exactly like terminal orders in the kitchen (printing, KDS, reports)?
  8. Can a retried order-create after a timeout be made safe against double-creation — an idempotency key, or a way to check whether the order already exists?

A "no" or "unsure" on any of these is exactly what the scoping conversation is for — several have more than one viable answer.

From evaluation to a live connector

  1. Evaluation — your team reviews this guide, fills the checklist, and we compare notes. Usually triggered by a shared restaurant customer.
  2. Scoping — a working session mapping your API to the connector contract; gaps get options. Fooodo scopes and quotes its connector build per-customer, when a chain commits; the work needed on your side is sized in the same conversation, alongside the commercial arrangement. Useful to have ready: your API documentation, a test-environment plan, per-location identifiers, and a technical contact on your side.
  3. Build and test — development starts in mock mode, then moves to your test environment against Fooodo staging.
  4. Pilot and rollout — one live location first, then the chain.

To start: send your checklist answers and a rough effort estimate for your side to partners@fooodo.com, or use the developer form at fooodo.com/developers. The build-level view — the integration repo with the full connector contract — is handed over during onboarding.

On this page