> ## Documentation Index
> Fetch the complete documentation index at: https://docs.loyalty.xeniamoments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Open points

> Everything still unresolved, with an owner, REKOM's proposal where there is one, and the milestone it blocks.

<Note>
  "Needed before" uses three milestones: **Contract** (joint sign-off of the API
  contract), **Phase 1 live** (first venue with lookup), **Phase 2 live** (first venue
  with discounts).
</Note>

## Owned by OnlinePOS

| # | Point | REKOM proposal | Needed before |
| - | - | - | - |
| O1 | **Timeout and retry numbers** for the basket call, inside the BAXI prepurchase window. | 500 ms per attempt, one connect-only retry, hard cap 3 s; REKOM targets p95 ≤ 150 ms / p99 ≤ 250 ms. Joint measurement on staging with `Server-Timing`. | Contract |
| O2 | **Discount code value.** The exact predefined, semantic string for the catch-all third-party-loyalty discount type (`lineDiscountCode`), and how POS maps it to its note line and discount categorisation. | `loyalty`, one string for amount and percentage discounts. | Contract |
| O3 | **Meta attributes beyond the GUID.** The GUID is exposed as a meta attribute on the order (agreed after 7 Oct). Can the loyalty ID and the order loyalty status be stored as meta attributes too, and is the Phase 1 tag readable via REST? Can the transaction list be filtered by loyalty ID? | Store `loyaltyId` and loyalty status as meta attributes next to the GUID; REKOM only requires the GUID. | Phase 1 live (loyalty ID), Phase 2 live (status) |
| O4 | **Swapping existing discounts.** Confirm that OnlinePOS applies the returned basket as-is when REKOM has replaced or removed a staff discount, a product price discount or an order discount, and that no POS-side combination rule is involved (6 Oct: "REKOM follows POS's rules for combining discounts"). | The logic is REKOM's: keep the existing discount, or swap it for a larger loyalty discount. OnlinePOS validates arithmetic and product identity only. | Contract |
| O5 | **Product identity across venues**: is `productMasterId` reliable for the same product in different venues, or should REKOM key on EAN or per-venue IDs? | Send all three on each line; REKOM keys on `productMasterId` when present, else EAN, else venue `productId`. | Contract |
| O6 | **Split payments, tabs, partial card payments.** | Loyalty runs only when a single card payment settles the full basket; otherwise `not_applicable`. | Contract |
| O7 | **Webhook registration mechanics**: what is registrable, per venue or per partner, event names, where the secret is entered. | One base URL and one secret per environment per partner, with REKOM able to update the secret itself; per-venue activation in Backoffice. | Phase 2 live |
| O8 | **Money unit**: confirm integer minor units in the loyalty payloads (the REST API uses decimal strings). | Integer minor units + `currency`. | Contract |
| O9 | **Clocks**: NTP on Windows POS hosts; timezone semantics of the REST API `datetime` fields. | RFC 3339 with offset in loyalty payloads; signatures ±300 s. | Contract |
| O10 | **Limits**: 200 lines, 256 KB body, 50 rps sustained — acceptable? Egress IPs for allowlisting? | As stated in [Configuration and security](/architecture/configuration-and-security#limits). | Contract |
| O11 | **Basket object format and names.** OnlinePOS stated (6 Oct) that POS/mPOS define the order object. Every field name, enum value, header and structure in this document and the draft OpenAPI is directional. | OnlinePOS shares its default order object and webhook conventions; REKOM adopts them and maps the information in this document onto them. | Contract |
| O12 | **Legal-discount flag per line.** Confirm that `noDiscount` is populated from the product's `no_discount` setting on every line, including option lines, and whether any legal restriction exists that the flag does not cover. REKOM needs it to split order-level benefits correctly (3 Sep 2026). | Flags as drafted, mandatory on every line; `400` if missing. | Contract |
| O13 | **Added and split lines.** For lines REKOM adds: does OnlinePOS take `unitPrice` from the response or re-price from its own price list? Any convention for new `lineId`s? | OnlinePOS re-prices added lines from the venue price list and rejects a mismatch; REKOM prefixes new ids with `rk-`. | Contract |

## Owned by OnlinePOS and Nexi

| # | Point | REKOM proposal | Needed before |
| - | - | - | - |
| ON1 | **Amount reduction after the first tap via BAXI on Windows**: the guest approves the full original amount on the first tap. Confirm the prepurchase timing for seamlessly reducing it when membership benefits apply, without another tap or approval, and how long that window is. Otherwise the original amount continues. | None; this bounds O1. | Contract |
| ON2 | **Token key hand-over for `registerstore`.** Nexi has confirmed (Oct 2026) that enrollment needs a token key, that REKOM owns it and fetches it from the Nexi Engage API, and that enrollment still goes through the terminal via the ECR. Open: whether the key is one-time or reusable (and whether the every-startup `registerstore` must skip once enrolled), the hand-over to OnlinePOS, and the token-key API details. | REKOM fetches one key per BAX and enters it next to the Store ID in Backoffice; nothing in the terminal boot path depends on REKOM. | Phase 1 live |

## Owned by both

| # | Point | REKOM proposal | Needed before |
| - | - | - | - |
| B1 | **Same member in two open baskets** at once (two tills). | Benefits with a quantity limit are reserved at calculation and released on `cancelled`, supersession or expiry; first sale wins; the second calculation returns `unchanged` for the exhausted benefit. | Phase 2 live |
| B2 | **Test plan**: test venues, test BAX IDs as Nexi test stores, staging secrets, a joint latency run. | REKOM provides staging host, secret and a test member (test cards through Nexi's [test card frame](https://dev-engage.nexigroup.com/frame/index.html)); OnlinePOS provides a test venue and terminal. | Phase 1 live |

## Owned by Nexi

| # | Point | Note | Needed before |
| - | - | - | - |
| N1 | **`loyaltyId` format** as returned by `getasset` and Softpay: length, character set, stability. Confirm which attribute of the asset returned by the lookup OnlinePOS should pass on as the loyalty ID ([Nexi's example responses](https://dev-engage.nexigroup.com/getting-started/viking-example-response.html#loyalty-lookup)). | OnlinePOS treats it as an opaque string ≤ 64 chars until confirmed. | Contract |
| N2 | **Documentation hand-over and shared Slack channel.** Nexi's public [developer portal](https://dev-engage.nexigroup.com/) covers the Viking quick start and the Engage API references. Still needed from Nexi: the DAM / Baxi ECR integration notes the quick start refers to (not public), token validity and reuse rules, and the error-code list (212). | Promised for when work starts. | Phase 1 live |
| N3 | **DAM API-based enrollment** (≈ 2 months). | Parked; raised as a general improvement only. | — |

## REKOM-internal (for completeness)

| # | Point | Note |
| - | - | - |
| R1 | Guest card-enrolment channel (Nexi Engage API versus terminal action). | Does not affect OnlinePOS. |
| R2 | Consolidation to one BAX per venue. | **Resolved (Oct 2026):** REKOM runs one BAX per terminal (Nexi's "Model B"); several BAX per venue is the normal case. Enrollment keys on the BAX and attribution on the venue ID, so nothing in the design depends on it. |
| R3 | Hosts `loyalty.xeniamoments.com` / `loyalty-staging.xeniamoments.com` go live (DNS, certificates). | Marked TBC throughout. |

## Resolved in this document

| Was open | Resolution |
| - | - |
| `memberID` versus `loyaltyID` naming | "loyalty ID" in prose; the payload field name is directional and follows OnlinePOS's default. |
| "Three" versus four webhooks in the 4 Sep text | Two REKOM endpoints: `POST /v1/onlinepos/basket` and `POST /v1/onlinepos/sale`. |
| How `unchanged` is signalled | Explicit `unchanged` response with `reason`, no lines (7 Oct 2026). |
| Correlation between systems | Calculation GUID (7 Oct 2026), exposed as a meta attribute on the order in the REST API (after 7 Oct 2026). |
| Campaign ID provisioning | Not needed: loyalty discounts carry the predefined catch-all discount code instead of a campaign ID (after 7 Oct 2026); only the exact string is open (O2). |
| Venue attribution of orders | BAX number and terminal identifier are required in the order sent to REKOM (after 7 Oct 2026). |
| Store enrollment ownership | Option 1 (2 Sep 2026), token hand-over still open (ON2). |
| Several BAX numbers per venue | Expected: REKOM runs one BAX per terminal (Nexi's "Model B", Oct 2026); enrollment follows the BAX, orders carry the venue ID. See [Store enrollment](/architecture/store-enrollment#enrollment-follows-the-bax-never-the-terminal). |
| Who owns the store token key | REKOM, fetched from the Nexi Engage API (Nexi, Oct 2026). Hand-over to OnlinePOS still open (ON2). |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.