Skip to main content
Agreed. The basket call is synchronous (REKOM request 31 Aug 2026, OnlinePOS acceptance 4 Sep 2026). There is no basketId, no polling and no callback. The checkout waits on the REKOM backend’s response. If the response does not arrive in time or is invalid, the sale proceeds with the original basket, without a new card approval, and the order’s loyalty status is set to failed. The sale itself completes normally.
Directional. Field names, enum values, headers and JSON structures on this page show which information is exchanged, not the final names. None of them has been aligned with OnlinePOS yet. REKOM will adopt whatever OnlinePOS has by default for the order object and its webhooks, and does not require any of these specific names.

Sequence

1

Card payment starts

Staff press the normal card-payment button. The terminal (BAXI/Viking) or Softpay performs the Nexi Engage lookup as part of the prepurchase step and returns a loyalty ID, or nothing. See Member identification.
2

POS generates the calculation GUID

POS/mPOS generate a GUID per basket calculation (calculationId), send it to the REKOM backend with the basket, store it on the order and expose it through the REST API as a meta attribute (agreed 7 Oct 2026; meta attribute mechanism agreed after 7 Oct). The GUID is the only correlation key the two sides need.
3

OnlinePOS backend calls the REKOM backend

POST /v1/onlinepos/basket with the loyalty ID, the full basket, the context (venue, BAX number, terminal, clerk, channel) and the GUID. The basket is OnlinePOS’s own object exactly as OnlinePOS has it, including the discounts already on it; REKOM returns the same object, modified. The BAX number and the terminal identifier are required so REKOM can attribute every order to a venue and a till (agreed after 7 Oct 2026). Idempotency-Key equals the GUID. The call is signed; see Configuration and security.
4

REKOM backend answers synchronously

One of three outcomes, always HTTP 200: applied with the full basket, unchanged with a reason, or member_not_found. Anything else (4xx, 5xx, timeout, malformed body) is a failure.
5

OnlinePOS validates and swaps the basket

OnlinePOS checks schema and arithmetic identities only (see Basket rules → Validation). On success the POS replaces its basket with the returned one. On any failure it keeps the original basket.
6

Single approval on the final amount

The terminal authorises the final amount once: either the original amount or the discounted one. The guest, who tapped once at step 1, is not asked to do anything else. BAXI prepurchase is used as it is today; the integration requires no change to the payment flow (agreed 6 Oct 2026).
7

Post-sale event

After the transaction is finalised, the OnlinePOS backend sends exactly one POST /v1/onlinepos/sale for the GUID. See Post-sale and reconciliation.

Latency contract

Proposed — for OnlinePOS confirmation. The numbers below are REKOM’s proposal. They have to fit inside the window the BAXI prepurchase step gives the POS between card read and authorisation, which OnlinePOS and Nexi own (see open points).

Proposed POS client behaviour

The V1 text (“retries up to three times with the same idempotency key, within an agreed overall maximum timeout”) is superseded by the proposal above because three sequential attempts cannot fit the payment window.

Fallback

In every row the guest approves exactly once, on whatever amount the POS ends up with. Staff are not asked anything.

Order loyalty status

OnlinePOS marks each order with one loyalty status (agreed 12 Aug 2026; unchanged kept through the no-change response, 7 Oct 2026). The status describes the loyalty step only and never the sale: an order with loyalty status failed is a completed, paid sale with the original basket.

The no-change response

When the member is known but no benefit applies, the REKOM backend returns status unchanged with a machine-readable reason and no lines (agreed 7 Oct 2026). The POS keeps its basket untouched. Reasons are informational for support and never shown to the guest: Invariant: a response with status applied always changes the basket in at least one way (a discount, an order discount, a price update, an added, removed or split line). If the calculation changes nothing, the REKOM backend returns unchanged.

The calculation GUID

Idempotency

All calls carry an idempotency key / request ID and retries never create duplicates or double discounts (agreed 12 Aug 2026).
  • The REKOM backend stores the response for each Idempotency-Key for 24 hours. A repeat with the same key and the same body gets the stored response.
  • The same key with a different body is answered 409 idempotency_conflict. The POS treats this as failed; it indicates a POS bug, not a transient fault.
  • A new basket calculation always gets a new GUID (below).

Basket change after calculation

Proposed — for OnlinePOS confirmation.
If the basket changes after a calculation but before authorisation (staff add a drink, void a line), the POS:
  1. generates a new GUID,
  2. calls POST /v1/onlinepos/basket again with the changed basket and supersedesCalculationId set to the previous GUID,
  3. reuses the loyaltyId already resolved. The guest does not tap again.
The REKOM backend releases anything reserved for the superseded calculation and sends no sale event expectation for it. The POS sends the sale event for the GUID that was actually finalised; the superseded one needs no event. If the payment is abandoned after a calculation, the POS sends a sale event with status cancelled for the last GUID. Calculations that receive neither a sale event nor a superseding calculation expire after 30 minutes on REKOM’s side and are treated as abandoned. A late sale event for an expired calculation is still accepted and reconciled.

What the call never does

  • Ask the guest or staff anything, or wait for input.
  • Reserve, authorise or in any way touch the payment.
  • Depend on a previous call: every request contains the full basket.
  • Return VAT, or add a product that does not exist on the venue.