curl --request POST \
--url https://loyalty.xeniamoments.com/v1/onlinepos/basket \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'OnlinePOS-Signature: <api-key>' \
--data @- <<EOF
{
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"loyaltyId": "rk_8f2a1c9d4b7e",
"currency": "DKK",
"requestedAt": "2026-10-08T21:14:03+02:00",
"context": {
"venueId": "123",
"cashRegisterId": "7",
"baxId": "601553",
"terminalId": "1001",
"clerkNumber": 12,
"channel": "pos"
},
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": false,
"noPercentageDiscount": false,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 13000
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": true,
"noPercentageDiscount": true,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 0,
"total": 19000
}
}
EOFimport requests
url = "https://loyalty.xeniamoments.com/v1/onlinepos/basket"
payload = {
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"loyaltyId": "rk_8f2a1c9d4b7e",
"currency": "DKK",
"requestedAt": "2026-10-08T21:14:03+02:00",
"context": {
"venueId": "123",
"cashRegisterId": "7",
"baxId": "601553",
"terminalId": "1001",
"clerkNumber": 12,
"channel": "pos"
},
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": False,
"noPercentageDiscount": False,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 13000
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": True,
"noPercentageDiscount": True,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 0,
"total": 19000
}
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"OnlinePOS-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'OnlinePOS-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
calculationId: '6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f',
loyaltyId: 'rk_8f2a1c9d4b7e',
currency: 'DKK',
requestedAt: '2026-10-08T21:14:03+02:00',
context: {
venueId: '123',
cashRegisterId: '7',
baxId: '601553',
terminalId: '1001',
clerkNumber: 12,
channel: 'pos'
},
lines: [
{
lineId: '1',
productId: '4711',
productMasterId: 'M-4711',
productGroupId: '12',
ean: '5700000000011',
name: 'Heidi\'s Lager 0,5 l',
quantity: 2,
unitPrice: 6500,
originalLinePrice: 13000,
noDiscount: false,
noPercentageDiscount: false,
existingLineDiscountType: 'none',
existingLineDiscountAmount: 0,
orderDiscountAllocation: [],
orderLinePrice: 13000
},
{
lineId: '2',
productId: '8120',
productGroupId: '40',
name: 'Cigarettes 20 pcs',
quantity: 1,
unitPrice: 6000,
originalLinePrice: 6000,
noDiscount: true,
noPercentageDiscount: true,
existingLineDiscountType: 'none',
existingLineDiscountAmount: 0,
orderDiscountAllocation: [],
orderLinePrice: 6000
}
],
orderDiscounts: [],
totals: {
originalTotal: 19000,
existingDiscountTotal: 0,
orderDiscountTotal: 0,
loyaltyDiscountTotal: 0,
total: 19000
}
})
};
fetch('https://loyalty.xeniamoments.com/v1/onlinepos/basket', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://loyalty.xeniamoments.com/v1/onlinepos/basket",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'calculationId' => '6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f',
'loyaltyId' => 'rk_8f2a1c9d4b7e',
'currency' => 'DKK',
'requestedAt' => '2026-10-08T21:14:03+02:00',
'context' => [
'venueId' => '123',
'cashRegisterId' => '7',
'baxId' => '601553',
'terminalId' => '1001',
'clerkNumber' => 12,
'channel' => 'pos'
],
'lines' => [
[
'lineId' => '1',
'productId' => '4711',
'productMasterId' => 'M-4711',
'productGroupId' => '12',
'ean' => '5700000000011',
'name' => 'Heidi\'s Lager 0,5 l',
'quantity' => 2,
'unitPrice' => 6500,
'originalLinePrice' => 13000,
'noDiscount' => false,
'noPercentageDiscount' => false,
'existingLineDiscountType' => 'none',
'existingLineDiscountAmount' => 0,
'orderDiscountAllocation' => [
],
'orderLinePrice' => 13000
],
[
'lineId' => '2',
'productId' => '8120',
'productGroupId' => '40',
'name' => 'Cigarettes 20 pcs',
'quantity' => 1,
'unitPrice' => 6000,
'originalLinePrice' => 6000,
'noDiscount' => true,
'noPercentageDiscount' => true,
'existingLineDiscountType' => 'none',
'existingLineDiscountAmount' => 0,
'orderDiscountAllocation' => [
],
'orderLinePrice' => 6000
]
],
'orderDiscounts' => [
],
'totals' => [
'originalTotal' => 19000,
'existingDiscountTotal' => 0,
'orderDiscountTotal' => 0,
'loyaltyDiscountTotal' => 0,
'total' => 19000
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"OnlinePOS-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://loyalty.xeniamoments.com/v1/onlinepos/basket"
payload := strings.NewReader("{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("OnlinePOS-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://loyalty.xeniamoments.com/v1/onlinepos/basket")
.header("Idempotency-Key", "<idempotency-key>")
.header("OnlinePOS-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://loyalty.xeniamoments.com/v1/onlinepos/basket")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["OnlinePOS-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}"
response = http.request(request)
puts response.read_body{
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"status": "applied",
"memberLabel": "REKOM Member",
"receiptFooterText": "Member benefits today: -26,00 kr.",
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": false,
"noPercentageDiscount": false,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"lineDiscountType": "percent",
"lineDiscountPercent": 20,
"lineDiscountAmount": 2600,
"lineDiscountText": "Members 20 %",
"showLineDiscountText": true,
"lineDiscountCode": "loyalty",
"orderLinePrice": 10400
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": true,
"noPercentageDiscount": true,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"lineDiscountType": "none",
"lineDiscountAmount": 0,
"showLineDiscountText": false,
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 2600,
"total": 16400
}
}Calculate loyalty basket
Called by the OnlinePOS backend once per basket calculation, after the Nexi Engage lookup returned a loyalty ID and before the amount is authorised.
The REKOM backend answers synchronously with one of three statuses, always HTTP 200:
applied— the full basket with loyalty discounts; the POS replaces its basket with it.unchanged— nothing applies; no lines returned; the POS keeps its basket.member_not_found— the loyalty ID is unknown to REKOM; the POS keeps its basket.
Any other HTTP status, a timeout, or a response that fails OnlinePOS’s arithmetic validation
means the POS keeps the original basket and sets the order’s loyalty status to failed;
the sale itself completes normally.
Target latency: p95 ≤ 150 ms, p99 ≤ 250 ms. Proposed POS timeout: 500 ms per attempt, one retry only on connection failure before the request was sent, hard cap 3 s.
Field names and structures are directional (see the API description).
curl --request POST \
--url https://loyalty.xeniamoments.com/v1/onlinepos/basket \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'OnlinePOS-Signature: <api-key>' \
--data @- <<EOF
{
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"loyaltyId": "rk_8f2a1c9d4b7e",
"currency": "DKK",
"requestedAt": "2026-10-08T21:14:03+02:00",
"context": {
"venueId": "123",
"cashRegisterId": "7",
"baxId": "601553",
"terminalId": "1001",
"clerkNumber": 12,
"channel": "pos"
},
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": false,
"noPercentageDiscount": false,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 13000
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": true,
"noPercentageDiscount": true,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 0,
"total": 19000
}
}
EOFimport requests
url = "https://loyalty.xeniamoments.com/v1/onlinepos/basket"
payload = {
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"loyaltyId": "rk_8f2a1c9d4b7e",
"currency": "DKK",
"requestedAt": "2026-10-08T21:14:03+02:00",
"context": {
"venueId": "123",
"cashRegisterId": "7",
"baxId": "601553",
"terminalId": "1001",
"clerkNumber": 12,
"channel": "pos"
},
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": False,
"noPercentageDiscount": False,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 13000
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": True,
"noPercentageDiscount": True,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 0,
"total": 19000
}
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"OnlinePOS-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
'OnlinePOS-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
calculationId: '6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f',
loyaltyId: 'rk_8f2a1c9d4b7e',
currency: 'DKK',
requestedAt: '2026-10-08T21:14:03+02:00',
context: {
venueId: '123',
cashRegisterId: '7',
baxId: '601553',
terminalId: '1001',
clerkNumber: 12,
channel: 'pos'
},
lines: [
{
lineId: '1',
productId: '4711',
productMasterId: 'M-4711',
productGroupId: '12',
ean: '5700000000011',
name: 'Heidi\'s Lager 0,5 l',
quantity: 2,
unitPrice: 6500,
originalLinePrice: 13000,
noDiscount: false,
noPercentageDiscount: false,
existingLineDiscountType: 'none',
existingLineDiscountAmount: 0,
orderDiscountAllocation: [],
orderLinePrice: 13000
},
{
lineId: '2',
productId: '8120',
productGroupId: '40',
name: 'Cigarettes 20 pcs',
quantity: 1,
unitPrice: 6000,
originalLinePrice: 6000,
noDiscount: true,
noPercentageDiscount: true,
existingLineDiscountType: 'none',
existingLineDiscountAmount: 0,
orderDiscountAllocation: [],
orderLinePrice: 6000
}
],
orderDiscounts: [],
totals: {
originalTotal: 19000,
existingDiscountTotal: 0,
orderDiscountTotal: 0,
loyaltyDiscountTotal: 0,
total: 19000
}
})
};
fetch('https://loyalty.xeniamoments.com/v1/onlinepos/basket', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://loyalty.xeniamoments.com/v1/onlinepos/basket",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'calculationId' => '6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f',
'loyaltyId' => 'rk_8f2a1c9d4b7e',
'currency' => 'DKK',
'requestedAt' => '2026-10-08T21:14:03+02:00',
'context' => [
'venueId' => '123',
'cashRegisterId' => '7',
'baxId' => '601553',
'terminalId' => '1001',
'clerkNumber' => 12,
'channel' => 'pos'
],
'lines' => [
[
'lineId' => '1',
'productId' => '4711',
'productMasterId' => 'M-4711',
'productGroupId' => '12',
'ean' => '5700000000011',
'name' => 'Heidi\'s Lager 0,5 l',
'quantity' => 2,
'unitPrice' => 6500,
'originalLinePrice' => 13000,
'noDiscount' => false,
'noPercentageDiscount' => false,
'existingLineDiscountType' => 'none',
'existingLineDiscountAmount' => 0,
'orderDiscountAllocation' => [
],
'orderLinePrice' => 13000
],
[
'lineId' => '2',
'productId' => '8120',
'productGroupId' => '40',
'name' => 'Cigarettes 20 pcs',
'quantity' => 1,
'unitPrice' => 6000,
'originalLinePrice' => 6000,
'noDiscount' => true,
'noPercentageDiscount' => true,
'existingLineDiscountType' => 'none',
'existingLineDiscountAmount' => 0,
'orderDiscountAllocation' => [
],
'orderLinePrice' => 6000
]
],
'orderDiscounts' => [
],
'totals' => [
'originalTotal' => 19000,
'existingDiscountTotal' => 0,
'orderDiscountTotal' => 0,
'loyaltyDiscountTotal' => 0,
'total' => 19000
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"OnlinePOS-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://loyalty.xeniamoments.com/v1/onlinepos/basket"
payload := strings.NewReader("{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("OnlinePOS-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://loyalty.xeniamoments.com/v1/onlinepos/basket")
.header("Idempotency-Key", "<idempotency-key>")
.header("OnlinePOS-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://loyalty.xeniamoments.com/v1/onlinepos/basket")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["OnlinePOS-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"calculationId\": \"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f\",\n \"loyaltyId\": \"rk_8f2a1c9d4b7e\",\n \"currency\": \"DKK\",\n \"requestedAt\": \"2026-10-08T21:14:03+02:00\",\n \"context\": {\n \"venueId\": \"123\",\n \"cashRegisterId\": \"7\",\n \"baxId\": \"601553\",\n \"terminalId\": \"1001\",\n \"clerkNumber\": 12,\n \"channel\": \"pos\"\n },\n \"lines\": [\n {\n \"lineId\": \"1\",\n \"productId\": \"4711\",\n \"productMasterId\": \"M-4711\",\n \"productGroupId\": \"12\",\n \"ean\": \"5700000000011\",\n \"name\": \"Heidi's Lager 0,5 l\",\n \"quantity\": 2,\n \"unitPrice\": 6500,\n \"originalLinePrice\": 13000,\n \"noDiscount\": false,\n \"noPercentageDiscount\": false,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 13000\n },\n {\n \"lineId\": \"2\",\n \"productId\": \"8120\",\n \"productGroupId\": \"40\",\n \"name\": \"Cigarettes 20 pcs\",\n \"quantity\": 1,\n \"unitPrice\": 6000,\n \"originalLinePrice\": 6000,\n \"noDiscount\": true,\n \"noPercentageDiscount\": true,\n \"existingLineDiscountType\": \"none\",\n \"existingLineDiscountAmount\": 0,\n \"orderDiscountAllocation\": [],\n \"orderLinePrice\": 6000\n }\n ],\n \"orderDiscounts\": [],\n \"totals\": {\n \"originalTotal\": 19000,\n \"existingDiscountTotal\": 0,\n \"orderDiscountTotal\": 0,\n \"loyaltyDiscountTotal\": 0,\n \"total\": 19000\n }\n}"
response = http.request(request)
puts response.read_body{
"calculationId": "6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f",
"status": "applied",
"memberLabel": "REKOM Member",
"receiptFooterText": "Member benefits today: -26,00 kr.",
"lines": [
{
"lineId": "1",
"productId": "4711",
"productMasterId": "M-4711",
"productGroupId": "12",
"ean": "5700000000011",
"name": "Heidi's Lager 0,5 l",
"quantity": 2,
"unitPrice": 6500,
"originalLinePrice": 13000,
"noDiscount": false,
"noPercentageDiscount": false,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"lineDiscountType": "percent",
"lineDiscountPercent": 20,
"lineDiscountAmount": 2600,
"lineDiscountText": "Members 20 %",
"showLineDiscountText": true,
"lineDiscountCode": "loyalty",
"orderLinePrice": 10400
},
{
"lineId": "2",
"productId": "8120",
"productGroupId": "40",
"name": "Cigarettes 20 pcs",
"quantity": 1,
"unitPrice": 6000,
"originalLinePrice": 6000,
"noDiscount": true,
"noPercentageDiscount": true,
"existingLineDiscountType": "none",
"existingLineDiscountAmount": 0,
"orderDiscountAllocation": [],
"lineDiscountType": "none",
"lineDiscountAmount": 0,
"showLineDiscountText": false,
"orderLinePrice": 6000
}
],
"orderDiscounts": [],
"totals": {
"originalTotal": 19000,
"existingDiscountTotal": 0,
"orderDiscountTotal": 0,
"loyaltyDiscountTotal": 2600,
"total": 16400
}
}Authorizations
HMAC-SHA256 request signature: t=<unix seconds>,v1=<hex> where
v1 = HMAC_SHA256(secret, "<t>.<raw body>"). Timestamp window ±300 s.
One secret per environment. No scheduled rotation; when a secret is swapped, old and new stay
active with an overlap so nothing is interrupted. See Configuration and security.
Headers
The calculationId. Same key with the same body replays the stored response; same key with a different body is rejected with 409.
Fresh UUID per HTTP attempt, echoed in the response for log correlation.
Body
GUID generated by POS/mPOS for this calculation. Also sent as Idempotency-Key and stored on the transaction.
"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f"
Opaque REKOM member identifier as returned by Nexi Engage (getasset / Softpay). Contains no PII.
Exact format pending Nexi confirmation; treat as an opaque string.
1 - 64"rk_8f2a1c9d4b7e"
ISO 4217 currency code.
^[A-Z]{3}$"DKK"
"NOK"
"SEK"
"EUR"
POS time of the request, RFC 3339 with offset.
"2026-10-08T21:14:03+02:00"
Where the basket is being sold. Field meanings mirror the OnlinePOS REST transaction API so reconciliation is a join.
baxId and cashRegisterId are required so REKOM can attribute every order to a venue and a till (agreed after 7 Oct 2026).
Show child attributes
Show child attributes
1 - 200 elementsShow child attributes
Show child attributes
Order-level discounts already applied by staff. Empty when none.
Show child attributes
Show child attributes
Basket totals in minor units. Identities: total = Σ orderLinePrice,
loyaltyDiscountTotal = Σ lineDiscountAmount, total ≥ 0.
Show child attributes
Show child attributes
Set when the basket changed after an earlier calculation; REKOM releases anything reserved for that GUID.
"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f"
Response
Calculation result. The status field says whether the basket changed.
Result of a calculation. status decides which fields are present:
applied:lines(kept lines echoed, untouched ones withlineDiscountType: none; removed lines omitted; split and added lines marked),orderDiscounts(staff ones echoed, loyalty ones added) andtotals. The basket differs from the request in at least one way.unchanged:reason; nolines, nototals.member_not_found: nothing else.
Lower-case UUID with hyphens (36 characters).
"6f1d2c3e-8a4b-4c5d-9e0f-1a2b3c4d5e6f"
applied, unchanged, member_not_found Present when status is unchanged. Informational; never shown to the guest. New values may be added.
no_applicable_benefits, all_lines_excluded, member_inactive, basket_too_small Optional label OnlinePOS may print on the receipt if it has a place for it.
40"REKOM Member"
Optional free text for the bottom of the receipt describing order-level benefits. Informational; not in reporting.
200"Member benefits today: -26,00 kr."
Present only when status is applied. The full basket after loyalty, including added and split lines and without removed ones.
Show child attributes
Show child attributes
Present only when status is applied. Existing order discounts as kept or changed by REKOM, plus any REKOM added.
Show child attributes
Show child attributes
Basket totals in minor units. Identities: total = Σ orderLinePrice,
loyaltyDiscountTotal = Σ lineDiscountAmount, total ≥ 0.
Show child attributes
Show child attributes