Skip to main content

Data Models

This page describes the data structures used in the Storefront API.

Basket

The basket represents the shopping cart state.

interface Basket {
items: LineItem[];
promoCode: string | null;
stage: BasketStage;
}

Properties

PropertyTypeDescription
itemsLineItem[]Array of line items in the basket
promoCodestring | nullThe currently applied promotional code
stageBasketStageThe current stage of the basket

BasketStage

ValueDescription
BasketThe basket is active and accepts modifications
SettledThe order has been completed; the basket can no longer be modified

Product

A product represents a voucher that can be added to the basket. Products are retrieved using the GetVouchers method.

interface Product {
id: string;
catalogueId: string;
name: string;
venueName: string | null;
price: Money;
isPrivate: boolean;
limitedAvailability: unknown | null;
marketingDescription: string;
detailedDescription: string;
images: string[];
parentPath: string[];
tags: string[];
terms: string;
validity: Validity;
version: number;
reservationEmail: string;
reservationPhone: string;
reservationWebsite: string | null;
reservationInstructions: string | null;
isActive: boolean;
}

// Validity can be either month-based or date-based
type Validity = MonthBasedValidity | DateBasedValidity;

interface MonthBasedValidity {
validMonths: number;
}

interface DateBasedValidity {
startDate: string; // ISO 8601 date string
endDate: string; // ISO 8601 date string
}

Validity

The validity field can have two different formats:

Month-based validity - The voucher is valid for a number of months from the purchase date:

{
"validity": {
"validMonths": 12
}
}

Date-based validity - The voucher is valid between specific dates:

{
"validity": {
"startDate": "2024-04-02T00:00:00Z",
"endDate": "2025-04-02T00:00:00Z"
}
}

Properties

PropertyTypeDescription
idstringUnique product identifier (UUID) - use this for AddItem
catalogueIdstringThe catalogue this product belongs to
namestringDisplay name of the product
venueNamestring | nullOptional venue name
priceMoneyThe product price
isPrivatebooleanWhether the product is private
limitedAvailabilityunknownAvailability constraints, if any
marketingDescriptionstringShort description for marketing purposes
detailedDescriptionstringFull product description
imagesstring[]Array of image URLs
parentPathstring[]Category hierarchy (array of UUIDs)
tagsstring[]Product tags for filtering/categorization
termsstringTerms and conditions (HTML)
validityValidityVoucher validity period
versionnumberProduct version number
reservationEmailstringEmail for reservations
reservationPhonestringPhone number for reservations
reservationWebsitestring | nullWebsite for reservations
reservationInstructionsstring | nullSpecial reservation instructions
isActivebooleanWhether the product is currently available

Example

// Format validity for display
function formatValidity(validity) {
if (validity.validMonths) {
return "Valid for " + validity.validMonths + " months";
}

if (validity.startDate && validity.endDate) {
const start = new Date(validity.startDate);
const end = new Date(validity.endDate);
return "Valid from " + start.toLocaleDateString() + " to " + end.toLocaleDateString();
}

return "";
}

// Display a product card
function renderProductCard(product) {
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: product.price.currency,
});

return (
'<div class="product-card">' +
'<img src="' + product.images[0] + '" alt="' + product.name + '">' +
"<h3>" + product.name + "</h3>" +
"<p>" + product.marketingDescription + "</p>" +
'<p class="price">' + formatter.format(product.price.amount) + "</p>" +
'<p class="validity">' + formatValidity(product.validity) + "</p>" +
'<button data-product-id="' + product.id + '">Add to Cart</button>' +
"</div>"
);
}

LineItem

A line item represents a single product instance in the basket.

interface LineItem {
lineItemId: string;
productId: string;
productName: string;
retailPrice: Money;
quotedPrice: Money;
}

Properties

PropertyTypeDescription
lineItemIdstringUnique identifier for this line item (UUID)
productIdstringThe product identifier
productNamestringDisplay name of the product
retailPriceMoneyThe original price before discounts
quotedPriceMoneyThe price after applying discounts

Understanding Line Items

Each AddItem call creates a new line item. If a customer adds the same product twice, there will be two line items with the same productId but different lineItemId values.

To display quantity in your UI, group line items by productId:

function groupItemsByProduct(items) {
const grouped = {};

items.forEach((item) => {
if (!grouped[item.productId]) {
grouped[item.productId] = {
...item,
quantity: 0,
lineItemIds: [],
};
}
grouped[item.productId].quantity++;
grouped[item.productId].lineItemIds.push(item.lineItemId);
});

return Object.values(grouped);
}

Money

Represents a monetary value with currency.

interface Money {
amount: string | number;
currency: string;
}

Properties

PropertyTypeDescription
amountstring | numberThe monetary amount
currencystringISO 4217 currency code (e.g., "USD", "GBP", "EUR")
note

The amount field may be returned as a string in some responses (e.g., from GetVouchers). Always use parseFloat() or Number() when performing arithmetic operations.

Formatting Example

function formatPrice(money) {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: money.currency,
}).format(parseFloat(money.amount));
}

// Usage
const item = basket.items[0];
console.log(formatPrice(item.retailPrice)); // "$50.00"
console.log(formatPrice(item.quotedPrice)); // "$45.00"

Error

Represents an error returned by the SomethingHappened event.

interface Error {
errorCode: string;
message: string;
}

Properties

PropertyTypeDescription
errorCodestringMachine-readable error identifier
messagestringHuman-readable error description

Error Codes

CodeDescription
PromoCodeDoesntExistThe provided promotional code is invalid or has expired
UnavailableProductThe product is not available for purchase
OrderWasProcessedThe basket has already been settled and cannot be modified

ResumeShopping Response

The response returned by the ResumeShopping method.

interface ResumeShoppingResponse {
result: Basket | null;
}

Properties

PropertyTypeDescription
resultBasket | nullThe basket state, or null if no basket exists