Appearance
Guided Setup
Overview
Guided Setup is Upvendo's interactive onboarding flow that walks new merchants through the essential configuration steps needed to get their business operational. It is presented as a checklist panel inside the Emily assistant (not a standalone page), reachable from any backoffice page. The merchant first picks their POS provider, and the panel then shows an ordered checklist of setup steps (set up payment profile, set up billing profile, set up store branding, create location, connect the POS, sync the menu, and so on). Each step links to the backoffice page where the action is performed.
The current onboarding flow is powered by Upvendo's AI assistant Emily. The step list is generated by Emily during a "discovery" conversation and then served from Emily's knowledge base; there is no built-in per-provider list in the front end, so a missing or failed step lookup produces an empty checklist rather than a fallback. Completion is detected automatically: the backend inspects the merchant's actual data (does a payment profile exist? is a location created? is the POS connected and tested?) and reports which steps are done, so checkmarks appear without the merchant having to mark anything manually.
Note: an older, separate config-driven guided-setup system also exists in the codebase (service paths
self-service/online-ordering/qr-codewith categories and tasks). The frontend store module explicitly marks it deprecated and being migrated to Emily's onboarding state. The customer-facing onboarding flow described here is the Emily/POS-provider one.
Purpose
This page lets you follow a structured onboarding flow to configure your Upvendo business. You select your POS provider, then work through an ordered checklist that links you to each setup page and tracks which steps are already done.
Key Concepts
- Onboarding checklist: The live checklist UI is
src/components/emily/EmilySetupPanel.vue, rendered inside the Emily widget (src/components/emily/EmilyWidget.vue, lines 14 and 27). It opens on theemily:open-setup-panelwindow event, handled atEmilyWidget.vuelines 744-746 (listener registered at line 778). There is no page you can navigate to — the checklist only exists inside the Emily widget. - The old
EmilyGuidedSetupDialogis dead code. It is imported and registered insrc/App.vue(lines 12 and 23) but appears nowhere in App.vue's template, so it never renders — dead since backoffice36e3a3745(2025-12-19, "Replace EmilyGuidedSetupDialog with EmilySetupPanel"). Theshow_guided_setup_dialogstore flag (setShowGuidedSetupDialog) is inert with it: three call sites still write it (src/layouts/components/NavBarGuidedSetup.vueline 16,src/components/dialogs/guided-setup/GuidedSetupVideoContentDialog.vueline 128,src/layouts/components/DefaultLayoutWithVerticalNav.vueline 440) but no template reads it, which also means the boot-time auto-open atDefaultLayoutWithVerticalNav.vuelines 429-443 no longer opens anything. - Where it opens from: the unlabelled clipboard icon (
tabler-clipboard-list) in the navbar (src/components/navbar/NavBarGuidedSetup.vue, rendered atsrc/layouts/components/DefaultLayoutWithVerticalNav.vueline 604) and the Guided Setup entry in the account menu (src/components/navbar/UserProfile.vuelines 85-90 and 125-127). Both dispatch the sameemily:open-setup-panelevent. On a brand-new account Emily also opens itself — see "First run" below. - POS provider selection: The provider tiles the merchant actually sees come from the backend, not from a hardcoded frontend list.
GET /back-office/merchant/reseller-providers(ResellerService::getMerchantResellerProviders) filtersconfig/pos-providers.phpby the provider'sactiveflag, itstest_onlyflag, and either the merchant's country (no reseller) or the reseller's assigned provider catalog. In production a Belgian merchant with no reseller sees Hendrickx, Vanhoutte and MplusKassa; Shopcaisse, Lightspeed K-Series and the first-party Upvendo POS aretest_only(still shown to merchants flaggedis_test), and Square is limited to US / CA / GB / AU / JP / IE / FR / ES. Theupvendoentry setsfirst_party => true(which bypasses the country and reseller-catalog filters — thetest_onlycheck runs first) and is'active' => true, 'test_only' => trueatconfig/pos-providers.php:51-52, so Upvendo POS appears only for test merchants untiltest_onlyis dropped. Selecting a provider saves it to Emily's onboarding state withphase: 'discovery'and opens the Emily chat. (Verified:src/components/emily/EmilyWidget.vueline 136;src/store/modules/app.tslines 722-728;app/Services/BackOffice/ResellerService.phplines 666-689.) POS_PROVIDERSintypes.tsis not the live list. It drives onlyPOSSelectionGrid.vue, which lives inside the unrenderedEmilyGuidedSetupDialog. ItsPRODUCTION_POS_PROVIDERSarray does list Upvendo POS, but that is legacy and reflects nothing a merchant sees. The live selection UI is Emily'sproviderOptionscards inEmilyWidget.vue.- Setup step: A single onboarding task with
title, an optionalid, and an optionalroute(the backoffice page it links to). Some steps carry achannel(the POS channel to connect) or anaction(currently onlyopen_location_selector). Steps are typed by theSetupStepinterface intypes.ts. - Base steps vs channel steps (legacy):
BASE_SETUP_STEPS(per POS provider) and the two shared channel checklistsKIOSK_CHANNEL_STEPS/ONLINE_ORDERING_CHANNEL_STEPSlive intypes.ts, but only the unrendered dialog andChannelSetupTabs.vueread them. They are not what a merchant sees — see "Legacy step definitions" below. - Where the live steps come from: the
setup_stepsalready in the Vuex store (written by the Emily chat during discovery) when the store also carries apos_provider; otherwisegetSetupSteps(pos_provider, channel)against Emily's knowledge base. There is no per-provider frontend fallback: an unresolved provider, or a failed/empty knowledge-base response, produces an empty checklist. Some step routes are corrected at runtime bygetStepRouteOverride(e.g. "Connect Hendrickx" →/hendrickx, "Sync Menu" → the current POS page). (Verified:EmilySetupPanel.vuelines 374-398 and 433-441.) - Automatic completion detection: The backend endpoint
GET /api/back-office/setup-statusreturns boolean flags about the merchant's real data. The frontend (setupStepMappings.ts) maps those flags to completed step IDs and merges them with any manually tracked IDs from Emily's state. A step shows a checkmark when its ID is in the merged completed list. - Completion is an exact ID match, normalized on read via
canonicalizeStepId(). A step is ticked bycompletedStepIds.value.includes(canonicalizeStepId(step.id))(EmilySetupPanel.vue). Historical onboarding docs used retired spellings (setup_menu_kiosk,setup_menu_online,configure_kiosk,pos_setup).canonicalizeStepId()insrc/utils/emily/setupStepIds.tsnormalizes those retired spellings to their canonical forms (menu_for_kiosk,menu_for_online_ordering,kiosk_device,connect_pos), andsetupStepMappings.tsemits only single canonical step IDs. Step gating is governed strictly by the prerequisite dependency graph insetupStepLock.ts, not by list index orrequiredflags. (Verified:upvendo-backoffice/src/utils/emily/setupStepLock.tsandsetupStepIds.ts.)
Route
- Access: A panel inside the Emily widget — there is no
/guided-setuppage route, and none exists in the backoffice's file-based pages or itsredirectsarray. Opened by the navbar clipboard icon, the Guided Setup entry in the account menu, or programmatically by dispatching theemily:open-setup-panelwindow event. (Verified: nosrc/pages/guided-setup*entry and no/guided-setuppath insrc/plugins/1.router/additional-routes.tsonorigin/production./guided-setup-videosis a separate global-admin page for managing tutorial videos, not this feature.) - Checklist component:
src/components/emily/EmilySetupPanel.vue, rendered bysrc/components/emily/EmilyWidget.vueat lines 14 and 27. - Legacy, not rendered:
src/components/dialogs/EmilyGuidedSetupDialog.vueis imported and registered insrc/App.vue(lines 12 and 23) but never appears in its template. The still oldersrc/components/dialogs/GuidedSetupDialog.vueis reachable only through Emily's modal registry (src/utils/emilyModalRegistry.tsline 139, keyguided-setup). Neither is what a merchant sees. - Legacy sub-components (imported only by
EmilyGuidedSetupDialog.vuelines 8-11, therefore also unrendered):src/components/dialogs/guided-setup/POSSelectionGrid.vue,SetupProgressList.vue,ChannelSetupTabs.vue,DisconnectRequiredNotice.vue.GuidedSetupVideoContentDialog.vueis separate. - What the live panel imports:
EmilySetupPanel.vueline 117 takes only the typesSetupStepandOnboardingStatefromguided-setup/types.ts, plussetupStepMappings,setupStepLock,posSetupTitleandemilyApi. - Step definitions (legacy):
src/components/dialogs/guided-setup/types.ts(SetupStep,POS_PROVIDERS,BASE_SETUP_STEPS,KIOSK_CHANNEL_STEPS,ONLINE_ORDERING_CHANNEL_STEPS) — consumed only by the unrendered dialog andChannelSetupTabs.vue. - Step ↔ status mapping:
src/utils/emily/setupStepMappings.ts - Onboarding-state API client:
src/utils/api/emilyApi.ts(getOnboardingState,saveOnboardingState,deleteOnboardingState,getSetupSteps) - Store module:
src/store/modules/guidedSetup.ts - Backend status endpoint:
GET /api/back-office/setup-status→app/Http/Controllers/Api/BackOffice/SetupStatusController.php(logic inapp/Services/SetupStatusService.php) - Backend video endpoints:
app/Http/Controllers/Api/BackOffice/GuidedSetupManagementController.php(logic inapp/Services/BackOffice/Settings/GuidedSetupVideoService.php) - Task/video catalog config:
config/guided-setup.php
The legacy backend artifacts the previous version of this page listed (
GuidedSetupController,GuidedSetupOrchestrator,GuidedSetupService,GuidedSetupProgressmodel,GuidedSetupProgressRepository,GuidedSetupTaskListener,app/Events/GuidedSetup/*,UpdateGuidedSetupProgresscommand) do not exist in the backend and have been removed from this doc.
Legacy step definitions (BASE_SETUP_STEPS) — not what merchants see
These lists are legacy.
BASE_SETUP_STEPS,KIOSK_CHANNEL_STEPSandONLINE_ORDERING_CHANNEL_STEPSinguided-setup/types.tsare reachable only fromEmilyGuidedSetupDialog.vueandChannelSetupTabs.vue, both of which sit behind the dialog that App.vue registers but never renders. The live panel has no per-provider frontend fallback — its steps come from the store or from Emily's knowledge base (see Business Rules). The canonical checklists a merchant actually receives are thesetup_stepsserved frommerchant/onboarding/*.mdin this knowledge base. The lists below are kept only as a record of the historical ordering. (Verified:grep BASE_SETUP_STEPS src/matches onlyguided-setup/types.tsandEmilyGuidedSetupDialog.vue;EmilySetupPanel.vueline 117 imports types only.)
These lists record historical ordering only. The
setup_stepsfences inmerchant/onboarding/*.mdare canonical, and they no longer match the order below: payment and billing moved to the end flaggedoptional_for_go_live, and the menu steps moved up directly after the connect.
Hendrickx / Vanhoutte / Shopcaisse / Lightspeed K-Series (Lightspeed omits "Select Location from Topbar" and "Sync Menu"):
- Set up Store Branding —
/settings/brand - Create Location —
/settings/locations - Select Location from Topbar — action:
open_location_selector - Connect <POS> —
/hendrickx//vanhoutte//shopcaisse//lightspeed - Sync Menu — the current POS page
- Build Menu for Kiosk / Build Menu for Online Ordering —
/menus/menu-builder - Channel configuration (in-house / device / kiosk, or online settings / online ordering)
- Set up Payment Profile —
/settings/payments(optional_for_go_live) - Set up Billing Profile —
/settings/billing(optional_for_go_live) - Test steps (
optional_for_go_live)
Square (POS imports locations, so it has a shorter list):
- Set up Store Branding —
/settings/brand - Connect Square —
/square - Review Imported Locations —
/settings/locations
MplusKassa (merchant-scoped, syncs locations):
- Set up Payment Profile —
/settings/payments - Set up Billing Profile —
/settings/billing - Set up Store Branding —
/settings/brand - Connect MplusKassa —
/mpluskassa - Sync Locations —
/mpluskassa - Complete Location Details —
/settings/locations - Sync Menu —
/mpluskassa
Kiosk channel steps (KIOSK_CHANNEL_STEPS, shown after base steps):
- Build Menu for Kiosk —
/menus/menu-builder - Set up In-House Settings —
/in-house/settings - Create Device Profile —
/device-management/profiles - Set up Kiosk & Activate Payment —
/device-management/devices - Activate Kiosk & Test Order — (no route)
Online Ordering channel steps (ONLINE_ORDERING_CHANNEL_STEPS):
- Build Menu for Online Ordering —
/menus/menu-builder - Set up Online Settings —
/online-settings - Set up Online Ordering —
/online/online-ordering - Open Online Ordering URL & Test Order —
/online/online-ordering
Actions
First run (a brand-new account)
Three things happen automatically for a merchant who has not started onboarding:
- Emily opens by itself and starts discovery. Once the onboarding state has loaded, if the merchant's onboarding phase is
none, Emily opens once per session and auto-launches discovery — it does not need the persisted dock flag a returning user has. It only fires in merchant context, only when Emily is available, and is suppressed while the user is on a/settings/locationspage, where the location co-pilot takes priority. (Verified:src/components/emily/EmilyWidget.vuelines 922-939;src/utils/emily/onboardingGating.ts.) /homeshows a Welcome card. A regular merchant user with no location yet lands on a "Welcome … Let's get your restaurant set up" card with a Start setup with Emily button (which dispatchesemily:start-onboarding) instead of being redirected to the first permission-accessible page. Global-admin and partner logins still go to their own dashboards, and the decision is made only after the location list has loaded, so a slow load is not misread as "no location". (Verified:src/pages/home/index.vuelines 10-21, 55-71 and 157-186.)- The operational nav is visible but locked. Until the merchant has a location, every left-sidebar nav link and group stays on screen but is greyed out, non-navigable and marked with a
tabler-lockicon. The top bar and Settings stay reachable, so the merchant can still create the location that unlocks everything. The code assumes a location exists until the location list resolves, so an existing merchant never flashes the locked state. (Verified:src/navigation/vertical/index.tslines 259 and 321-328;src/@layouts/components/VerticalNavLink.vuelines 89-96.)
Select a POS provider
On first open (no POS connected, no provider saved), Emily asks which POS the merchant uses and offers the provider cards. Selecting a provider saves { pos_provider, phase: 'discovery', current_question_index: 0, answers: {}, setup_steps: [], completed_steps_ids: [] } to Emily's onboarding state and opens the Emily chat to begin discovery.
- Saves via:
POST {emily-endpoint}/onboarding-state/{merchantId}(saveOnboardingState)
View setup progress
When a POS provider is connected or saved, the panel loads the step list (from the store, otherwise from Emily's knowledge base) and overlays auto-detected completion. Each step renders with a number, checkmark, or lock; the overall progress bar reflects the completed/total ratio.
- Fetches state via:
GET {emily-endpoint}/onboarding-state/{merchantId}(getOnboardingState) - Fetches steps via:
getSetupSteps(pos_provider, channel)against Emily's knowledge base - Fetches completion via:
GET /api/back-office/setup-status?location_id={locationId}(fetchSetupStatus)
Click a step
Navigates to the step's route and closes the panel. Special cases: a step with action: 'open_location_selector' dispatches the guided-setup:open-location-selector window event instead of navigating; a POS-connection step whose channel is not yet connected opens the in-house channel connect dialog (pre-selecting that channel) first.
The "Continue to Channel Setup" tabs, the "Change POS" link and the disconnect-required notice belonged to the old
EmilyGuidedSetupDialog, which no longer renders.EmilySetupPanel.vuecontains none of them. To change POS provider today, go through Emily's chat or disconnect the integration from its own settings page.
Get the video for a page
When a step navigates to a backoffice page, the app fetches a contextual tutorial video for that route.
- Endpoint:
GET /api/back-office/guided-setup-management/video/url?url={pagePath} - Backend:
GuidedSetupManagementController::getVideoByUrl. Returns video metadata, or an empty object (HTTP 200) when no video is configured for that URL.
Manage onboarding state (programmatic)
The store exposes helper actions used by the Emily widget and setup panel: fetchEmilyOnboardingState, completeEmilyOnboardingStep, and resetEmilyOnboardingState (which calls DELETE {emily-endpoint}/onboarding-state/{merchantId}).
Fields
| Field | Where | Type | Notes |
|---|---|---|---|
| POS provider | POS selection | String | A provider key from GET /back-office/merchant/reseller-providers (for a Belgian merchant in production: hendrickx, vanhoutte, mpluskassa) |
| Step ID | Setup status / step list | String | e.g. payment_profile, billing_profile, branding_profile, create_location, connect_pos, lightspeed_order_profiles, sync_menu, complete_location |
| Location ID | Setup status request | String | Optional query param scoping completion to a location |
| Phase | Onboarding state | String | none / discovery / checklist / completed (and execution is accepted by the store) |
Setup-status flags (backend response)
GET /api/back-office/setup-status returns success plus boolean/string flags including: has_payment_profile, has_billing_profile, has_branding, has_location, location_selected, any_incomplete_location, has_menu_items, has_menu_for_kiosk, has_menu_for_online_ordering, pos_connected, pos_provider, menu_synced, has_integration_test, has_pos_order_profiles, has_kiosk_test_order, kiosk_test_order_id, has_online_ordering_test_order, online_ordering_test_order_id, has_in_house_settings, has_online_settings, has_online_ordering_settings, has_device_profile, has_kiosk_device.
Business Rules
- POS selection drives the flow. When no POS is connected and none is saved in Emily's state, Emily asks for the provider first. The offered list is whatever
GET /back-office/merchant/reseller-providersreturns for that merchant, filtered byactive,test_onlyand country / reseller catalog — not a hardcoded frontend list. Upvendo POS is stagedtest_only, so in production it is offered only to merchants flaggedis_test. - There is no per-provider frontend fallback. The panel uses the
setup_stepsalready in the Vuex store (put there by the Emily chat) when the store also carries apos_provider(EmilySetupPanel.vueline 375). Otherwise it resolves the provider from store > connected POS > Emily's onboarding state; if none resolves it renders an empty checklist without calling the knowledge base (lines 396-398). When a provider does resolve it fetchesgetSetupSteps(pos_provider, channel)from Emily's knowledge base, and a failed or empty response also yields an empty checklist (lines 434-441).BASE_SETUP_STEPS[posProvider]is not consulted anywhere in the rendered UI. - Completion is auto-detected, not stored as task records. A step is marked complete when its ID appears in the merged list of (a) backend-detected IDs from
/setup-statusand (b) any IDs already in Emily's onboarding state. There is no per-task progress collection. - The "connect POS" step requires a real, tested integration. In
setupStepMappings.ts,connect_posis only completed when bothpos_connectedandhas_integration_testare true. The backend treats a POS as connected only when its integration is in a connected state or has stored credentials. (Verified:upvendo-backoffice/src/utils/emily/setupStepMappings.tslines 67-72;upvendo-backend/app/Services/SetupStatusService.phplines 364-368 and 434-439.) - First-party Upvendo POS is the other exception. When
pos_providerisupvendothe backend hard-codespos_connected = trueandhas_integration_test = false— there is noThirdPartyIntegrationrow at all — soconnect_pos(and its retired aliaspos_setup) complete onpos_connectedalone. The provider is stagedtest_only(config/pos-providers.php:51-52): in production, only merchants flaggedis_testcan select it viaPOST /back-office/pos/select-provider; a live merchant gets a 403 from thetest_onlygate inFirstPartyPosProvisioningService::selectFirstPartyPos()(FirstPartyPosProvisioningService.php:70-77). The console seeders (pos:seed-demo/ test-account) also callselectFirstPartyPos()directly. (Verified:setupStepMappings.tslines 67-72;SetupStatusService.phplines 325-333;config/pos-providers.phplines 36-54;app/Http/Requests/BackOffice/Pos/SelectPosProviderRequest.phplines 28-37;app/Services/Pos/PosDemoSeederService.phpline 254.) has_integration_testmeans the integration has alast_successful_testtimestamp. For Hendrickx, Vanhoutte, Square, MplusKassa, and Shopcaisse that timestamp is only written when a connection check against the provider succeeds — in practice, the merchant clicking Test Connection on the integration page. (Shopcaisse additionally records it when loading the integration-details view finds the connection live.) (Verified:app/Services/Common/AbstractKassanetService.phplines 2540-2546 for Hendrickx/Vanhoutte;SquareIntegrationService.phplines 198-221;MplusKassaIntegrationService.phplines 1596-1611;ShopCaisseIntegrationService.phplines 1560-1570, plus the details-view stamp at lines 955-967.)- Lightspeed K-Series is the exception —
connect_posself-completes on connect. The Lightspeed OAuth callback fetches the merchant's business from/o/op/data/businesses; because that is a live authenticated round-trip, a successful fetch stampslast_successful_testright there. The step therefore completes as soon as the merchant authorizes Upvendo, with no separate Test Connection click, on both the first connect and a re-auth (they run the same callback). If that businesses fetch fails, the stamp is skipped and any earlier genuine stamp is preserved. (Verified:app/Services/BackOffice/LightspeedKSeriesIntegrationService.phplines 336-354 and 414-421. Square's OAuth callback does not stamp it —SquareIntegrationService.phplines 434-445.) - Lightspeed K-Series adds a step:
lightspeed_order_profiles("Set up Order Profiles & Tax"). It auto-completes whenpos_provider === 'lightspeed'andhas_pos_order_profilesis true. The backend returns true only for Lightspeed K-Series, and only when a location mapping carries a non-emptysettings.account_profiles— the map the merchant saves in the back-office Order-profiles dialog. Scoped to one location when the request carrieslocation_id, otherwise any active mapping counts; false for every other provider and when no POS is connected. (Verified:app/Services/SetupStatusService.phplines 378 and 393-410;upvendo-backoffice/src/utils/emily/setupStepMappings.tsline 56.) - Step gating is by declared prerequisites, not list order.
DEPENDS_ONinupvendo-backoffice/src/utils/emily/setupStepLock.tsdeclares what each step actually needs (e.g.connect_posneeds branding, a location and a selected location;test_kioskneedskiosk_device). A step that merely sits later in the list than an incomplete one is not thereby blocked. Three rules make one graph serve every provider: (1) a prerequisite absent from a provider's checklist is transitively replaced by its own prerequisites, so Square — which has nosync_menu— resolvesmenu_for_kioskback toconnect_pos; (2) a completed step is never locked, which guards the case where a completion flag is stricter than the gate that actually let the merchant past it (has_brandingneedsis_completed = true, while the connect gate only needs a branding profile to exist); (3) a prerequisite flaggedoptional_for_go_livecounts as satisfied, because the backend enforces a branding profile at connect only for Hendrickx, Vanhoutte, Shopcaisse and MplusKassa (ThirdPartyIntegrationHelper::checkRequiredProfiles) — Square and Upvendo flag branding optional for exactly that reason, and without rule 3 "Connect Square" would be locked behind a step Square never requires.payment_profileandbilling_profileare nobody's prerequisite and gate nothing. optional_for_go_livereplaces the oldrequiredflag, and is labelling only. It surfaces the "complete before you go live" hint onpayment_profile,billing_profileandlightspeed_order_profiles, and (via rule 3 above) stops a step the backend does not enforce from blocking one it does. It does not remove the step from the progress denominator. The retiredrequiredfield is no longer read by the front end.- The billing step is omitted under
reseller_collects. When the merchant's reseller uses thereseller_collectsbilling model the reseller invoices the merchant and Upvendo bills the reseller, sobilling_profileis filtered out of the checklist entirely rather than shown as optional — a task that is never coming should not sit in the list or in the progress denominator. Underplatform_collects, and for a merchant with no reseller, it stays. The signal isuserData.billing_model, set at login byupvendo-backendAuthServicefrom the merchant's reseller (nullwhen there is no reseller). Note the back office's pre-existingisResellerManagedcomputed meansplatform_collects— the opposite case — so do not reuse that predicate. - Merchant-scoped providers add location-sync steps. For MplusKassa and Square, having a location adds
sync_locations; if no location is incomplete,complete_locationis also added. - Test orders require a completed order on that channel.
has_kiosk_test_order/has_online_ordering_test_orderare true only when aCompletetransaction exists for that channel at the selected location. - The legacy config system is deprecated. The store module header marks the old
/back-office/guided-setup/*flow deprecated in favor of Emily's onboarding state; treat the Emily/POS flow as authoritative.
Customer Impact
- Kiosk: After the base steps, the Kiosk channel checklist guides you through building a kiosk menu, in-house settings, a device profile, activating the kiosk with payment, and placing a test order.
- Online Ordering: The Online Ordering channel checklist covers building an online-ordering menu, online settings, configuring online ordering, and opening the online-ordering URL to place a test order.
- POS connection: A central step is connecting your POS provider (e.g. Hendrickx, Vanhoutte, Square, MplusKassa, Shopcaisse, Lightspeed K-Series) and syncing your menu.
- Time to first order: Guided Setup is the primary path from registration to a working kiosk or online-ordering channel, with steps marked done automatically as you complete the underlying configuration.
FAQs
Is Guided Setup mandatory?
No. It is a helpful onboarding aid you can close at any time and configure everything manually through the standard backoffice pages. Reopen it from the clipboard icon in the navbar or the Guided Setup entry in the account menu.
How do steps get marked as completed?
Automatically. The backend setup-status endpoint inspects your actual data (payment profile, billing profile, branding, locations, menus, POS connection, devices, test orders, etc.) and the frontend maps those results to step checkmarks. You generally don't mark steps yourself.
Why does a step still show as incomplete after I did it?
Completion is detected from real data and can be location-scoped. Make sure you have the correct location selected in the topbar, and that the underlying record actually meets the check (for example, "connect POS" needs both a connected POS and a successful integration test — click Test Connection on the integration page if you have not; a payment profile must be verified/enabled). Lightspeed K-Series is the exception to the test click: its OAuth callback records the successful test for you.
Which POS providers can I choose?
Whichever providers GET /back-office/merchant/reseller-providers returns for your account. It filters the platform's provider catalog by each provider's active and test_only flags and by your country (or, if you were onboarded through a reseller, that reseller's assigned catalog). In production a Belgian merchant with no reseller sees Hendrickx, Vanhoutte and MplusKassa. Shopcaisse, Lightspeed K-Series and Upvendo's own first-party Upvendo POS are marked test-only and appear only for test merchants and non-production environments (Upvendo POS in every country — first_party bypasses the country filter); Square is offered in US, CA, GB, AU, JP, IE, FR and ES. (The POS_PROVIDERS constant in types.ts is legacy and does not describe this list.)
Can I change my POS later?
Yes, via the "Change POS" link. If a POS is already connected you'll be asked to disconnect it from its settings page first; otherwise you go straight back to the POS selection grid.
How do the tutorial videos work?
When a step opens a backoffice page, the app calls GET /back-office/guided-setup-management/video/url?url=<page> to fetch a contextual video. If no video is configured for that page, the endpoint returns an empty object and a placeholder is shown. Global administrators can manage these videos from the Guided Setup Videos admin page.
Troubleshooting
Emily keeps asking which POS I use
Emily asks for the provider when no POS is connected and no pos_provider is saved in your onboarding state. Pick one (which saves the state and starts discovery), or connect a POS so it is auto-detected.
Emily opened by itself on my first login
That is deliberate. On a brand-new account whose onboarding phase is still none, Emily opens once and starts discovery so setup does not have to be found. It does not do this on a /settings/locations page, where the location co-pilot takes priority. See "First run" under Actions.
Most of my sidebar is greyed out with a padlock
Also deliberate, and temporary. Until your account has a location, the operational navigation stays visible but locked so you can see what is coming without being able to walk into empty pages. Settings and the top bar stay reachable — create your first location there and the rest unlocks. Existing accounts never see this.
Steps are missing or the list looks empty
There is no per-provider fallback list in the front end, so an empty checklist means one of two things. Either no POS provider could be resolved at all (nothing in the store, no connected POS, nothing in Emily's onboarding state) — in which case the panel does not even call the knowledge base — or the provider resolved but the getSetupSteps call to Emily's knowledge base failed or came back with no steps. Start (or restart) discovery with Emily so a provider and a step list get saved. (Verified: EmilySetupPanel.vue lines 393-398 and 433-441.)
Progress shows 0% even though I configured things
Completion is detected per merchant and (often) per selected location. Confirm the correct location is selected in the topbar so setup-status evaluates the right data, and verify each underlying record satisfies its check.
"Connect POS" never completes
connect_pos requires both pos_connected and has_integration_test to be true. Ensure the integration is connected (connected status or stored credentials) and that a successful integration test has been recorded.
Two exceptions to that rule. Lightspeed K-Series records the test itself during OAuth (see below). And first-party Upvendo POS never records one at all: the backend hard-codes pos_connected = true and has_integration_test = false for it, so connect_pos (and its retired alias pos_setup) complete on pos_connected alone. That branch is reachable in production only by test-flagged merchants — the upvendo provider is staged test_only and POST /pos/select-provider 403s a live merchant — and by accounts placed there by the pos:seed-demo / test-account console seeders.
For Hendrickx, Vanhoutte, Square, MplusKassa, and Shopcaisse, recording that test means a successful connection check — normally clicking Test Connection on the integration page. That timestamp is what has_integration_test reads.
For Lightspeed K-Series there is nothing to click: the OAuth callback records the successful test itself when it fetches your business from Lightspeed, so the step completes on connect. If it is still not complete, the businesses fetch after authorization failed — reconnect from /lightspeed → Settings, and check the Status tab for the error. (Verified: app/Services/BackOffice/LightspeedKSeriesIntegrationService.php lines 336-354 and 414-421.)
Video content is not loading
Verify a video is configured for that exact page URL in config/guided-setup.php (or via a custom video override managed by a global admin). The lookup matches the current page path against task URLs; an unmatched URL returns an empty result and the no-video placeholder is shown.
Assistant Guidance
When users ask about Guided Setup, describe it as a checklist panel inside the Emily assistant (not a separate page), opened from the clipboard icon in the navbar or the Guided Setup entry in the account menu — and note that on a brand-new account Emily opens itself on first login. Explain the flow: pick a POS provider, then work through an ordered checklist that links to each setup page. Emphasize that step completion is detected automatically from the merchant's real data via the backend setup-status endpoint, so users usually don't mark steps themselves. If a step won't complete, suggest checking the selected location and the specific condition (e.g. "connect POS" needs a connected and tested integration — for most providers that means clicking Test Connection, but for Lightspeed K-Series the test is recorded automatically by the OAuth callback, so don't tell a Lightspeed merchant to click it; a payment profile must be verified). Do not state a fixed production provider list: it depends on the merchant's country and reseller, and Upvendo's own first-party POS is offered only to test-flagged merchants while it is staged test_only. Avoid referencing the older config-driven self-service/online-ordering/qr-code task system as the current behavior; it is deprecated in favor of the Emily/POS flow.
Relations
Depends On
- Merchant / Vendor: Onboarding state and setup status are keyed by merchant ID.
- Locations: Many completion checks are location-scoped; "Select Location from Topbar" is itself a step, and devices/test orders are evaluated per location.
- POS Integrations: The provider list and the "connect POS"/"sync menu" steps depend on third-party integrations (Hendrickx, Vanhoutte, Square, MplusKassa, Shopcaisse, Lightspeed K-Series).
- Emily: Dynamic steps and persisted onboarding state come from Emily's
onboarding-stateandsetup-stepsendpoints via the proxy. - Backend setup-status service:
SetupStatusServiceaggregates data from payment, billing, branding, location, item, menu, integration, transaction, and device repositories.
Affects
- Onboarding experience: Guided Setup is the primary onboarding tool for new merchants, directly affecting time-to-first-order.
- Setup pages: Steps deep-link to payments, billing, branding, locations, menus, in-house settings, online settings, online ordering, and device management pages.
- Tutorial videos: Each backoffice page can surface a contextual guided-setup video via the video-by-URL endpoint.