Skip to main content

Versioning and Changelog

Read first: Overview & Concepts · General Requirements

This page is the version story for the In-Store Loyalty API: how the protocol is versioned, which capability arrived in which version, what changed at each step, and how to migrate an existing integration forward. New integrations are recommended to build on version 1.5 or later — the latest is 1.7, and the rest of this document set describes it. Versions below 1.5 are deprecated: integrations built on them keep working for backward compatibility, but these versions are no longer part of the specification or this documentation set. Field-level detail for the supported versions lives in the In-Store Loyalty API specification.

1. How versioning works

The protocol version is part of every URL path: POST {baseUrl}/qr-code/1.7, POST {baseUrl}/order-closed/1.7, and so on. The pattern is {baseUrl}/{operation}/{version}. There is no version header and no content negotiation — the path is the version selector.

The OpenAPI specification describes the supported versions 1.5 through 1.7 as distinct paths — all four operation families (one-time-salt, qr-code, order-closed, refund) are present at each supported version. Deprecated paths (below 1.5) are not part of the spec; this Markdown describes only 1.7.

Which version an outlet uses is set in its configuration, not chosen per call: the sales-outlet config carries an apiVersion value (alongside fields including apiUrl, establishmentId, the establishment password, and the scan flow), and your integration calls the matching versioned path. New outlets are provisioned for 1.7. See Kiosk and POS Configuration for the full config contract.

Note: Use the same version on every operation within one order. The version of order-closed and refund must match the version used for the qr-code validation that opened the order — mixing versions on a single order is not supported.

2. Capability × version matrix

Each row is a vendor-visible capability; each column a supported version. "added" marks the version that introduced the capability; "available" marks later versions where it remains in force. A blank cell means the capability does not exist in that version. Deprecated versions (below 1.5) are not shown.

Capability1.51.61.7
QR-code validation (qr-code)availableavailableavailable
SHA-256 AuthorizationToken authavailableavailableavailable
Structured messages[] with numeric codeavailableavailableavailable
payment objectavailableavailableavailable
hasEverRewardedPoints in responseavailableavailableavailable
maxPointsPercent in responseavailableavailableavailable
customerEmail in responseaddedavailableavailable
Structured modifiers + value/fixedPrice discountsaddedavailableavailable
Required total (qr-code); item price expectedaddedavailableavailable
phone number-based flow (phoneNumber et al.)addedavailable
customerTier + customerPointsBalanceadded
publicClientId lookupadded

3. Per-version changelog

Concise, vendor-facing deltas. Each entry states what a vendor would notice on the wire; field-level detail lives in the spec.

  • 1.7 (latest) — Added customer tier name (customerTier) and points balance (customerPointsBalance) to the qr-code response customer block (both nullable, best-effort enrichment), and a third identification method: publicClientId lookup. Additive and non-breaking over 1.6.
  • 1.6 — Added the phone number-based flow: identify or register a customer by phoneNumber instead of a QR code — the customer enters their number on the self-service kiosk, or the cashier enters it at the cash register / POS terminal — with optional clientName and subscribedToPushNotifications. The same fields appear on order-closed.
  • 1.5 — Restructured the order model: modifiers changed from string arrays to objects (itemId, title, price, quantity); discounts moved to a single value field with a new fixedPrice type; total became required on the qr-code request, and item title/price are expected on qr-code menu items per the migration contract. Also added customer/customerEmail to the qr-code response (exposed only when the outlet has the additional-customer-info feature enabled).
  • 1.0–1.4 (deprecated) — legacy versions predating the 1.5 order-model restructure; versions 1.0–1.3 additionally use the legacy MD5 Signature auth scheme. They are no longer part of the specification or this documentation set; integrations built on them keep working for backward compatibility. To move to a supported version, see Section 4.1.

4. Migration guides

Each guide covers moving to the named version. Apply them cumulatively if you skip versions — e.g. moving from a deprecated version to 1.7 means doing 4.1, 4.2, and 4.3 in order.

4.1 From a deprecated version (below 1.5) — to 1.5

Versions below 1.5 are deprecated; moving off them means two changes — authentication and the order-model structure.

Authentication. Versions 1.0–1.3 send a Signature header equal to MD5(requestBody + apiPrivateKey + salt), and the server signs its response with the same scheme. From 1.4 on, send an AuthorizationToken header equal to SHA256(apiPrivateKey + salt) (key first, request body excluded), and the response is unsigned.

  1. Replace the Signature header with AuthorizationToken (keep SaltId, which is unchanged — it is sent on both legacy and current requests).
  2. Compute the token as SHA256(apiPrivateKey + salt), lowercase hex — the request body is no longer part of the hash.
  3. Stop verifying the response Signature header; responses are not signed anymore.
  4. Start handling HTTP 400 validation errors: a JSON object mapping each invalid field's JSON-Pointer path to a reason.

The token mechanics are detailed in the QR Code Loyalty Guide.

Order model. 1.5 reshapes the order model. The change is in field structure, not new operations.

Deprecated (pre-1.5) shape1.5+ shape
discount: type (percent/amount) + percent/amount fielddiscount: type (percent/amount/fixedPrice) + single value field
modifiers: array of strings (["EXTRA_CHEESE"])modifiers: array of objects ({itemId, title, price, quantity})
qr-code menu item: title/price optional, no totalqr-code menu item: title/price expected (per migration contract); request total required

To migrate: convert every discount's percent/amount field to a single value (e.g. {"type":"percent","percent":10}{"type":"percent","value":10}); convert each modifier string into an object with itemId, title, price, quantity; add price to every order item; and add total to the qr-code request. The new fixedPrice discount type is optional — use it only if needed.

Note: The OpenAPI MenuItem.required set is [itemId, quantity] — item title and price are not flagged required by the machine schema. Their requiredness at 1.5+ comes from the migration business contract and server-side validation, not the OpenAPI required list. Sending them is always safe. Warning: The value/fixedPrice discount shape and modifier objects apply to both qr-code and order-closed. Update the order composition in both requests, or order-closed will fail schema validation.

4.2 To 1.6 — phone number-based flow

1.6 adds the phone number-based flow and is otherwise unchanged from 1.5 on the wire for existing QR-code traffic — your QR validation keeps working as-is. To adopt the new capability:

  1. On qr-code, send phoneNumber (international format) instead of qrCode, optionally with clientName and subscribedToPushNotifications — the customer enters their number on the self-service kiosk, or the cashier enters it at the cash register / POS terminal.
  2. Echo the same phoneNumber, clientName, and subscribedToPushNotifications on order-closed for that order.

Full implementation is in the Phone Number Guide. Migrating from a deprecated version requires doing 4.1 first.

4.3 To 1.7 — tier, balance, and publicClientId

1.7 is additive and non-breaking over 1.6. A 1.6 client can move to the /1.7 paths with no request changes and will simply start receiving two extra response fields. To use the new features:

  1. Read customer.customerTier (tier name, e.g. "Gold") and customer.customerPointsBalance (points balance) from the qr-code response when present, and surface them at the point of payment.
  2. Optionally, identify a customer by publicClientId instead of qrCode/phoneNumber.

Warning: customerTier and customerPointsBalance are best-effort enrichment and may be null in a successful (accepted: true) response if the backing lookup is unavailable. Treat them as optional display data; never gate the flow on their presence. Note: When more than one identifier is sent, the in-store API resolves them in priority order qrCodephoneNumberpublicClientId; if none is sent, the request is rejected.

5. Support and deprecation policy

  • Versions below 1.5 are deprecated. Integrations built on the 1.01.4 paths keep working for backward compatibility, but these versions have been removed from the specification and this documentation set. To move to a supported version, see Section 4.1.
  • New integrations are recommended to build on 1.5 or later. 1.7 is the latest version, and this documentation set describes it.
  • The legacy Integration Server XML protocol is out of scope. The older session-based in-store protocol ("Фабрика Лояльности" / Universal Protocol) is a separate, deprecated product and is not documented here; the In-Store Loyalty API is the current in-store API.

Note: No end-of-life dates are published for any version of the in-store API. If LoyaltyPlant schedules the retirement of a legacy version for your integration, it is communicated through your integration contact, not through this document.


Next: Message & Error Codes →