Appearance
How-To Guides
Step-by-step guides for common merchant tasks in the Upvendo back office.
The back office has two navigation areas:
- The main sidebar (Transactions, Marketing, Menus, Inventory, Device Management, Content, and the Online / In-House channel sections).
- The Settings menu (Payment Profiles, Billing Profiles, Team, Locations, Receipts, Localizations, Branding, Domains, Activity Log, Compliance).
Some features are gated and only appear for certain plans, connected POS systems, or in test environments; those are noted below where relevant.
Setting Up Your Restaurant
How to Set Up a New Location
- Go to Settings → Locations.
- Click Add Location.
- Fill in the General section:
- Location name
- Phone number
- Fill in the Address section (with address autocomplete).
- Set the Operation Hours (see below).
- Set order behaviour, including the average prep time (average minutes to prepare an order).
- Click Save.
The location form is organised into sections: Profiles, General, Address, Operation Hours, Restricted Dates, and Order Behaviour.
Route: /settings/locations (list) and /settings/locations/:id (form). Evidence: src/navigation/settings/index.ts:40-45, src/views/settings/Locations/LocationForm.vue:47-71, src/views/settings/Locations/forms/LocationAndContactDetails.vue, src/views/settings/Locations/forms/LocationAddress.vue.
Next steps: Set up online ordering, connect a payment provider, and assign menus to devices.
How to Set Up Operation Hours
- Go to Settings → Locations → [Your Location].
- Scroll to Operation Hours.
- For each day:
- Toggle the day on if you are open.
- Set opening and closing times.
- Add multiple time ranges for the same day if needed (e.g. 11:00–14:00 and 17:00–22:00).
- Click Save.
The UI labels this section Operation Hours, not "Business Hours".
Evidence: src/views/settings/Locations/forms/LocationBusinessHours.vue, src/views/settings/Locations/LocationForm.vue:61.
Tip: Use Restricted Dates for holidays and special closures.
How to Add a Holiday Closure
- Go to Settings → Locations → [Your Location].
- Scroll to Restricted Dates.
- Click Add Date.
- Select a single date or a date range.
- Toggle Repeat every year for annual holidays (e.g. Christmas).
- Click Save.
Evidence: src/views/settings/Locations/forms/LocationRestrictedDates.vue (addDate(), yearly field, locations.restricted_dates.repeat_every_year).
Online Ordering Setup
Online Ordering lives under the Online channel section of the main sidebar, not under a separate "Pickup & Delivery" menu (that menu no longer exists).
Route: /online/online-ordering. Evidence: src/pages/online/online-ordering/index.vue:1-8, src/views/online/online-ordering/OnlineOrdering.vue.
How to Configure Online Ordering Fulfilment
- Go to Online → Online Ordering.
- Enable and configure Takeout (pickup) and/or Delivery, each with its own delay time.
- Set Accept orders until — choose Closing time or Closing time minus prep time.
- Save your changes.
There is no single "Enable Online Ordering" master toggle. Availability of online ordering is managed through the channel subscription (shown as subscription status chips), and each fulfilment method (Takeout, Delivery) is enabled individually.
Evidence: src/views/online/online-ordering/forms/OnlineOrdering.vue (takeout/delivery delay + enable toggles), src/views/online/online-ordering/forms/FullfilmentAndScheduling.vue (Accept-orders-until options).
How to Set Up Delivery
- Go to Online → Online Ordering.
- Enable Delivery.
- Open the Delivery Settings section.
- Choose a delivery region type:
- Postal Code: add specific postal codes (with optional per-postal-code fees).
- Radius: set a radius from the location.
- Distance: set a distance-based region.
- Choose a delivery fee model:
- Free delivery
- Charge a delivery fee for all orders
- Free delivery for orders over a certain amount
- Optionally enable a Minimum order amount and set the amount.
- Save your changes.
Evidence: src/views/online/online-ordering/forms/DeliverySettings.vue (region types Postal Code / Radius / Distance, fee models, minimum-order-amount toggle + amount).
How to Set Up Pickup
- Go to Online → Online Ordering.
- Enable Takeout and set the takeout delay (extra minutes added before orders are ready).
- Open the Pickup Settings section.
- Optionally enable Pickup instructions and set placeholder text.
- Optionally set a pickup transaction fee and/or pickup minimum order amount.
- Save your changes.
The pickup/takeout delay is set in the main Online Ordering section (alongside the delivery delay), while pickup instructions, fee, and minimum order amount live in the Pickup Settings section.
Evidence: src/views/online/online-ordering/forms/PickupSettings.vue, src/views/online/online-ordering/forms/OnlineOrdering.vue (takeout.delay).
How to Allow Scheduled Orders
- Go to Online → Online Ordering.
- Open the Fulfilment & Scheduling section.
- For Takeout:
- Enable scheduling for future days.
- Set Days in advance.
- For Delivery:
- Enable scheduling for future days.
- Set Days in advance.
- Save your changes.
Evidence: src/views/online/online-ordering/forms/FullfilmentAndScheduling.vue (schedule_order_for_future_days.takeout/delivery.enabled and .days_in_advance).
Menu Management
The Menus section of the sidebar contains: Menu Builder, Items, Modifier Groups, Reporting Categories, and (for MplusKassa / ShopCaisse / Lightspeed K-Series merchants) Tax Rates.
Evidence: src/navigation/vertical/index.ts:51-81,174-191.
How to Create a Menu Item
- Go to Menus → Items.
- Click Create and choose New Item.
- Fill in the item details:
- Name (required)
- Kitchen name (optional)
- PLU (required; can be auto-generated)
- Description (optional)
- Image (optional)
- Category
- Status and Price (price can be customised per channel)
- Optionally open the Product Specifications tab to set Allergens, Dietary preferences, Dietary supplements, Ingredients, calories, and a per-item order limit. Allergens and dietary information are chosen from predefined lists, not free-text fields.
- Click Save.
Route: /menus/items (list) and /menus/items/new-item (form). Evidence: src/views/items/Items.vue (Create → New Item), src/views/items/forms/ItemDetails.vue (name, PLU, description, image, category), src/views/items/forms/ItemRightColumn.vue (status, price, channels).
How to Add Modifier Groups to an Item
Modifier groups are created and configured on their own page, then assigned to items.
Step 1 — Create a modifier group:
- Go to Menus → Modifier Groups.
- Click Create.
- Fill in the basics: Name, optional POS name, optional Description.
- In Settings, configure:
- Selection type: Optional or Required.
- Allow multiple selections, and if enabled, the maximum number of selections.
- Optionally allow the same modifier to be chosen more than once.
- Add the individual modifiers (name and price).
- Save the group.
Step 2 — Assign the group to an item:
- Go to Menus → Items → [Your Item].
- Open the Modifier Groups tab.
- Click Add Modifier Group and select an existing group.
- Save the item.
The selection limit is configured as Allow multiple selections + maximum selections (a single max), not a separate "min/max" pair, and these settings are group-level rather than per-option.
Route: /menus/modifiers (list) and /menus/modifiers/new-modifier (form). Evidence: src/navigation/vertical/index.ts:68-73, src/views/modifiers/forms/ModifierBasicInformation.vue, src/views/modifiers/forms/ModifierSetting.vue (is_mandatory, allow_select_more_than_one, max_selected), src/views/items/forms/ItemModifierGroups.vue (Add Modifier Group on the item).
How to Set Up Variants (e.g. Size/Color)
Variant groups are created from the Items page, not from a dedicated "Variant Groups" menu item.
- Go to Menus → Items.
- Click Create and choose New Variant Group.
- Set the variant group name and add its variations.
- Configure modifier groups for the variant group if needed.
- Save.
Variant groups are available only in test environments or for Square-integrated merchants. There is no standalone "Variant Groups" navigation entry.
Route: /menus/items/variant-groups/new and /menus/items/variant-groups/edit/:id. Evidence: src/views/items/Items.vue (Create → New Variant Group, gated by isTestEnv || is_square_integrated).
How to Mark an Item as Unavailable (Sold Out)
Mark as unavailable (recommended):
- Go to Menus → Items.
- Use the Unavailable toggle on the item row.
- Customers can still see the item but cannot order it. Use this for sold-out or temporarily unavailable items.
Evidence: src/views/items/Items.vue (mark_unavailable toggle, updateItemStatus(item, 'Unavailable' | 'Active')).
Track and adjust stock:
- Go to Inventory → Overview.
- Find the item and adjust its quantity (set it to 0 to make it out of stock).
Route: /inventory/overview. Evidence: src/navigation/vertical/index.ts:82-88, src/views/inventory/Overview.vue, src/views/inventory/components/AddItemInventoryDialog.vue (quantity, expiry).
There is no time-limited "Snooze" feature on individual menu items. Use the Unavailable toggle to hide an item from ordering and re-enable it when it is back.
Order Capacity
Order capacity controls how many orders or items can be placed per time slot. It is configured on the Online Settings page (/online-settings).
Evidence: src/views/online-settings/OnlineSettingsForm.vue is the only component that mounts OrderCapacityManagement.vue. The component still supports a settings mode, but the In-House Settings page no longer renders it — InHouseSettingsForm.vue carries only Sections & Tables, Collect Tips, Checkout Notes and Default Menus. Backend enforcement reads online_settings.order_capacity, and StoreInHouseSettingsRequest has no order_capacity rules.
How to Limit Orders During Busy Hours
- Open Online Settings (
/online-settings). - Find Order Capacity and enable it.
- Set the time slot duration (5, 10, 15, 20, 30, 45, or 60 minutes).
- Enter Max orders per slot (
0= no limit). - Optionally enter Max items per slot (
0= no limit). - Open Advanced Options for Protect rush capacity (flexible ordering), Category limits, and Rush Hour Rules (time-specific rules).
- Save.
These are plain numeric inputs, not toggles — the underlying
limit_orders_per_time_slot/limit_items_per_time_slotbooleans are derived from whether the number is above 0.
Evidence: src/views/in-house/components/forms/OrderCapacityManagement.vue:88-131 (the maxOrdersPerSlot / maxItemsPerSlot computed setters), :324-347 (the two numeric fields), :352-366 (Advanced Options collapsible), :378-385 (Protect rush capacity toggle).
How to Set Different Limits for Specific Times
- In Order Capacity, find Time-specific rules.
- Add a rule and configure the days, time range, and the order/item limit for that window.
- Save.
Evidence: src/views/in-house/components/forms/OrderCapacityManagement.vue (time_specific_rules, TimeSpecificRuleFormDialog).
How to Limit Specific Categories
- In Order Capacity, find Category limits.
- Add a category limit, choose the category, and set the maximum per slot.
- Save.
Evidence: src/views/in-house/components/forms/OrderCapacityManagement.vue (limit_specific_categories, CategoryLimitFormDialog).
Payments
Payment configuration is organised as Payment Profiles under Settings → Payments. A profile holds the Stripe connected account used for online ordering plus one in-person provider — Viva Wallet or Stripe Terminal — chosen when the profile is created. Square merchants do not create Payment Profiles; Square handles its own payments.
Route: /settings/payments. Evidence: src/navigation/settings/index.ts:4-10, src/views/settings/PaymentsComponent.vue, src/views/settings/Payments/PaymentProfileDetail.vue.
How to Connect a Payment Provider
- Go to Settings → Payments.
- Create a payment profile (the action button reads New Profile), or open an existing profile. The new-profile dialog asks for name, country, and the in-person payment provider — Viva Wallet or Stripe (Stripe Terminal). Submit with Setup Profile.
- Inside the profile, complete onboarding for:
- Stripe — always, for online ordering.
- The in-person provider you chose — Viva Wallet or Stripe Terminal.
- Follow the provider's connection flow.
The in-person provider choice is permanent: "You won't be able to change the in-person provider after the profile is created."
There is no account-wide "Live Mode" switch. Test mode is a per-location toggle on the payment profile detail page: each location row has a Test Mode switch, a TEST MODE badge while it is on, and a warning that payments are simulated (no real charges) but orders still process normally. Turn it off for that location to take live payments.
Evidence: src/views/settings/PaymentsComponent.vue (new_profile_button, Viva Wallet and Stripe status indicators, has_test_mode_locations chip), src/views/settings/Payments/NewPaymentProfileDialog.vue:149-227 (name / country / in-person provider), src/views/settings/Payments/PaymentProfileDetail.vue:1255-1300 (togglePaymentTestMode, per-location Test Mode switch and badge), src/views/settings/Payments/ (ConnectStripeWebsiteDialog.vue, EditVivaWalletAccountDialog.vue).
Unverified: the exact steps inside the external Stripe / Viva Wallet onboarding screens are handled by those providers and are outside the back office.
How to Set Up Tips
Tips are configured in In-House Settings, not in Online Ordering.
- Open In-House Settings.
- Find the Collect Tips section and enable it.
- Set up to three suggested tip percentages.
- Choose the calculation basis: Before taxes or After taxes.
- Save.
Evidence: src/views/in-house/components/forms/CollectTips.vue (is_collect_tips, tip_percentage_1/2/3, calculate_tips_type with BEFORE_TAXES / AFTER_TAXES).
Marketing
The Marketing section links to Offers and includes Customers and Upsell Groups. Gift Cards and Offers appear in the menu in test environments, and Loyalty appears for merchants connected to a supported POS (MplusKassa, Hendrickx, or Vanhoutte) or in test environments.
Evidence: src/navigation/vertical/index.ts:30-48,131-215.
How to Create a Discount Offer
- Go to Marketing → Offers.
- Create a new offer (route
/marketing/offers/new-offer). - Choose the offer type:
- Amount of Items — discount applied to specific items.
- Amount of Order — discount applied to the order total.
- Buy X, Get Y (BOGO).
- Choose the discount method: a percentage, a fixed amount, or (for BOGO) free items.
- Set conditions such as minimum purchase, applicable items/categories, active days, channels, and combination rules.
- Set a maximum number of uses if you want a redemption limit.
- Save.
The offer types are Items / Order / BOGO; "percentage off", "amount off", and "free" are discount methods within those types, not separate offer types.
Evidence: src/views/marketing/offers/CreateOfferForm.vue, src/views/marketing/offers/components/create-offers/types/index.ts (ITEMS / ORDER / BOGO; amount / percent / free), src/views/marketing/offers/components/create-offers/OfferDetails.vue (minimum purchase, max uses, applies-to, active days, channels, combinations).
How to Create a Coupon Code
Coupon codes are not a separate feature — they are a property of an Offer. (The /marketing/coupons page exists but is an empty stub.)
- Go to Marketing → Offers and create or edit an offer.
- For the offer's method, choose Code (instead of Automatic).
- Enter (or auto-generate) the discount code (up to 10 characters).
- Configure the offer's conditions and maximum number of uses as needed.
- Save.
- Share the code with customers to enter at checkout.
Evidence: src/views/marketing/offers/components/create-offers/OfferInformation.vue (method = Automatic/Code, discount_code field); src/pages/marketing/coupons.vue (empty stub, no form).
How to Set Up a Loyalty Program
Loyalty is a paid add-on. In production it is available only to merchants connected to a supported POS (MplusKassa, Hendrickx, or Vanhoutte); it is available everywhere in test environments. Setting it up creates a subscription.
- Go to Marketing → Loyalty.
- Start creating a loyalty program (a multi-step wizard).
- Configure earning, e.g. points earned per € and/or points earned per visit, an optional minimum spend to earn points, and months until points expire.
- Configure rewards (redemption tiers).
- Configure any welcome / additional bonuses in the relevant step.
- Review and complete the subscription step.
Route: /marketing/loyalty (list) and /marketing/loyalty/create-loyalty (wizard). Evidence: src/navigation/vertical/index.ts:194-215, src/views/marketing/loyalty/LoyaltyForm.vue, src/views/marketing/loyalty/components/loyaltyCreateStep/Step2CreateLoyalty.vue (points_earned_each_dollar, points_earned_each_visit, minimum_spend_to_earn_points, months_to_expire_points, rewards).
Devices
Devices are managed under Device Management, which has two sections: Devices (the device list) and Device Profiles (reusable configuration templates that devices use). There are no separate "Kiosks" or "KDS" menu entries.
Evidence: src/navigation/vertical/index.ts:103-121.
How to Set Up a Device (Kiosk)
- Go to Device Management → Devices.
- Add a device and choose its type. The picker offers POS, Kiosk, Kitchen Display and Printer, each with its own gate: POS and Kitchen Display appear only for merchants running the first-party Upvendo POS (not self-serve selectable today), Kiosk requires a connected POS, and Printer is freely creatable.
- Configure the device (a device picks up settings from an assigned Device Profile).
Route: /device-management/devices. Evidence: src/pages/device-management/devices/index.vue, src/views/devices/Devices.vue, src/constants.ts:11-57 (DATA_TYPE_OPTION_DEVICE, POS_REQUIRED_DEVICE_TYPES = ['Kiosk'], FIRST_PARTY_POS_REQUIRED_DEVICE_TYPES = ['POS', 'Kitchen Display']). The old isTestEnv gate on Kitchen Display is gone.
Unverified: the on-device pairing / activation flow happens on the kiosk hardware/app and cannot be confirmed from the back-office code.
How to Configure a Device Profile (incl. Kitchen Display)
Kitchen Display and other device behaviours are configured through Device Profiles, not a dedicated KDS page.
- Go to Device Management → Device Profiles.
- Create a new profile (or edit an existing one).
- Configure the available sections, which include: Dining Options, Customer Flow, Section Selection, Receipt Settings, Receiving Orders, Inventory Settings, Menus, Idle Settings, and Device Schedule.
- Save and assign the profile to one or more devices.
Routes: /device-management/profiles, /device-management/profiles/new-profile, /device-management/profiles/edit/:id. Evidence: src/pages/device-management/profiles/index.vue, src/views/device-profiles/DeviceProfileForm.vue.
The documented "caution time" / "late time" KDS timer fields could not be confirmed in the device-profile form sections in this code. Unverified.
Integrations
There is no single "Integrations" menu. Each integration is its own channel page, reached from the channel sections / add-channel flows rather than from a shared Integrations menu.
How to Connect Deliveroo
- Open the Deliveroo integration page.
- Enter your Site ID.
- Optionally enable Sandbox mode for testing.
- Connect, then configure menu/availability sync.
The connection uses a Site ID (and an optional sandbox toggle); there is no separate "API Key" field in the back office. Deliveroo is a production online channel, but it is only offered when the platform's
services.deliveroo.enabledflag (DELIVEROO_ENABLED, default off) is on — it is flag-gated, not test-environment-gated.
Route: /deliveroo. Evidence: src/views/deliveroo/index.vue (Site ID field, sandbox toggle, enableIntegration()), src/store/modules/app.ts (Deliveroo channel commented out in production).
Unverified: where you obtain your Deliveroo Site ID and any partner-portal steps are external to the back office.
How to Connect Square
- Open the Square integration page.
- Click Connect with Square to start the OAuth flow and authorise Upvendo.
- Once connected, the page shows the connected merchant and token status, and lets you set an auto-sync time and view sync status/logs.
Route: /square. Evidence: src/pages/square/index.vue, src/views/square/index.vue, src/views/square/SquareForm.vue (Connect with Square OAuth, merchant/token status, auto-sync time).
Unverified: choosing a specific Square location and the detailed sync option set are not fully exposed in the back-office code reviewed here. The claim that "Square Payments replaces Stripe when Square is connected" is not stated anywhere in this UI code and has been removed.
Reports & Analytics
The bare /reports page is still an empty stub, but a Reports nav group now exists with one child — Kitchen Reports (/reports/kitchen), a KDS speed-of-service report. It is gated on the view-kitchen-reports permission and firstPartyPosOnly, and the group hides entirely when the user has no visible child — so a merchant not on the first-party Upvendo POS (which is not self-serve selectable today) sees no Reports menu at all. For those merchants, reporting is still the Transactions page: summary statistics plus an Excel export.
Evidence: src/pages/reports/index.vue (empty div), src/navigation/vertical/index.ts:31-45 (live Reports group), src/pages/reports/kitchen/index.vue, src/views/reports/KitchenReports.vue.
How to View Sales Stats and Export
- Go to Transactions.
- Apply filters (date range with presets, status, channel, type, device, dining option, location, search).
- Review the summary stats cards (e.g. total revenue, number of orders, number of customers) for the current filters.
- Click Export to download an XLSX (Excel) file (requires the export permission).
Export is XLSX only — there is no CSV or PDF export in the back office.
Route: /transactions. Evidence: src/views/transactions/Transactions.vue (filters, summary stats cards, Export action producing transactions_export_*.xlsx, gated by $can('export', 'transaction-reports')).
How to Check Order History
- Go to Transactions.
- Use the filters (date range, status, channel, type, device, dining option, location) and the search box (order number / customer).
- Click an order to open its details.
Route: /transactions (list) and /transactions/detail/:id (detail). Evidence: src/views/transactions/Transactions.vue, src/pages/transactions/detail/[id].vue.
Troubleshooting
How to Check Why Orders Are Being Rejected
Common causes to check:
- Order Capacity — time slots may be full (In-House / online settings).
- Operation Hours — the order may fall outside open hours (Settings → Locations).
- Restricted Dates — it may be a holiday closure.
- Inventory — items may be out of stock (Inventory → Overview).
- Delivery region — the customer may be outside your delivery area (Online Ordering → Delivery Settings).
Activity Log: Go to Settings → Activity Log to review recent changes. Evidence: src/navigation/settings/index.ts:89-95.
How to Refund an Order
In the current production build there is no way to open the refund dialog from the back office. showRefundDialog has exactly two references in the whole repo — its ref(false) declaration (src/components/OrderDetailView.vue:95) and the v-model binding on the mounted dialog (:644-649). Nothing ever sets it to true, so no button, menu item or route opens it. Refund from the payment provider's own dashboard until this is wired up.
For reference, the dialog itself supports:
- By amount (Euro) — full or partial amount.
- By item — select specific items to refund.
- Confirmation with Send refund. There is no "reason" field.
Evidence: src/views/transactions/components/RefundDialog.vue (by_euro / by_item, send_refund, no reason field), src/components/OrderDetailView.vue:95,644-649 (RefundDialog mounted but never opened; the header menu only has resend-receipt / delete-test-transaction).
Note: Refunds are processed through the order's original payment provider — Stripe for online orders, and Viva Wallet, Stripe Terminal or Square for in-person orders.