Skip to main content

Scope of changes in Phase 2

Agreed scope, unchanged from Version 1 §7 (28 Aug / 4 Sep 2026). Phase 2 keeps every operation Version 1 allowed; nothing has been removed. Where a row says “REKOM practice”, it describes how REKOM intends to use the operation, not a restriction on it.
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.

Line model (directional)

The request body is OnlinePOS’s own basket object, exactly as OnlinePOS has it, including the discounts already on it. REKOM modifies that object per its loyalty model and returns it; OnlinePOS applies what comes back. The tables below are REKOM’s illustration of the information in that object, grouped by who sets it.

Set by OnlinePOS (input)

Identity and quantity fields are echoed verbatim on every line REKOM keeps. The existing-discount fields are input: REKOM may change or clear them when it swaps in a loyalty discount.

Set by REKOM (only on applied)

Arithmetic identities

For every line:
For the basket:
Lines the REKOM backend does not change are returned exactly as received, with lineDiscountType: "none" and lineDiscountAmount: 0. A response with status applied changes the basket in at least one way (a discount, a price update, an added, removed or split line); if the calculation changes nothing, the response is unchanged.
Agreed 3 Sep 2026 (Google Doc comments on V1 §8). Order-level discounts are allowed, and REKOM does the splitting onto lines. OnlinePOS’s answer: to register revenue correctly, all order discounts have to be split on the separate lines, and because some products, cigarettes for example, are not legally allowed to be discounted, the partner must do that split correctly. OnlinePOS places order discounts visually at the bottom of the receipt, as it already does for discount campaigns.
For REKOM to do that split correctly, OnlinePOS has to tell it per line whether the product may legally be discounted. That is what the two flags are for, and why they are mandatory on every line. The names are directional; the information is what is required, under whatever name OnlinePOS already has for it.

Discount code

Agreed, follow-up after 7 Oct 2026. Loyalty discounts carry no campaign ID. Every loyalty discount instead carries a predefined, semantic string that identifies the catch-all third-party-loyalty discount type in POS (lineDiscountCode on lines, discountCode on order discounts). This is the “general system campaign for third-party loyalty” variant of the 6 Oct 2026 assumption: no per-venue campaign is created, and nothing is provisioned through the REST API.
Staff discounts that already exist on a line or order keep their campaign reference (existingLineDiscountCampaignId, orderDiscounts[].campaignId); that is OnlinePOS’s existing discount system and is untouched.

Receipt rules

Agreed 17 Aug, 3 Sep and 6 Oct 2026.
  • A loyalty line discount prints as a note line directly under the product, with the discount text and the monetary value shown separately. The product’s own receipt text is never changed.
  • No new print layouts. Note lines use the existing mechanism.
  • A discount is dedicated POS discount data, never a free-text product with price zero (3 Sep 2026).
  • Order-level discounts are shown at the bottom of the receipt, as OnlinePOS does for discount campaigns (3 Sep 2026), through a free-text field that is informational and not part of reporting (7 Oct 2026). REKOM may fill receiptFooterText (≤ 200 characters) for this, e.g. “Members 10 %: −13,00 kr.”
  • memberLabel (≤ 40 characters, e.g. “REKOM Member”) may be shown on the receipt header or footer if OnlinePOS has a place for it; otherwise ignored.
  • Nothing from the response is shown on the customer display or to staff before payment beyond the updated basket total, since the call runs during the payment motion.

Rounding

Proposed — for OnlinePOS confirmation.
The REKOM backend computes every amount. For a percentage discount on a line:
Rounding happens once per line, in minor units; order-discount allocations are rounded the same way, with the remainder on the largest eligible line. OnlinePOS does not recompute percentages; it validates the identities above using the integer amounts in the response. This avoids one-øre disagreements between the two systems.

Existing discounts: REKOM decides what is swapped

REKOM logic. The basket OnlinePOS sends includes the discounts already on it: a staff discount, a price discount on a specific product, an order discount. The REKOM backend decides, per line, what stays and what is swapped. If the loyalty programme unlocks a larger discount than the one already there, the guest gets the loyalty discount instead when the basket comes back; otherwise the existing discount stays and REKOM adds nothing. This logic is strictly REKOM’s. OnlinePOS simply receives the returned basket and applies it, which follows from the 7 Oct 2026 agreement that the returned basket is authoritative.
Consequences:
  • A returned line may carry a different existing discount than it was sent with, or none, because REKOM swapped it out. OnlinePOS’s validation therefore checks arithmetic and product identity, not that discount fields are unchanged.
  • A swapped-out staff discount no longer prints; the loyalty note line prints in its place. Nothing is printed twice for the same line.
  • Whether a benefit stacks on top of an existing discount or replaces it is a REKOM rule per benefit, not a POS setting. REKOM’s default is replace-if-larger.
  • The same applies to order discounts already on the basket: REKOM may keep, change or remove them and re-allocate accordingly.
  • If every eligible line already carries a better discount, the response is unchanged with reason all_lines_excluded.
Open — OnlinePOS to confirm (O4). OnlinePOS’s 6 Oct 2026 assumption said REKOM follows POS’s existing rules for combining discounts. REKOM’s reading is that the returned basket is applied as-is, including a replaced or removed staff discount, and that no POS-side combination rule is involved. OnlinePOS to confirm.

Flags

Validation in OnlinePOS

OnlinePOS validates the returned basket for (V1 §9, unchanged):
  1. Correct schema and the same calculationId as the request.
  2. Every productId exists on the venue, including added and split lines.
  3. Identity and quantity fields (lineId, productId, quantity, unitPrice, the flags) are unchanged on every line REKOM kept; split lines’ quantities add up to the original line. Discount fields may differ, because REKOM may have swapped an existing discount.
  4. lineDiscountCode / discountCode equals the agreed catch-all loyalty discount code wherever a loyalty discount is set.
  5. No loyalty discount, allocation or price reduction on a noDiscount line; no percentage discount on a noPercentageDiscount line.
  6. The sum of orderDiscountAllocationAmount per orderDiscountId equals the stated order discount.
  7. The per-line and basket identities above hold; all amounts are integers ≥ 0; the basket total equals the sum of orderLinePrice; total ≥ 0.
OnlinePOS does not validate REKOM’s business logic. A basket that fails validation is rejected: the original basket is used, the order’s loyalty status is set to failed (the sale itself completes), and the sale event carries failureReason: invalid_response.