Every flow, every persona, both systems (FMS back-office and the guest webticket/app). Each screen below mirrors the live UI and quotes the exact Danish labels in grey, so nobody is in doubt about which control to use.
Festival back-office in FMS. Configures products, comps passes, gives Beats, generates login links, looks up guests.
staging-fms.livecloud.dk · Drift → DeltagereFront-line at a bar / booth / return point / cloakroom desk. Uses the scanner / POS app with a vendor key to scan guests and move Beats.
Scanner app · vendor API key (lcap_…)The attendee. Uses the native app or the webticket (browser) to hold a pass, spend Beats, get refunds and show QR codes.
App · …-webticket-…livecloud.dkThe festival wallet currency. 1 Beat = 1 DKK. Held on the guest’s profile; used for the store, bar, Pant deposits and Garderobe fees.
The paid entry credential — 75 kr, valid 1 year, one-time (not a subscription). Required for everyone; can be comped for free.
The app is the full native experience. The webticket is the same account in a browser — the fallback for guests without the app or without MitID.
The paid entry credential (75 kr / 1 year). It gates the entry credential (wallet / QR / wristband) and the buy-actions. LiveCloud sells it as its own product, so it is additive — it does not touch the festival’s ticket revenue. Everyone needs one; specific guests can be comped for free.
The “Festival Pass” product must exist for the summit (on staging it is seeded). If not, create it under /commerce/products as a PlatformAccess product, price 7500 (75.00 kr), meta.platform_access = { billing_interval:"one_time", duration_days:365 }, published to the guest-app channel.
In the app, the guest opens the Festival Pass and pays the 75 kr with a card.
The pass is granted for one year.
Entry credential + buy-actions unlock automatically.
Drift → Deltagere, open the guest.
Handlinger → Giv gratis festivalpas.
Type a reason in Årsag (required, written to the audit log), then confirm.
Toast: “Gratis festivalpas tildelt.” A comped pass is identical to a paid one at the gate.
Gate & renewal (guest, app): without an active pass, the entry credential and buy-actions are blocked (the block only triggers on a definite “no pass” — network hiccups fail open, so a guest is never wrongly locked out). Near expiry the guest gets a one-tap renewal prompt (it is one-time, not an auto-charging subscription). Repeating the comp on the same guest is safe — it returns the existing pass, never a duplicate.
Some guests have no MitID (e.g. a foreign attendee an admin imported tickets for) and cannot log in normally. The operator generates a one-time link; the guest opens it and lands signed into the webticket — no MitID, no password.
Open the guest → Handlinger → Generér login-link.
A dialog shows a QR and the link. Let the guest scan the QR, or copy the link and send it.
It shows when it expires, e.g. “Udløber 05. juli 2026 kl. 00.46.”
Click Luk.
The link works once, then expires (24 h).
The guest opens the link on their phone — tap it, or scan the QR from your screen with the camera.
The webticket shows a brief “Logger dig ind…” screen while it validates the one-time token.
Automatic — nothing to type.
They land signed in on their tickets and wallet.
Done. The link is now used up.
If it doesn’t work: a used/expired link shows a short “link is invalid or expired” message with a route back to normal login — just generate a fresh one.
Not live yet: the webticket redemption page is on the b2b develop branch but not on the webticket’s staging release, so a link currently returns 404 until that promotion is deployed.
Beats is the festival wallet currency (1 Beat = 1 DKK). Guests fund it, then spend it on the store, bar, Pant deposits and Garderobe fees. Operators can gift or deduct Beats by hand.
Open the guest → Handlinger → Udsted produkt.
Pick a Beats amount in Produkt (e.g. 100 Beats).
Under Betalingsmetode choose Gratis (gave) to gift it, or Træk fra beats to deduct.
Add a reason → Udsted produkt.
Toast: “Product given to attendee.” The Credits field updates at once (e.g. 100 Beats).
Guest side: the guest tops up with a card in the app, and sees the balance in the app or webticket wallet. When paying an order with Beats, the system charges the correct amount (the øre→Beats conversion is applied — a 20 kr item costs 20 Beats, not 2000).
A Pant item (e.g. a reusable cup) carries a refundable Beats deposit. The guest pays it at purchase and gets it back when they return the item to staff. Net wallet change over buy + return is zero.
A Pant product must exist — a Deposit product with meta.pant.deposit_amount in Beats (seeded on staging: Genbrugskrus = 20 Beats). The return scanner needs a vendor API key: /commerce/vendors → open the vendor → create an API-nøgle, put the lcap_… key in that vendor’s scanner.
The guest buys the item in the app; the deposit is charged from their Beats wallet and tracked as outstanding.
An operator can also do it: Ordrer → opret the item, then Træk fra wallet (charge-wallet).
At the return point, the guest opens Min pant and shows the QR.
Staff scan the guest and confirm the return in the scanner app.
The deposit is refunded to the guest’s Beats wallet (e.g. +20 Beats) and the item drops off the outstanding list.
Guardrails (already verified): scanning the same item twice refunds nothing the second time (“no outstanding deposit”). A partial return (e.g. 2 of 3) leaves the rest outstanding. Requesting more than is outstanding refunds only what is owed — never more.
A cloakroom rental fee in Beats, charged when staff hang the guest’s coat and bind a hanger to them. Fee-only — not refunded at pickup (it is a rental, not a deposit).
A Garderobe product must exist — a Rental product with meta.garderobe.rental_fee in Beats (seeded on staging: 30 Beats). Same vendor API key as Pant. Precondition: the guest must already hold enough Beats (see Guide 3) — the fee is charged live at bind.
Staff scan the guest and the hanger in the scanner app.
The fee is charged (e.g. −30 Beats) and the hanger is bound to the guest.
At pickup, staff scan the hanger to release it.
Hanger freed, no refund. The guest keeps the difference of their balance; the rental fee stays spent.
Guardrails (already verified): a guest with too few Beats is declined with no charge and no hanger bound. Binding a hanger that is already in use is blocked (“hanger in use”) with no second charge. Releasing an already-released or unknown hanger is a safe no-op. Release never refunds.
The behaviours below are built in and were verified on staging. Staff and operators do not need to do anything special — this is what the system guarantees if a scan or click is repeated or mistaken.
| Flow | If this happens… | The system… |
|---|---|---|
| PANT Double return | Same item scanned for return twice. | Refunds the deposit once. The second scan refunds 0 (“no outstanding deposit”). |
| PANT Over-quantity | Return more than is outstanding. | Refunds only what is owed — never over-refunds. |
| GARDEROBE Insufficient Beats | Guest can’t cover the fee at bind. | Declines with no charge and no hanger bound (nothing partial). |
| GARDEROBE Double-bind | Same hanger bound twice (even racing). | One charge only; the second is blocked (“hanger in use”). |
| GARDEROBE Re-release | Release a hanger already released / unknown. | Safe no-op, no error, no wallet change. |
| PASS Repeat comp | Comp the same guest twice. | Returns the existing pass — never a duplicate. |
| BEATS Pay with Beats | Guest pays an order with Beats. | Charges the correct amount — a 20 kr item costs 20 Beats (the øre→Beats conversion is applied). |